Add passphrase support for Eth, Polygon, and Tron (#1719)

* Add passphrase support for Eth, Polygon, and Tron

* move passphrase to advanced settings even for restore
This commit is contained in:
Omar Hatem
2024-10-04 20:01:46 +03:00
committed by GitHub
parent fc14bf4e2b
commit 4b4d8a4840
29 changed files with 249 additions and 154 deletions
@@ -1,10 +1,7 @@
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
const channel = MethodChannel('com.cake_wallet/native_utils');
Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async {
var address = '';
+9 -1
View File
@@ -14,6 +14,7 @@ class CWEthereum extends Ethereum {
String? parentAddress,
WalletInfo? walletInfo,
String? password,
String? passphrase,
}) =>
EVMChainNewWalletCredentials(
name: name,
@@ -21,6 +22,7 @@ class CWEthereum extends Ethereum {
password: password,
parentAddress: parentAddress,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
@@ -28,8 +30,14 @@ class CWEthereum extends Ethereum {
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
EVMChainRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
EVMChainRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createEthereumRestoreWalletFromPrivateKey({
+4
View File
@@ -95,6 +95,7 @@ class CWNano extends Nano {
String? password,
String? mnemonic,
String? parentAddress,
String? passphrase,
}) =>
NanoNewWalletCredentials(
name: name,
@@ -102,6 +103,7 @@ class CWNano extends Nano {
mnemonic: mnemonic,
parentAddress: parentAddress,
walletInfo: walletInfo,
passphrase: passphrase,
);
@override
@@ -110,6 +112,7 @@ class CWNano extends Nano {
required String password,
required String mnemonic,
required DerivationType derivationType,
String? passphrase,
}) {
if (mnemonic.split(" ").length == 12 && derivationType != DerivationType.bip39) {
throw Exception("Invalid mnemonic for derivation type!");
@@ -120,6 +123,7 @@ class CWNano extends Nano {
password: password,
mnemonic: mnemonic,
derivationType: derivationType,
passphrase: passphrase,
);
}
+16 -7
View File
@@ -8,18 +8,21 @@ class CWPolygon extends Polygon {
PolygonWalletService(walletInfoSource, isDirect, client: PolygonClient());
@override
WalletCredentials createPolygonNewWalletCredentials(
{required String name,
String? mnemonic,
String? parentAddress,
WalletInfo? walletInfo,
String? password}) =>
WalletCredentials createPolygonNewWalletCredentials({
required String name,
String? mnemonic,
String? parentAddress,
WalletInfo? walletInfo,
String? password,
String? passphrase,
}) =>
EVMChainNewWalletCredentials(
name: name,
walletInfo: walletInfo,
password: password,
mnemonic: mnemonic,
parentAddress: parentAddress,
passphrase: passphrase,
);
@override
@@ -27,8 +30,14 @@ class CWPolygon extends Polygon {
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
EVMChainRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
EVMChainRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createPolygonRestoreWalletFromPrivateKey({
+9 -1
View File
@@ -14,6 +14,7 @@ class CWSolana extends Solana {
String? parentAddress,
WalletInfo? walletInfo,
String? password,
String? passphrase,
}) =>
SolanaNewWalletCredentials(
name: name,
@@ -21,6 +22,7 @@ class CWSolana extends Solana {
password: password,
mnemonic: mnemonic,
parentAddress: parentAddress,
passphrase: passphrase,
);
@override
@@ -28,8 +30,14 @@ class CWSolana extends Solana {
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
SolanaRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
SolanaRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createSolanaRestoreWalletFromPrivateKey({
@@ -189,7 +189,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
),
);
}),
if (!widget.isFromRestore) ...[
if (!widget.isFromRestore)
Observer(builder: (_) {
if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
return SettingsPickerCell<SeedPhraseLength>(
@@ -202,54 +202,53 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
);
return Container();
}),
if (widget.privacySettingsViewModel.hasPassphraseOption)
Padding(
padding: EdgeInsets.all(24),
child: Form(
key: _passphraseFormKey,
child: Column(
children: [
BaseTextFormField(
hintText: S.of(context).passphrase,
controller: passphraseController,
obscureText: obscurePassphrase,
suffixIcon: GestureDetector(
onTap: () => setState(() {
obscurePassphrase = !obscurePassphrase;
}),
child: Icon(
Icons.remove_red_eye,
color: obscurePassphrase ? Colors.black54 : Colors.black26,
),
if (widget.privacySettingsViewModel.hasPassphraseOption)
Padding(
padding: EdgeInsets.all(24),
child: Form(
key: _passphraseFormKey,
child: Column(
children: [
BaseTextFormField(
hintText: S.of(context).passphrase,
controller: passphraseController,
obscureText: obscurePassphrase,
suffixIcon: GestureDetector(
onTap: () => setState(() {
obscurePassphrase = !obscurePassphrase;
}),
child: Icon(
Icons.remove_red_eye,
color: obscurePassphrase ? Colors.black54 : Colors.black26,
),
),
const SizedBox(height: 10),
BaseTextFormField(
hintText: S.of(context).confirm_passphrase,
controller: confirmPassphraseController,
obscureText: obscurePassphrase,
validator: (text) {
if (text == passphraseController.text) {
return null;
}
),
const SizedBox(height: 10),
BaseTextFormField(
hintText: S.of(context).confirm_passphrase,
controller: confirmPassphraseController,
obscureText: obscurePassphrase,
validator: (text) {
if (text == passphraseController.text) {
return null;
}
return S.of(context).passphrases_doesnt_match;
},
suffixIcon: GestureDetector(
onTap: () => setState(() {
obscurePassphrase = !obscurePassphrase;
}),
child: Icon(
Icons.remove_red_eye,
color: obscurePassphrase ? Colors.black54 : Colors.black26,
),
return S.of(context).passphrases_doesnt_match;
},
suffixIcon: GestureDetector(
onTap: () => setState(() {
obscurePassphrase = !obscurePassphrase;
}),
child: Icon(
Icons.remove_red_eye,
color: obscurePassphrase ? Colors.black54 : Colors.black26,
),
),
],
),
),
],
),
),
],
),
Observer(builder: (_) {
return Column(
children: [
@@ -311,13 +310,14 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
widget.nodeViewModel.save();
}
if (passphraseController.text.isNotEmpty) {
if (_passphraseFormKey.currentState != null && !_passphraseFormKey.currentState!.validate()) {
if (_passphraseFormKey.currentState != null &&
!_passphraseFormKey.currentState!.validate()) {
return;
}
widget.seedTypeViewModel.setPassphrase(passphraseController.text);
}
widget.seedTypeViewModel.setPassphrase(passphraseController.text);
Navigator.pop(context);
},
text: S.of(context).continue_text,
@@ -19,7 +19,6 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
WalletRestoreFromSeedForm({Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type,
required this.displayWalletPassword,
required this.seedSettingsViewModel,
@@ -35,7 +34,6 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
final bool displayLanguageSelector;
final bool displayBlockHeightSelector;
final bool displayWalletPassword;
final bool displayPassphrase;
final SeedSettingsViewModel seedSettingsViewModel;
final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered;
@@ -60,7 +58,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
repeatedPasswordTextEditingController = displayWalletPassword
? TextEditingController()
: null,
passphraseController = TextEditingController(),
seedTypeController = TextEditingController();
final GlobalKey<SeedWidgetState> seedWidgetStateKey;
@@ -70,15 +67,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
final TextEditingController? passwordTextEditingController;
final TextEditingController? repeatedPasswordTextEditingController;
final TextEditingController seedTypeController;
final TextEditingController passphraseController;
final GlobalKey<FormState> formKey;
late ReactionDisposer moneroSeedTypeReaction;
String language;
void Function()? passwordListener;
void Function()? repeatedPasswordListener;
void Function()? passphraseListener;
bool obscurePassphrase = true;
@override
void initState() {
@@ -96,9 +89,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
}
passphraseListener = () => widget.seedSettingsViewModel.setPassphrase(passphraseController.text);
passphraseController.addListener(passphraseListener!);
moneroSeedTypeReaction =
reaction((_) => widget.seedSettingsViewModel.moneroSeedType, (MoneroSeedType item) {
_setSeedType(item);
@@ -120,8 +110,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
}
passphraseController.removeListener(passphraseListener!);
super.dispose();
}
@@ -280,23 +268,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
hasDatePicker: widget.type == WalletType.monero || widget.type == WalletType.wownero,
walletType: widget.type,
),
if (widget.displayPassphrase) ...[
const SizedBox(height: 10),
BaseTextFormField(
hintText: S.current.passphrase,
controller: passphraseController,
obscureText: obscurePassphrase,
suffixIcon: GestureDetector(
onTap: () => setState(() {
obscurePassphrase = !obscurePassphrase;
}),
child: Icon(
Icons.remove_red_eye,
color: obscurePassphrase ? Colors.black54 : Colors.black26,
),
),
),
]
]));
}
@@ -37,7 +37,6 @@ class WalletRestorePage extends BasePage {
displayBlockHeightSelector:
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
displayPassphrase: walletRestoreViewModel.hasPassphrase,
type: walletRestoreViewModel.type,
key: walletRestoreFromSeedFormKey,
blockHeightFocusNode: _blockHeightFocusNode,
@@ -320,9 +319,7 @@ class WalletRestorePage extends BasePage {
-1;
}
if (walletRestoreViewModel.hasPassphrase) {
credentials['passphrase'] = seedSettingsViewModel.passphrase;
}
credentials['passphrase'] = seedSettingsViewModel.passphrase;
credentials['name'] =
walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
+9 -1
View File
@@ -15,12 +15,14 @@ class CWTron extends Tron {
String? password,
String? mnemonic,
String? parentAddress,
String? passphrase,
}) =>
TronNewWalletCredentials(
name: name,
walletInfo: walletInfo,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
parentAddress: parentAddress);
@override
@@ -28,8 +30,14 @@ class CWTron extends Tron {
required String name,
required String mnemonic,
required String password,
String? passphrase,
}) =>
TronRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
TronRestoreWalletFromSeedCredentials(
name: name,
password: password,
mnemonic: mnemonic,
passphrase: passphrase,
);
@override
WalletCredentials createTronRestoreWalletFromPrivateKey({
@@ -75,6 +75,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.ethereum,
WalletType.polygon,
WalletType.tron,
].contains(type);
@computed
+31 -8
View File
@@ -13,7 +13,7 @@ import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/core/generate_wallet_password.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cw_core/wallet_credentials.dart';
@@ -26,14 +26,19 @@ part 'restore_from_qr_vm.g.dart';
class WalletRestorationFromQRVM = WalletRestorationFromQRVMBase with _$WalletRestorationFromQRVM;
abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store {
WalletRestorationFromQRVMBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource, WalletType type, SeedSettingsViewModel seedSettingsViewModel)
WalletRestorationFromQRVMBase(
AppStore appStore,
WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
WalletType type,
SeedSettingsViewModel seedSettingsViewModel)
: height = 0,
viewKey = '',
spendKey = '',
wif = '',
address = '',
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
type: type, isRecovery: true);
@observable
int height;
@@ -124,26 +129,44 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
passphrase: restoreWallet.passphrase,
);
case WalletType.ethereum:
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
passphrase: restoreWallet.passphrase,
);
case WalletType.nano:
return nano!.createNanoRestoreWalletFromSeedCredentials(
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
derivationType: derivationInfo!.derivationType!,
passphrase: restoreWallet.passphrase,
);
case WalletType.polygon:
return polygon!.createPolygonRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
passphrase: restoreWallet.passphrase,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
passphrase: restoreWallet.passphrase,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromSeedCredentials(
name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
name: name,
mnemonic: restoreWallet.mnemonicSeed ?? '',
password: password,
passphrase: restoreWallet.passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromSeedCredentials(
name: name,
+5
View File
@@ -106,6 +106,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
parentAddress: newWalletArguments!.parentAddress,
passphrase: passphrase,
);
case WalletType.bitcoinCash:
return bitcoinCash!.createBitcoinCashNewWalletCredentials(
@@ -122,6 +123,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
parentAddress: newWalletArguments!.parentAddress,
passphrase: passphrase,
);
case WalletType.polygon:
return polygon!.createPolygonNewWalletCredentials(
@@ -129,6 +131,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
parentAddress: newWalletArguments!.parentAddress,
passphrase: passphrase,
);
case WalletType.solana:
return solana!.createSolanaNewWalletCredentials(
@@ -136,6 +139,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
parentAddress: newWalletArguments!.parentAddress,
passphrase: passphrase,
);
case WalletType.tron:
return tron!.createTronNewWalletCredentials(
@@ -143,6 +147,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
password: walletPassword,
mnemonic: newWalletArguments!.mnemonic,
parentAddress: newWalletArguments!.parentAddress,
passphrase: passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroNewWalletCredentials(
+14 -5
View File
@@ -78,9 +78,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
final bool hasBlockchainHeightLanguageSelector;
final bool hasRestoreFromPrivateKey;
bool get hasPassphrase =>
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(type);
@observable
WalletRestoreMode mode;
@@ -116,10 +113,18 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
name: name, height: height, mnemonic: seed, password: password);
case WalletType.ethereum:
return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
name: name, mnemonic: seed, password: password);
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.bitcoinCash:
return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials(
name: name, mnemonic: seed, password: password);
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.nano:
case WalletType.banano:
return nano!.createNanoRestoreWalletFromSeedCredentials(
@@ -127,24 +132,28 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
mnemonic: seed,
password: password,
derivationType: derivationInfo!.derivationType!,
passphrase: passphrase,
);
case WalletType.polygon:
return polygon!.createPolygonRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.solana:
return solana!.createSolanaRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.tron:
return tron!.createTronRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password,
passphrase: passphrase,
);
case WalletType.wownero:
return wownero!.createWowneroRestoreWalletFromSeedCredentials(