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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 249 additions and 154 deletions

View file

@ -83,7 +83,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: await MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
seedBytes: MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,

View file

@ -36,7 +36,7 @@ class BitcoinCashWalletService extends WalletService<
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
final wallet = await BitcoinCashWalletBase.create(
mnemonic: credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength),
mnemonic: credentials.mnemonic ?? MnemonicBip39.generate(strength: strength),
password: credentials.password!,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,

View file

@ -27,6 +27,7 @@ class EthereumWallet extends EVMChainWallet {
super.initialBalance,
super.privateKey,
required super.encryptionFileUtils,
super.passphrase,
}) : super(nativeCurrency: CryptoCurrency.eth);
@override
@ -150,8 +151,9 @@ class EthereumWallet extends EVMChainWallet {
if (!hasKeysFile) {
final mnemonic = data!['mnemonic'] as String?;
final privateKey = data['private_key'] as String?;
final passphrase = data['passphrase'] as String?;
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
} else {
keysData = await WalletKeysFile.readKeysFile(
name,
@ -166,6 +168,7 @@ class EthereumWallet extends EVMChainWallet {
password: password,
mnemonic: keysData.mnemonic,
privateKey: keysData.privateKey,
passphrase: keysData.passphrase,
initialBalance: balance,
client: EthereumClient(),
encryptionFileUtils: encryptionFileUtils,

View file

@ -27,6 +27,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
walletInfo: credentials.walletInfo!,
mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
client: client,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
@ -144,6 +145,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
password: credentials.password!,
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
passphrase: credentials.passphrase,
client: client,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);

View file

@ -70,6 +70,7 @@ abstract class EVMChainWalletBase
required String password,
EVMChainERC20Balance? initialBalance,
required this.encryptionFileUtils,
this.passphrase,
}) : syncStatus = const NotConnectedSyncStatus(),
_password = password,
_mnemonic = mnemonic,
@ -178,6 +179,7 @@ abstract class EVMChainWalletBase
mnemonic: _mnemonic,
privateKey: _hexPrivateKey,
password: _password,
passphrase: passphrase,
);
walletAddresses.address = _evmChainPrivateKey.address.hexEip55;
}
@ -545,6 +547,7 @@ abstract class EVMChainWalletBase
'mnemonic': _mnemonic,
'private_key': privateKey,
'balance': balance[currency]!.toJSON(),
'passphrase': passphrase,
});
Future<void> _updateBalance() async {
@ -574,15 +577,19 @@ abstract class EVMChainWalletBase
}
}
Future<EthPrivateKey> getPrivateKey(
{String? mnemonic, String? privateKey, required String password}) async {
Future<EthPrivateKey> getPrivateKey({
String? mnemonic,
String? privateKey,
required String password,
String? passphrase,
}) async {
assert(mnemonic != null || privateKey != null);
if (privateKey != null) {
return EthPrivateKey.fromHex(privateKey);
}
final seed = bip39.mnemonicToSeed(mnemonic!);
final seed = bip39.mnemonicToSeed(mnemonic!, passphrase: passphrase ?? '');
final root = bip32.BIP32.fromSeed(seed);
@ -716,4 +723,7 @@ abstract class EVMChainWalletBase
@override
String get password => _password;
@override
final String? passphrase;
}

View file

@ -4,28 +4,25 @@ import 'package:cw_core/wallet_info.dart';
class EVMChainNewWalletCredentials extends WalletCredentials {
EVMChainNewWalletCredentials({
required String name,
WalletInfo? walletInfo,
String? password,
String? parentAddress,
required super.name,
super.walletInfo,
super.password,
super.parentAddress,
this.mnemonic,
}) : super(
name: name,
walletInfo: walletInfo,
password: password,
parentAddress: parentAddress,
);
super.passphrase,
});
final String? mnemonic;
}
class EVMChainRestoreWalletFromSeedCredentials extends WalletCredentials {
EVMChainRestoreWalletFromSeedCredentials({
required String name,
required String password,
required super.name,
required super.password,
required this.mnemonic,
WalletInfo? walletInfo,
}) : super(name: name, password: password, walletInfo: walletInfo);
super.walletInfo,
super.passphrase,
});
final String mnemonic;
}

View file

@ -42,6 +42,7 @@ abstract class NanoWalletBase
required String password,
NanoBalance? initialBalance,
required EncryptionFileUtils encryptionFileUtils,
this.passphrase,
}) : syncStatus = NotConnectedSyncStatus(),
_password = password,
_mnemonic = mnemonic,
@ -548,4 +549,7 @@ abstract class NanoWalletBase
}
return await NanoSignatures.verifyMessage(message, signature, address);
}
@override
final String? passphrase;
}

View file

@ -9,13 +9,15 @@ class NanoNewWalletCredentials extends WalletCredentials {
DerivationType? derivationType,
this.mnemonic,
String? parentAddress,
String? passphrase,
}) : super(
name: name,
password: password,
walletInfo: walletInfo,
parentAddress: parentAddress,
passphrase: passphrase,
);
final String? mnemonic;
}
@ -25,10 +27,12 @@ class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
required this.mnemonic,
String? password,
required DerivationType derivationType,
String? passphrase,
}) : super(
name: name,
password: password,
derivationInfo: DerivationInfo(derivationType: derivationType),
passphrase: passphrase,
);
final String mnemonic;

View file

@ -27,6 +27,7 @@ class PolygonWallet extends EVMChainWallet {
super.privateKey,
required super.client,
required super.encryptionFileUtils,
super.passphrase,
}) : super(nativeCurrency: CryptoCurrency.maticpoly);
@override
@ -128,8 +129,9 @@ class PolygonWallet extends EVMChainWallet {
if (!hasKeysFile) {
final mnemonic = data!['mnemonic'] as String?;
final privateKey = data['private_key'] as String?;
final passphrase = data['passphrase'] as String?;
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
} else {
keysData = await WalletKeysFile.readKeysFile(
name,
@ -144,6 +146,7 @@ class PolygonWallet extends EVMChainWallet {
password: password,
mnemonic: keysData.mnemonic,
privateKey: keysData.privateKey,
passphrase: keysData.passphrase,
initialBalance: balance,
client: PolygonClient(),
encryptionFileUtils: encryptionFileUtils,

View file

@ -30,6 +30,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
walletInfo: credentials.walletInfo!,
mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
client: client,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
@ -125,6 +126,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
password: credentials.password!,
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
passphrase: credentials.passphrase,
client: client,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);

View file

@ -33,7 +33,6 @@ import 'package:solana/base58.dart';
import 'package:solana/metaplex.dart' as metaplex;
import 'package:solana/solana.dart';
import 'package:solana/src/crypto/ed25519_hd_keypair.dart';
import 'package:cryptography/cryptography.dart';
part 'solana_wallet.g.dart';
@ -49,6 +48,7 @@ abstract class SolanaWalletBase
required String password,
SolanaBalance? initialBalance,
required this.encryptionFileUtils,
this.passphrase,
}) : syncStatus = const NotConnectedSyncStatus(),
_password = password,
_mnemonic = mnemonic,
@ -632,4 +632,7 @@ abstract class SolanaWalletBase
@override
String get password => _password;
@override
final String? passphrase;
}

View file

@ -8,22 +8,30 @@ class SolanaNewWalletCredentials extends WalletCredentials {
String? password,
String? parentAddress,
this.mnemonic,
String? passphrase,
}) : super(
name: name,
walletInfo: walletInfo,
password: password,
parentAddress: parentAddress,
passphrase: passphrase,
);
final String? mnemonic;
}
class SolanaRestoreWalletFromSeedCredentials extends WalletCredentials {
SolanaRestoreWalletFromSeedCredentials(
{required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo})
: super(name: name, password: password, walletInfo: walletInfo);
SolanaRestoreWalletFromSeedCredentials({
required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo,
String? passphrase,
}) : super(
name: name,
password: password,
walletInfo: walletInfo,
passphrase: passphrase,
);
final String mnemonic;
}

View file

@ -47,6 +47,7 @@ abstract class TronWalletBase
required String password,
TronBalance? initialBalance,
required this.encryptionFileUtils,
this.passphrase,
}) : syncStatus = const NotConnectedSyncStatus(),
_password = password,
_mnemonic = mnemonic,
@ -113,6 +114,7 @@ abstract class TronWalletBase
mnemonic: _mnemonic,
privateKey: _hexPrivateKey,
password: _password,
passphrase: passphrase,
);
_tronPublicKey = _tronPrivateKey.publicKey();
@ -149,8 +151,9 @@ abstract class TronWalletBase
if (!hasKeysFile) {
final mnemonic = data!['mnemonic'] as String?;
final privateKey = data['private_key'] as String?;
final passphrase = data['passphrase'] as String?;
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
} else {
keysData = await WalletKeysFile.readKeysFile(
name,
@ -165,6 +168,7 @@ abstract class TronWalletBase
password: password,
mnemonic: keysData.mnemonic,
privateKey: keysData.privateKey,
passphrase: keysData.passphrase,
initialBalance: balance,
encryptionFileUtils: encryptionFileUtils,
);
@ -190,12 +194,13 @@ abstract class TronWalletBase
String? mnemonic,
String? privateKey,
required String password,
String? passphrase,
}) async {
assert(mnemonic != null || privateKey != null);
if (privateKey != null) return TronPrivateKey(privateKey);
final seed = bip39.mnemonicToSeed(mnemonic!);
final seed = bip39.mnemonicToSeed(mnemonic!, passphrase: passphrase ?? '');
// Derive a TRON private key from the seed
final bip44 = Bip44.fromSeed(seed, Bip44Coins.tron);
@ -463,6 +468,7 @@ abstract class TronWalletBase
'mnemonic': _mnemonic,
'private_key': privateKey,
'balance': balance[currency]!.toJSON(),
'passphrase': passphrase,
});
Future<void> _updateBalance() async {
@ -607,4 +613,7 @@ abstract class TronWalletBase
@override
String get password => _password;
@override
final String? passphrase;
}

View file

@ -8,23 +8,31 @@ class TronNewWalletCredentials extends WalletCredentials {
String? password,
this.mnemonic,
String? parentAddress,
String? passphrase,
}) : super(
name: name,
walletInfo: walletInfo,
password: password,
parentAddress: parentAddress,
passphrase: passphrase,
);
final String? mnemonic;
}
class TronRestoreWalletFromSeedCredentials extends WalletCredentials {
TronRestoreWalletFromSeedCredentials(
{required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo})
: super(name: name, password: password, walletInfo: walletInfo);
TronRestoreWalletFromSeedCredentials({
required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo,
String? passphrase,
}) : super(
name: name,
password: password,
walletInfo: walletInfo,
passphrase: passphrase,
);
final String mnemonic;
}

View file

@ -33,10 +33,7 @@ class TronWalletService extends WalletService<
WalletType getType() => WalletType.tron;
@override
Future<TronWallet> create(
TronNewWalletCredentials credentials, {
bool? isTestnet,
}) async {
Future<TronWallet> create(TronNewWalletCredentials credentials, {bool? isTestnet}) async {
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
@ -45,6 +42,7 @@ class TronWalletService extends WalletService<
walletInfo: credentials.walletInfo!,
mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
@ -120,6 +118,7 @@ class TronWalletService extends WalletService<
password: credentials.password!,
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
passphrase: credentials.passphrase,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);

View file

@ -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 = '';

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({

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,
);
}

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({

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({

View file

@ -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,

View file

@ -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,
),
),
),
]
]));
}

View file

@ -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;

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({

View file

@ -75,6 +75,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.ethereum,
WalletType.polygon,
WalletType.tron,
].contains(type);
@computed

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,

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(

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(

View file

@ -843,8 +843,8 @@ import 'package:eth_sig_util/util/utils.dart';
abstract class Ethereum {
List<String> getEthereumWordList(String language);
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
String getAddress(WalletBase wallet);
@ -947,8 +947,8 @@ import 'package:eth_sig_util/util/utils.dart';
abstract class Polygon {
List<String> getPolygonWordList(String language);
WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
String getAddress(WalletBase wallet);
@ -1119,6 +1119,7 @@ abstract class Nano {
String? mnemonic,
String? parentAddress,
WalletInfo? walletInfo,
String? passphrase,
});
WalletCredentials createNanoRestoreWalletFromSeedCredentials({
@ -1126,6 +1127,7 @@ abstract class Nano {
required String password,
required String mnemonic,
required DerivationType derivationType,
String? passphrase,
});
WalletCredentials createNanoRestoreWalletFromKeysCredentials({
@ -1234,9 +1236,9 @@ abstract class Solana {
List<String> getSolanaWordList(String language);
WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
WalletCredentials createSolanaNewWalletCredentials(
{required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress,});
{required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
{required String name, required String mnemonic, required String password});
{required String name, required String mnemonic, required String password, String? passphrase});
WalletCredentials createSolanaRestoreWalletFromPrivateKey(
{required String name, required String privateKey, required String password});
@ -1320,9 +1322,8 @@ import 'package:cw_tron/tron_wallet_service.dart';
abstract class Tron {
List<String> getTronWordList(String language);
WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic,
String? parentAddress});
WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
String getAddress(WalletBase wallet);