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

This commit is contained in:
Omar Hatem 2025-02-04 23:11:04 +02:00 committed by GitHub
parent 6d4b93132f
commit e88b6b2bcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 162 additions and 232 deletions

View file

@ -1,5 +1,3 @@
import 'dart:math';
import 'package:cake_wallet/entities/qr_view_data.dart'; import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
@ -18,7 +16,6 @@ import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
class WalletKeysPage extends BasePage { class WalletKeysPage extends BasePage {
@ -35,14 +32,14 @@ class WalletKeysPage extends BasePage {
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0), padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0),
child: Column( child: Column(
children: [ children: [
Padding( Padding(
padding: EdgeInsets.only(left: 14, right: 14, bottom: 8), padding: EdgeInsets.only(left: 14, right: 14, bottom: 8),
child: WarningBox( child: WarningBox(
key: const ValueKey('wallet_keys_page_share_warning_text_key'), key: const ValueKey('wallet_keys_page_share_warning_text_key'),
content: S.of(context).do_not_share_warning_text.toUpperCase(), content: S.of(context).do_not_share_warning_text.toUpperCase(),
currentTheme: currentTheme, currentTheme: currentTheme,
),
), ),
),
Expanded( Expanded(
child: WalletKeysPageBody( child: WalletKeysPageBody(
walletKeysViewModel: walletKeysViewModel, walletKeysViewModel: walletKeysViewModel,
@ -102,36 +99,36 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(left: 22, right: 22, top: 0), padding: const EdgeInsets.only(left: 22, right: 22, top: 0),
child: TabBar( child: TabBar(
controller: _tabController, controller: _tabController,
splashFactory: NoSplash.splashFactory, splashFactory: NoSplash.splashFactory,
indicatorSize: TabBarIndicatorSize.label, indicatorSize: TabBarIndicatorSize.label,
isScrollable: true, isScrollable: true,
labelStyle: TextStyle( labelStyle: TextStyle(
fontSize: 18, fontSize: 18,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color, color: Theme.of(context).appBarTheme.titleTextStyle!.color,
),
unselectedLabelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
),
labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorPadding: EdgeInsets.zero,
labelPadding: const EdgeInsets.only(right: 24),
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
padding: EdgeInsets.zero,
tabs: [
Tab(text: S.of(context).widgets_seed),
if (showKeyTab) Tab(text: S.of(context).keys),
if (showLegacySeedTab) Tab(text: S.of(context).legacy),
],
), ),
unselectedLabelStyle: TextStyle(
fontSize: 18,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).appBarTheme.titleTextStyle!.color?.withOpacity(0.5),
),
labelColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorColor: Theme.of(context).appBarTheme.titleTextStyle!.color,
indicatorPadding: EdgeInsets.zero,
labelPadding: const EdgeInsets.only(right: 24),
tabAlignment: TabAlignment.start,
dividerColor: Colors.transparent,
padding: EdgeInsets.zero,
tabs: [
Tab(text: S.of(context).widgets_seed),
if (showKeyTab) Tab(text: S.of(context).keys),
if (showLegacySeedTab) Tab(text: S.of(context).legacy),
],
),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Expanded( Expanded(
@ -139,14 +136,14 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
controller: _tabController, controller: _tabController,
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.only(left: 22, right: 22,), padding: const EdgeInsets.only(left: 22, right: 22),
child: _buildSeedTab(context, false), child: _buildSeedTab(context, false),
), ),
if (showKeyTab) if (showKeyTab)
Padding( Padding(
padding: const EdgeInsets.only(left: 22, right: 22), padding: const EdgeInsets.only(left: 22, right: 22),
child: _buildKeysTab(context), child: _buildKeysTab(context),
), ),
if (showLegacySeedTab) if (showLegacySeedTab)
Padding( Padding(
padding: const EdgeInsets.only(left: 22, right: 22), padding: const EdgeInsets.only(left: 22, right: 22),
@ -155,7 +152,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
], ],
), ),
), ),
], ],
), ),
); );
@ -268,7 +264,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
), ),
); );
} }
Widget? _buildPassphraseBox() { Widget? _buildPassphraseBox() {
if (widget.walletKeysViewModel.passphrase.isEmpty) return null; if (widget.walletKeysViewModel.passphrase.isEmpty) return null;
@ -297,9 +292,9 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [ children: [
Observer(builder: (BuildContext context) { Observer(builder: (BuildContext context) {
return Text( return Text(
(widget.walletKeysViewModel.obscurePassphrase) ? (widget.walletKeysViewModel.obscurePassphrase)
"*****" : ? "*****"
widget.walletKeysViewModel.passphrase, : widget.walletKeysViewModel.passphrase,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
@ -308,16 +303,18 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
); );
}), }),
Observer(builder: (BuildContext context) { Observer(builder: (BuildContext context) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
widget.walletKeysViewModel.obscurePassphrase = !widget.walletKeysViewModel.obscurePassphrase; widget.walletKeysViewModel.obscurePassphrase =
}, !widget.walletKeysViewModel.obscurePassphrase;
child: Icon( },
widget.walletKeysViewModel.obscurePassphrase ? Icons.visibility_off : Icons.visibility, child: Icon(
size: 16, widget.walletKeysViewModel.obscurePassphrase
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7), ? Icons.visibility_off
) : Icons.visibility,
); size: 16,
color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7),
));
}), }),
], ],
), ),
@ -327,7 +324,6 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
); );
} }
Widget _buildBottomActionPanel({ Widget _buildBottomActionPanel({
required String titleForClipboard, required String titleForClipboard,
required String dataToCopy, required String dataToCopy,
@ -337,37 +333,37 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
children: [ children: [
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: [ children: [
Flexible( Flexible(
child: Container( child: Container(
padding: const EdgeInsets.only(right: 8.0, top: 8.0), padding: const EdgeInsets.only(right: 8.0, top: 8.0),
child: PrimaryButton( child: PrimaryButton(
key: const ValueKey('wallet_keys_page_copy_seeds_button_key'), key: const ValueKey('wallet_keys_page_copy_seeds_button_key'),
onPressed: () => _onCopy(titleForClipboard, dataToCopy, context), onPressed: () => _onCopy(titleForClipboard, dataToCopy, context),
text: S.of(context).copy, text: S.of(context).copy,
color: Theme.of(context).cardColor, color: Theme.of(context).cardColor,
textColor: widget.currentTheme.type == ThemeType.dark textColor: widget.currentTheme.type == ThemeType.dark
? Theme.of(context).extension<DashboardPageTheme>()!.textColor ? Theme.of(context).extension<DashboardPageTheme>()!.textColor
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor, : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor,
),
), ),
), ),
), Flexible(
Flexible( child: Container(
child: Container( padding: const EdgeInsets.only(left: 8.0, top: 8.0),
padding: const EdgeInsets.only(left: 8.0, top: 8.0), child: PrimaryButton(
child: PrimaryButton( key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'),
key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'), onPressed: onShowQR,
onPressed: onShowQR, text: S.current.show + ' QR',
text: S.current.show + ' QR', color: Theme.of(context).primaryColor,
color: Theme.of(context).primaryColor, textColor: Colors.white,
textColor: Colors.white, ),
), ),
), ),
), ],
], ),
),
), ),
const SizedBox(height: 12), const SizedBox(height: 12),
], ],

View file

@ -1,10 +1,10 @@
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart'; import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/wownero/wownero.dart'; import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cake_wallet/zano/zano.dart';
import 'package:cw_core/transaction_direction.dart'; import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart'; import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
@ -64,8 +64,8 @@ abstract class WalletKeysViewModelBase with Store {
bool get isLegacySeedOnly => bool get isLegacySeedOnly =>
(_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) && (_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
_wallet.seed != null && _wallet.seed != null &&
!Polyseed.isValidSeed(_wallet.seed!); !Polyseed.isValidSeed(_wallet.seed!);
String get legacySeed { String get legacySeed {
if ((_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) && if ((_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) &&
@ -92,11 +92,9 @@ abstract class WalletKeysViewModelBase with Store {
return ''; return '';
} }
@observable @observable
bool obscurePassphrase = true; bool obscurePassphrase = true;
String get passphrase { String get passphrase {
return _wallet.passphrase ?? ''; return _wallet.passphrase ?? '';
} }
@ -111,9 +109,70 @@ abstract class WalletKeysViewModelBase with Store {
void _populateKeysItems() { void _populateKeysItems() {
items.clear(); items.clear();
if (_wallet.type == WalletType.monero) { Map<String, String>? keys;
final keys = monero!.getKeys(_wallet);
switch (_wallet.type) {
case WalletType.monero:
keys = monero!.getKeys(_wallet);
break;
case WalletType.haven:
keys = haven!.getKeys(_wallet);
break;
case WalletType.wownero:
keys = wownero!.getKeys(_wallet);
break;
case WalletType.zano:
keys = zano!.getKeys(_wallet);
break;
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.solana:
case WalletType.tron:
items.addAll([
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
break;
case WalletType.nano:
case WalletType.banano:
// we always have the hex version of the seed and private key:
items.addAll([
if (_wallet.hexSeed != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_hex_seed_key'),
title: S.current.seed_hex_form,
value: _wallet.hexSeed!,
),
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
break;
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.none:
// final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
//
// items.addAll([
// if (keys['wif'] != null)
// StandartListItem(title: "WIF", value: keys['wif']!),
// if (keys['privateKey'] != null)
// StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
// if (keys['publicKey'] != null)
// StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
// ]);
break;
}
if (keys != null) {
items.addAll([ items.addAll([
if (keys['primaryAddress'] != null) if (keys['primaryAddress'] != null)
StandartListItem( StandartListItem(
@ -146,132 +205,6 @@ abstract class WalletKeysViewModelBase with Store {
), ),
]); ]);
} }
if (_wallet.type == WalletType.haven) {
final keys = haven!.getKeys(_wallet);
items.addAll([
if (keys['primaryAddress'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
title: S.current.primary_address,
value: keys['primaryAddress']!),
if (keys['publicSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
title: S.current.spend_key_public,
value: keys['publicSpendKey']!,
),
if (keys['privateSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
title: S.current.spend_key_private,
value: keys['privateSpendKey']!,
),
if (keys['publicViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
title: S.current.view_key_public,
value: keys['publicViewKey']!,
),
if (keys['privateViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
title: S.current.view_key_private,
value: keys['privateViewKey']!,
),
]);
}
if (_wallet.type == WalletType.wownero) {
final keys = wownero!.getKeys(_wallet);
items.addAll([
if (keys['primaryAddress'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_primary_address_item_key'),
title: S.current.primary_address,
value: keys['primaryAddress']!),
if (keys['publicSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_spend_key_item_key'),
title: S.current.spend_key_public,
value: keys['publicSpendKey']!,
),
if (keys['privateSpendKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_spend_key_item_key'),
title: S.current.spend_key_private,
value: keys['privateSpendKey']!,
),
if (keys['publicViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_public_view_key_item_key'),
title: S.current.view_key_public,
value: keys['publicViewKey']!,
),
if (keys['privateViewKey'] != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_view_key_item_key'),
title: S.current.view_key_private,
value: keys['privateViewKey']!,
),
]);
}
// if (_wallet.type == WalletType.bitcoin ||
// _wallet.type == WalletType.litecoin ||
// _wallet.type == WalletType.bitcoinCash) {
// final keys = bitcoin!.getWalletKeys(_appStore.wallet!);
//
// items.addAll([
// if (keys['wif'] != null)
// StandartListItem(title: "WIF", value: keys['wif']!),
// if (keys['privateKey'] != null)
// StandartListItem(title: S.current.private_key, value: keys['privateKey']!),
// if (keys['publicKey'] != null)
// StandartListItem(title: S.current.public_key, value: keys['publicKey']!),
// ]);
// }
if (isEVMCompatibleChain(_wallet.type) ||
_wallet.type == WalletType.solana ||
_wallet.type == WalletType.tron) {
items.addAll([
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
}
bool nanoBased = _wallet.type == WalletType.nano || _wallet.type == WalletType.banano;
if (nanoBased) {
// we always have the hex version of the seed and private key:
items.addAll([
if (_wallet.hexSeed != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_hex_seed_key'),
title: S.current.seed_hex_form,
value: _wallet.hexSeed!,
),
if (_wallet.privateKey != null)
StandartListItem(
key: ValueKey('${_walletName}_wallet_private_key_item_key'),
title: S.current.private_key,
value: _wallet.privateKey!,
),
]);
}
if (_appStore.wallet!.type == WalletType.zano) {
items.addAll([
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
]);
}
} }
Future<int?> _currentHeight() async { Future<int?> _currentHeight() async {

View file

@ -57,17 +57,17 @@ class CWZano extends Zano {
return ZanoNewWalletCredentials(name: name, password: password); return ZanoNewWalletCredentials(name: name, password: password);
} }
// @override @override
// Map<String, String> getKeys(Object wallet) { Map<String, String> getKeys(Object wallet) {
// final zanoWallet = wallet as ZanoWallet; final zanoWallet = wallet as ZanoWallet;
// final keys = zanoWallet.keys; final keys = zanoWallet.keys;
// return <String, String>{ return <String, String>{
// 'privateSpendKey': keys.privateSpendKey, 'privateSpendKey': keys.privateSpendKey,
// 'privateViewKey': keys.privateViewKey, 'privateViewKey': keys.privateViewKey,
// 'publicSpendKey': keys.publicSpendKey, 'publicSpendKey': keys.publicSpendKey,
// 'publicViewKey': keys.publicViewKey 'publicViewKey': keys.publicViewKey
// }; };
// } }
@override @override
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) { Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}) {

View file

@ -1444,6 +1444,7 @@ abstract class Zano {
WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic}); WalletCredentials createZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createZanoNewWalletCredentials({required String name, required String? password}); WalletCredentials createZanoNewWalletCredentials({required String name, required String? password});
Map<String, String> getKeys(Object wallet);
Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency}); Object createZanoTransactionCredentials({required List<Output> outputs, required TransactionPriority priority, required CryptoCurrency currency});
double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee}); double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee});
int formatterParseAmount({required String amount, required CryptoCurrency currency}); int formatterParseAmount({required String amount, required CryptoCurrency currency});