From e88b6b2bcfb6f0c60403912863f138467a7e7796 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Tue, 4 Feb 2025 23:11:04 +0200 Subject: [PATCH] show Zano keys properly in the keys tab (#2004) --- .../screens/wallet_keys/wallet_keys_page.dart | 170 ++++++++------- lib/view_model/wallet_keys_view_model.dart | 201 ++++++------------ lib/zano/cw_zano.dart | 22 +- tool/configure.dart | 1 + 4 files changed, 162 insertions(+), 232 deletions(-) diff --git a/lib/src/screens/wallet_keys/wallet_keys_page.dart b/lib/src/screens/wallet_keys/wallet_keys_page.dart index f9b2f5015..a8a35096a 100644 --- a/lib/src/screens/wallet_keys/wallet_keys_page.dart +++ b/lib/src/screens/wallet_keys/wallet_keys_page.dart @@ -1,5 +1,3 @@ -import 'dart:math'; - import 'package:cake_wallet/entities/qr_view_data.dart'; import 'package:cake_wallet/generated/i18n.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/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; -import 'package:mobx/mobx.dart'; import 'package:qr_flutter/qr_flutter.dart'; class WalletKeysPage extends BasePage { @@ -35,14 +32,14 @@ class WalletKeysPage extends BasePage { padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0), child: Column( children: [ - Padding( - padding: EdgeInsets.only(left: 14, right: 14, bottom: 8), - child: WarningBox( - key: const ValueKey('wallet_keys_page_share_warning_text_key'), - content: S.of(context).do_not_share_warning_text.toUpperCase(), - currentTheme: currentTheme, + Padding( + padding: EdgeInsets.only(left: 14, right: 14, bottom: 8), + child: WarningBox( + key: const ValueKey('wallet_keys_page_share_warning_text_key'), + content: S.of(context).do_not_share_warning_text.toUpperCase(), + currentTheme: currentTheme, + ), ), - ), Expanded( child: WalletKeysPageBody( walletKeysViewModel: walletKeysViewModel, @@ -102,36 +99,36 @@ class _WalletKeysPageBodyState extends State children: [ Padding( padding: const EdgeInsets.only(left: 22, right: 22, top: 0), - child: TabBar( - controller: _tabController, - splashFactory: NoSplash.splashFactory, - indicatorSize: TabBarIndicatorSize.label, - isScrollable: true, - labelStyle: TextStyle( - fontSize: 18, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: Theme.of(context).appBarTheme.titleTextStyle!.color, + child: TabBar( + controller: _tabController, + splashFactory: NoSplash.splashFactory, + indicatorSize: TabBarIndicatorSize.label, + isScrollable: true, + labelStyle: TextStyle( + fontSize: 18, + fontFamily: 'Lato', + fontWeight: FontWeight.w600, + 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), Expanded( @@ -139,14 +136,14 @@ class _WalletKeysPageBodyState extends State controller: _tabController, children: [ Padding( - padding: const EdgeInsets.only(left: 22, right: 22,), + padding: const EdgeInsets.only(left: 22, right: 22), child: _buildSeedTab(context, false), ), if (showKeyTab) - Padding( - padding: const EdgeInsets.only(left: 22, right: 22), - child: _buildKeysTab(context), - ), + Padding( + padding: const EdgeInsets.only(left: 22, right: 22), + child: _buildKeysTab(context), + ), if (showLegacySeedTab) Padding( padding: const EdgeInsets.only(left: 22, right: 22), @@ -155,7 +152,6 @@ class _WalletKeysPageBodyState extends State ], ), ), - ], ), ); @@ -268,7 +264,6 @@ class _WalletKeysPageBodyState extends State ), ); } - Widget? _buildPassphraseBox() { if (widget.walletKeysViewModel.passphrase.isEmpty) return null; @@ -297,9 +292,9 @@ class _WalletKeysPageBodyState extends State children: [ Observer(builder: (BuildContext context) { return Text( - (widget.walletKeysViewModel.obscurePassphrase) ? - "*****" : - widget.walletKeysViewModel.passphrase, + (widget.walletKeysViewModel.obscurePassphrase) + ? "*****" + : widget.walletKeysViewModel.passphrase, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, @@ -308,16 +303,18 @@ class _WalletKeysPageBodyState extends State ); }), Observer(builder: (BuildContext context) { - return GestureDetector( - onTap: () { - widget.walletKeysViewModel.obscurePassphrase = !widget.walletKeysViewModel.obscurePassphrase; - }, - child: Icon( - widget.walletKeysViewModel.obscurePassphrase ? Icons.visibility_off : Icons.visibility, - size: 16, - color: Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.7), - ) - ); + return GestureDetector( + onTap: () { + widget.walletKeysViewModel.obscurePassphrase = + !widget.walletKeysViewModel.obscurePassphrase; + }, + child: Icon( + widget.walletKeysViewModel.obscurePassphrase + ? 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 ); } - Widget _buildBottomActionPanel({ required String titleForClipboard, required String dataToCopy, @@ -337,37 +333,37 @@ class _WalletKeysPageBodyState extends State children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Flexible( - child: Container( - padding: const EdgeInsets.only(right: 8.0, top: 8.0), - child: PrimaryButton( - key: const ValueKey('wallet_keys_page_copy_seeds_button_key'), - onPressed: () => _onCopy(titleForClipboard, dataToCopy, context), - text: S.of(context).copy, - color: Theme.of(context).cardColor, - textColor: widget.currentTheme.type == ThemeType.dark - ? Theme.of(context).extension()!.textColor - : Theme.of(context).extension()!.buttonTextColor, + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Flexible( + child: Container( + padding: const EdgeInsets.only(right: 8.0, top: 8.0), + child: PrimaryButton( + key: const ValueKey('wallet_keys_page_copy_seeds_button_key'), + onPressed: () => _onCopy(titleForClipboard, dataToCopy, context), + text: S.of(context).copy, + color: Theme.of(context).cardColor, + textColor: widget.currentTheme.type == ThemeType.dark + ? Theme.of(context).extension()!.textColor + : Theme.of(context).extension()!.buttonTextColor, + ), ), ), - ), - Flexible( - child: Container( - padding: const EdgeInsets.only(left: 8.0, top: 8.0), - child: PrimaryButton( - key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'), - onPressed: onShowQR, - text: S.current.show + ' QR', - color: Theme.of(context).primaryColor, - textColor: Colors.white, + Flexible( + child: Container( + padding: const EdgeInsets.only(left: 8.0, top: 8.0), + child: PrimaryButton( + key: const ValueKey('wallet_keys_page_show_qr_seeds_button_key'), + onPressed: onShowQR, + text: S.current.show + ' QR', + color: Theme.of(context).primaryColor, + textColor: Colors.white, + ), ), ), - ), - ], - ), + ], + ), ), const SizedBox(height: 12), ], diff --git a/lib/view_model/wallet_keys_view_model.dart b/lib/view_model/wallet_keys_view_model.dart index edeacfcd6..402764c40 100644 --- a/lib/view_model/wallet_keys_view_model.dart +++ b/lib/view_model/wallet_keys_view_model.dart @@ -1,10 +1,10 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/haven/haven.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/store/app_store.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_info.dart'; import 'package:cw_core/wallet_base.dart'; @@ -64,8 +64,8 @@ abstract class WalletKeysViewModelBase with Store { bool get isLegacySeedOnly => (_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) && - _wallet.seed != null && - !Polyseed.isValidSeed(_wallet.seed!); + _wallet.seed != null && + !Polyseed.isValidSeed(_wallet.seed!); String get legacySeed { if ((_wallet.type == WalletType.monero || _wallet.type == WalletType.wownero) && @@ -92,11 +92,9 @@ abstract class WalletKeysViewModelBase with Store { return ''; } - - @observable bool obscurePassphrase = true; - + String get passphrase { return _wallet.passphrase ?? ''; } @@ -111,9 +109,70 @@ abstract class WalletKeysViewModelBase with Store { void _populateKeysItems() { items.clear(); - if (_wallet.type == WalletType.monero) { - final keys = monero!.getKeys(_wallet); + Map? keys; + 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([ if (keys['primaryAddress'] != null) 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 _currentHeight() async { diff --git a/lib/zano/cw_zano.dart b/lib/zano/cw_zano.dart index f7f10a91e..a1cae19c8 100644 --- a/lib/zano/cw_zano.dart +++ b/lib/zano/cw_zano.dart @@ -57,17 +57,17 @@ class CWZano extends Zano { return ZanoNewWalletCredentials(name: name, password: password); } - // @override - // Map getKeys(Object wallet) { - // final zanoWallet = wallet as ZanoWallet; - // final keys = zanoWallet.keys; - // return { - // 'privateSpendKey': keys.privateSpendKey, - // 'privateViewKey': keys.privateViewKey, - // 'publicSpendKey': keys.publicSpendKey, - // 'publicViewKey': keys.publicViewKey - // }; - // } + @override + Map getKeys(Object wallet) { + final zanoWallet = wallet as ZanoWallet; + final keys = zanoWallet.keys; + return { + 'privateSpendKey': keys.privateSpendKey, + 'privateViewKey': keys.privateViewKey, + 'publicSpendKey': keys.publicSpendKey, + 'publicViewKey': keys.publicViewKey + }; + } @override Object createZanoTransactionCredentials({required List outputs, required TransactionPriority priority, required CryptoCurrency currency}) { diff --git a/tool/configure.dart b/tool/configure.dart index c8ed958a9..3a49438e4 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -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 createZanoNewWalletCredentials({required String name, required String? password}); + Map getKeys(Object wallet); Object createZanoTransactionCredentials({required List outputs, required TransactionPriority priority, required CryptoCurrency currency}); double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee}); int formatterParseAmount({required String amount, required CryptoCurrency currency});