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

Omar Hatem committed Oct 4, 2024 at 20:01 UTC 4b4d8a4840309ec746accbca82ea097d00a5bf6a
29 files changed +249 -154
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart
+1 -1
@@ -83,7 +83,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
83 unspentCoinsInfo: unspentCoinsInfo,
84 initialAddresses: initialAddresses,
85 initialBalance: initialBalance,
86 - seedBytes: await MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
86 + seedBytes: MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
87 encryptionFileUtils: encryptionFileUtils,
88 initialRegularAddressIndex: initialRegularAddressIndex,
89 initialChangeAddressIndex: initialChangeAddressIndex,
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+1 -1
@@ -36,7 +36,7 @@ class BitcoinCashWalletService extends WalletService<
36 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
37
38 final wallet = await BitcoinCashWalletBase.create(
39 - mnemonic: credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength),
39 + mnemonic: credentials.mnemonic ?? MnemonicBip39.generate(strength: strength),
40 password: credentials.password!,
41 walletInfo: credentials.walletInfo!,
42 unspentCoinsInfo: unspentCoinsInfoSource,
cw_ethereum/lib/ethereum_wallet.dart
+4 -1
@@ -27,6 +27,7 @@ class EthereumWallet extends EVMChainWallet {
27 super.initialBalance,
28 super.privateKey,
29 required super.encryptionFileUtils,
30 + super.passphrase,
31 }) : super(nativeCurrency: CryptoCurrency.eth);
32
33 @override
@@ -150,8 +151,9 @@ class EthereumWallet extends EVMChainWallet {
151 if (!hasKeysFile) {
152 final mnemonic = data!['mnemonic'] as String?;
153 final privateKey = data['private_key'] as String?;
154 + final passphrase = data['passphrase'] as String?;
155
154 - keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
156 + keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
157 } else {
158 keysData = await WalletKeysFile.readKeysFile(
159 name,
@@ -166,6 +168,7 @@ class EthereumWallet extends EVMChainWallet {
168 password: password,
169 mnemonic: keysData.mnemonic,
170 privateKey: keysData.privateKey,
171 + passphrase: keysData.passphrase,
172 initialBalance: balance,
173 client: EthereumClient(),
174 encryptionFileUtils: encryptionFileUtils,
cw_ethereum/lib/ethereum_wallet_service.dart
+2
@@ -27,6 +27,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
27 walletInfo: credentials.walletInfo!,
28 mnemonic: mnemonic,
29 password: credentials.password!,
30 + passphrase: credentials.passphrase,
31 client: client,
32 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
33 );
@@ -144,6 +145,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
145 password: credentials.password!,
146 mnemonic: credentials.mnemonic,
147 walletInfo: credentials.walletInfo!,
148 + passphrase: credentials.passphrase,
149 client: client,
150 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
151 );
cw_evm/lib/evm_chain_wallet.dart
+13 -3
@@ -70,6 +70,7 @@ abstract class EVMChainWalletBase
70 required String password,
71 EVMChainERC20Balance? initialBalance,
72 required this.encryptionFileUtils,
73 + this.passphrase,
74 }) : syncStatus = const NotConnectedSyncStatus(),
75 _password = password,
76 _mnemonic = mnemonic,
@@ -178,6 +179,7 @@ abstract class EVMChainWalletBase
179 mnemonic: _mnemonic,
180 privateKey: _hexPrivateKey,
181 password: _password,
182 + passphrase: passphrase,
183 );
184 walletAddresses.address = _evmChainPrivateKey.address.hexEip55;
185 }
@@ -545,6 +547,7 @@ abstract class EVMChainWalletBase
547 'mnemonic': _mnemonic,
548 'private_key': privateKey,
549 'balance': balance[currency]!.toJSON(),
550 + 'passphrase': passphrase,
551 });
552
553 Future<void> _updateBalance() async {
@@ -574,15 +577,19 @@ abstract class EVMChainWalletBase
577 }
578 }
579
577 - Future<EthPrivateKey> getPrivateKey(
578 - {String? mnemonic, String? privateKey, required String password}) async {
580 + Future<EthPrivateKey> getPrivateKey({
581 + String? mnemonic,
582 + String? privateKey,
583 + required String password,
584 + String? passphrase,
585 + }) async {
586 assert(mnemonic != null || privateKey != null);
587
588 if (privateKey != null) {
589 return EthPrivateKey.fromHex(privateKey);
590 }
591
585 - final seed = bip39.mnemonicToSeed(mnemonic!);
592 + final seed = bip39.mnemonicToSeed(mnemonic!, passphrase: passphrase ?? '');
593
594 final root = bip32.BIP32.fromSeed(seed);
595
@@ -716,4 +723,7 @@ abstract class EVMChainWalletBase
723
724 @override
725 String get password => _password;
726 +
727 + @override
728 + final String? passphrase;
729 }
cw_evm/lib/evm_chain_wallet_creation_credentials.dart
+11 -14
@@ -4,28 +4,25 @@ import 'package:cw_core/wallet_info.dart';
4
5 class EVMChainNewWalletCredentials extends WalletCredentials {
6 EVMChainNewWalletCredentials({
7 - required String name,
8 - WalletInfo? walletInfo,
9 - String? password,
10 - String? parentAddress,
7 + required super.name,
8 + super.walletInfo,
9 + super.password,
10 + super.parentAddress,
11 this.mnemonic,
12 - }) : super(
13 - name: name,
14 - walletInfo: walletInfo,
15 - password: password,
16 - parentAddress: parentAddress,
17 - );
12 + super.passphrase,
13 + });
14
15 final String? mnemonic;
16 }
17
18 class EVMChainRestoreWalletFromSeedCredentials extends WalletCredentials {
19 EVMChainRestoreWalletFromSeedCredentials({
24 - required String name,
25 - required String password,
20 + required super.name,
21 + required super.password,
22 required this.mnemonic,
27 - WalletInfo? walletInfo,
28 - }) : super(name: name, password: password, walletInfo: walletInfo);
23 + super.walletInfo,
24 + super.passphrase,
25 + });
26
27 final String mnemonic;
28 }
cw_nano/lib/nano_wallet.dart
+4
@@ -42,6 +42,7 @@ abstract class NanoWalletBase
42 required String password,
43 NanoBalance? initialBalance,
44 required EncryptionFileUtils encryptionFileUtils,
45 + this.passphrase,
46 }) : syncStatus = NotConnectedSyncStatus(),
47 _password = password,
48 _mnemonic = mnemonic,
@@ -548,4 +549,7 @@ abstract class NanoWalletBase
549 }
550 return await NanoSignatures.verifyMessage(message, signature, address);
551 }
552 +
553 + @override
554 + final String? passphrase;
555 }
cw_nano/lib/nano_wallet_creation_credentials.dart
+5 -1
@@ -9,13 +9,15 @@ class NanoNewWalletCredentials extends WalletCredentials {
9 DerivationType? derivationType,
10 this.mnemonic,
11 String? parentAddress,
12 + String? passphrase,
13 }) : super(
14 name: name,
15 password: password,
16 walletInfo: walletInfo,
17 parentAddress: parentAddress,
18 + passphrase: passphrase,
19 );
18 -
20 +
21 final String? mnemonic;
22 }
23
@@ -25,10 +27,12 @@ class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
27 required this.mnemonic,
28 String? password,
29 required DerivationType derivationType,
30 + String? passphrase,
31 }) : super(
32 name: name,
33 password: password,
34 derivationInfo: DerivationInfo(derivationType: derivationType),
35 + passphrase: passphrase,
36 );
37
38 final String mnemonic;
cw_polygon/lib/polygon_wallet.dart
+4 -1
@@ -27,6 +27,7 @@ class PolygonWallet extends EVMChainWallet {
27 super.privateKey,
28 required super.client,
29 required super.encryptionFileUtils,
30 + super.passphrase,
31 }) : super(nativeCurrency: CryptoCurrency.maticpoly);
32
33 @override
@@ -128,8 +129,9 @@ class PolygonWallet extends EVMChainWallet {
129 if (!hasKeysFile) {
130 final mnemonic = data!['mnemonic'] as String?;
131 final privateKey = data['private_key'] as String?;
132 + final passphrase = data['passphrase'] as String?;
133
132 - keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
134 + keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
135 } else {
136 keysData = await WalletKeysFile.readKeysFile(
137 name,
@@ -144,6 +146,7 @@ class PolygonWallet extends EVMChainWallet {
146 password: password,
147 mnemonic: keysData.mnemonic,
148 privateKey: keysData.privateKey,
149 + passphrase: keysData.passphrase,
150 initialBalance: balance,
151 client: PolygonClient(),
152 encryptionFileUtils: encryptionFileUtils,
cw_polygon/lib/polygon_wallet_service.dart
+2
@@ -30,6 +30,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
30 walletInfo: credentials.walletInfo!,
31 mnemonic: mnemonic,
32 password: credentials.password!,
33 + passphrase: credentials.passphrase,
34 client: client,
35 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
36 );
@@ -125,6 +126,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
126 password: credentials.password!,
127 mnemonic: credentials.mnemonic,
128 walletInfo: credentials.walletInfo!,
129 + passphrase: credentials.passphrase,
130 client: client,
131 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
132 );
cw_solana/lib/solana_wallet.dart
+4 -1
@@ -33,7 +33,6 @@ import 'package:solana/base58.dart';
33 import 'package:solana/metaplex.dart' as metaplex;
34 import 'package:solana/solana.dart';
35 import 'package:solana/src/crypto/ed25519_hd_keypair.dart';
36 -import 'package:cryptography/cryptography.dart';
36
37 part 'solana_wallet.g.dart';
38
@@ -49,6 +48,7 @@ abstract class SolanaWalletBase
48 required String password,
49 SolanaBalance? initialBalance,
50 required this.encryptionFileUtils,
51 + this.passphrase,
52 }) : syncStatus = const NotConnectedSyncStatus(),
53 _password = password,
54 _mnemonic = mnemonic,
@@ -632,4 +632,7 @@ abstract class SolanaWalletBase
632
633 @override
634 String get password => _password;
635 +
636 + @override
637 + final String? passphrase;
638 }
cw_solana/lib/solana_wallet_creation_credentials.dart
+14 -6
@@ -8,22 +8,30 @@ class SolanaNewWalletCredentials extends WalletCredentials {
8 String? password,
9 String? parentAddress,
10 this.mnemonic,
11 + String? passphrase,
12 }) : super(
13 name: name,
14 walletInfo: walletInfo,
15 password: password,
16 parentAddress: parentAddress,
17 + passphrase: passphrase,
18 );
19 final String? mnemonic;
20 }
21
22 class SolanaRestoreWalletFromSeedCredentials extends WalletCredentials {
21 - SolanaRestoreWalletFromSeedCredentials(
22 - {required String name,
23 - required String password,
24 - required this.mnemonic,
25 - WalletInfo? walletInfo})
26 - : super(name: name, password: password, walletInfo: walletInfo);
23 + SolanaRestoreWalletFromSeedCredentials({
24 + required String name,
25 + required String password,
26 + required this.mnemonic,
27 + WalletInfo? walletInfo,
28 + String? passphrase,
29 + }) : super(
30 + name: name,
31 + password: password,
32 + walletInfo: walletInfo,
33 + passphrase: passphrase,
34 + );
35
36 final String mnemonic;
37 }
cw_tron/lib/tron_wallet.dart
+11 -2
@@ -47,6 +47,7 @@ abstract class TronWalletBase
47 required String password,
48 TronBalance? initialBalance,
49 required this.encryptionFileUtils,
50 + this.passphrase,
51 }) : syncStatus = const NotConnectedSyncStatus(),
52 _password = password,
53 _mnemonic = mnemonic,
@@ -113,6 +114,7 @@ abstract class TronWalletBase
114 mnemonic: _mnemonic,
115 privateKey: _hexPrivateKey,
116 password: _password,
117 + passphrase: passphrase,
118 );
119
120 _tronPublicKey = _tronPrivateKey.publicKey();
@@ -149,8 +151,9 @@ abstract class TronWalletBase
151 if (!hasKeysFile) {
152 final mnemonic = data!['mnemonic'] as String?;
153 final privateKey = data['private_key'] as String?;
154 + final passphrase = data['passphrase'] as String?;
155
153 - keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey);
156 + keysData = WalletKeysData(mnemonic: mnemonic, privateKey: privateKey, passphrase: passphrase);
157 } else {
158 keysData = await WalletKeysFile.readKeysFile(
159 name,
@@ -165,6 +168,7 @@ abstract class TronWalletBase
168 password: password,
169 mnemonic: keysData.mnemonic,
170 privateKey: keysData.privateKey,
171 + passphrase: keysData.passphrase,
172 initialBalance: balance,
173 encryptionFileUtils: encryptionFileUtils,
174 );
@@ -190,12 +194,13 @@ abstract class TronWalletBase
194 String? mnemonic,
195 String? privateKey,
196 required String password,
197 + String? passphrase,
198 }) async {
199 assert(mnemonic != null || privateKey != null);
200
201 if (privateKey != null) return TronPrivateKey(privateKey);
202
198 - final seed = bip39.mnemonicToSeed(mnemonic!);
203 + final seed = bip39.mnemonicToSeed(mnemonic!, passphrase: passphrase ?? '');
204
205 // Derive a TRON private key from the seed
206 final bip44 = Bip44.fromSeed(seed, Bip44Coins.tron);
@@ -463,6 +468,7 @@ abstract class TronWalletBase
468 'mnemonic': _mnemonic,
469 'private_key': privateKey,
470 'balance': balance[currency]!.toJSON(),
471 + 'passphrase': passphrase,
472 });
473
474 Future<void> _updateBalance() async {
@@ -607,4 +613,7 @@ abstract class TronWalletBase
613
614 @override
615 String get password => _password;
616 +
617 + @override
618 + final String? passphrase;
619 }
cw_tron/lib/tron_wallet_creation_credentials.dart
+14 -6
@@ -8,23 +8,31 @@ class TronNewWalletCredentials extends WalletCredentials {
8 String? password,
9 this.mnemonic,
10 String? parentAddress,
11 + String? passphrase,
12 }) : super(
13 name: name,
14 walletInfo: walletInfo,
15 password: password,
16 parentAddress: parentAddress,
17 + passphrase: passphrase,
18 );
19
20 final String? mnemonic;
21 }
22
23 class TronRestoreWalletFromSeedCredentials extends WalletCredentials {
22 - TronRestoreWalletFromSeedCredentials(
23 - {required String name,
24 - required String password,
25 - required this.mnemonic,
26 - WalletInfo? walletInfo})
27 - : super(name: name, password: password, walletInfo: walletInfo);
24 + TronRestoreWalletFromSeedCredentials({
25 + required String name,
26 + required String password,
27 + required this.mnemonic,
28 + WalletInfo? walletInfo,
29 + String? passphrase,
30 + }) : super(
31 + name: name,
32 + password: password,
33 + walletInfo: walletInfo,
34 + passphrase: passphrase,
35 + );
36
37 final String mnemonic;
38 }
cw_tron/lib/tron_wallet_service.dart
+3 -4
@@ -33,10 +33,7 @@ class TronWalletService extends WalletService<
33 WalletType getType() => WalletType.tron;
34
35 @override
36 - Future<TronWallet> create(
37 - TronNewWalletCredentials credentials, {
38 - bool? isTestnet,
39 - }) async {
36 + Future<TronWallet> create(TronNewWalletCredentials credentials, {bool? isTestnet}) async {
37 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
38
39 final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
@@ -45,6 +42,7 @@ class TronWalletService extends WalletService<
42 walletInfo: credentials.walletInfo!,
43 mnemonic: mnemonic,
44 password: credentials.password!,
45 + passphrase: credentials.passphrase,
46 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
47 );
48
@@ -120,6 +118,7 @@ class TronWalletService extends WalletService<
118 password: credentials.password!,
119 mnemonic: credentials.mnemonic,
120 walletInfo: credentials.walletInfo!,
121 + passphrase: credentials.passphrase,
122 encryptionFileUtils: encryptionFileUtilsFor(isDirect),
123 );
124
lib/entities/unstoppable_domain_address.dart
-3
@@ -1,10 +1,7 @@
1 import 'dart:convert';
2
3 -import 'package:flutter/services.dart';
3 import 'package:http/http.dart' as http;
4
6 -const channel = MethodChannel('com.cake_wallet/native_utils');
7 -
5 Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async {
6 var address = '';
7
lib/ethereum/cw_ethereum.dart
+9 -1
@@ -14,6 +14,7 @@ class CWEthereum extends Ethereum {
14 String? parentAddress,
15 WalletInfo? walletInfo,
16 String? password,
17 + String? passphrase,
18 }) =>
19 EVMChainNewWalletCredentials(
20 name: name,
@@ -21,6 +22,7 @@ class CWEthereum extends Ethereum {
22 password: password,
23 parentAddress: parentAddress,
24 mnemonic: mnemonic,
25 + passphrase: passphrase,
26 );
27
28 @override
@@ -28,8 +30,14 @@ class CWEthereum extends Ethereum {
30 required String name,
31 required String mnemonic,
32 required String password,
33 + String? passphrase,
34 }) =>
32 - EVMChainRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
35 + EVMChainRestoreWalletFromSeedCredentials(
36 + name: name,
37 + password: password,
38 + mnemonic: mnemonic,
39 + passphrase: passphrase,
40 + );
41
42 @override
43 WalletCredentials createEthereumRestoreWalletFromPrivateKey({
lib/nano/cw_nano.dart
+4
@@ -95,6 +95,7 @@ class CWNano extends Nano {
95 String? password,
96 String? mnemonic,
97 String? parentAddress,
98 + String? passphrase,
99 }) =>
100 NanoNewWalletCredentials(
101 name: name,
@@ -102,6 +103,7 @@ class CWNano extends Nano {
103 mnemonic: mnemonic,
104 parentAddress: parentAddress,
105 walletInfo: walletInfo,
106 + passphrase: passphrase,
107 );
108
109 @override
@@ -110,6 +112,7 @@ class CWNano extends Nano {
112 required String password,
113 required String mnemonic,
114 required DerivationType derivationType,
115 + String? passphrase,
116 }) {
117 if (mnemonic.split(" ").length == 12 && derivationType != DerivationType.bip39) {
118 throw Exception("Invalid mnemonic for derivation type!");
@@ -120,6 +123,7 @@ class CWNano extends Nano {
123 password: password,
124 mnemonic: mnemonic,
125 derivationType: derivationType,
126 + passphrase: passphrase,
127 );
128 }
129
lib/polygon/cw_polygon.dart
+16 -7
@@ -8,18 +8,21 @@ class CWPolygon extends Polygon {
8 PolygonWalletService(walletInfoSource, isDirect, client: PolygonClient());
9
10 @override
11 - WalletCredentials createPolygonNewWalletCredentials(
12 - {required String name,
13 - String? mnemonic,
14 - String? parentAddress,
15 - WalletInfo? walletInfo,
16 - String? password}) =>
11 + WalletCredentials createPolygonNewWalletCredentials({
12 + required String name,
13 + String? mnemonic,
14 + String? parentAddress,
15 + WalletInfo? walletInfo,
16 + String? password,
17 + String? passphrase,
18 + }) =>
19 EVMChainNewWalletCredentials(
20 name: name,
21 walletInfo: walletInfo,
22 password: password,
23 mnemonic: mnemonic,
24 parentAddress: parentAddress,
25 + passphrase: passphrase,
26 );
27
28 @override
@@ -27,8 +30,14 @@ class CWPolygon extends Polygon {
30 required String name,
31 required String mnemonic,
32 required String password,
33 + String? passphrase,
34 }) =>
31 - EVMChainRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
35 + EVMChainRestoreWalletFromSeedCredentials(
36 + name: name,
37 + password: password,
38 + mnemonic: mnemonic,
39 + passphrase: passphrase,
40 + );
41
42 @override
43 WalletCredentials createPolygonRestoreWalletFromPrivateKey({
lib/solana/cw_solana.dart
+9 -1
@@ -14,6 +14,7 @@ class CWSolana extends Solana {
14 String? parentAddress,
15 WalletInfo? walletInfo,
16 String? password,
17 + String? passphrase,
18 }) =>
19 SolanaNewWalletCredentials(
20 name: name,
@@ -21,6 +22,7 @@ class CWSolana extends Solana {
22 password: password,
23 mnemonic: mnemonic,
24 parentAddress: parentAddress,
25 + passphrase: passphrase,
26 );
27
28 @override
@@ -28,8 +30,14 @@ class CWSolana extends Solana {
30 required String name,
31 required String mnemonic,
32 required String password,
33 + String? passphrase,
34 }) =>
32 - SolanaRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
35 + SolanaRestoreWalletFromSeedCredentials(
36 + name: name,
37 + password: password,
38 + mnemonic: mnemonic,
39 + passphrase: passphrase,
40 + );
41
42 @override
43 WalletCredentials createSolanaRestoreWalletFromPrivateKey({
lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
+45 -45
@@ -189,7 +189,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
189 ),
190 );
191 }),
192 - if (!widget.isFromRestore) ...[
192 + if (!widget.isFromRestore)
193 Observer(builder: (_) {
194 if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
195 return SettingsPickerCell<SeedPhraseLength>(
@@ -202,54 +202,53 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
202 );
203 return Container();
204 }),
205 - if (widget.privacySettingsViewModel.hasPassphraseOption)
206 - Padding(
207 - padding: EdgeInsets.all(24),
208 - child: Form(
209 - key: _passphraseFormKey,
210 - child: Column(
211 - children: [
212 - BaseTextFormField(
213 - hintText: S.of(context).passphrase,
214 - controller: passphraseController,
215 - obscureText: obscurePassphrase,
216 - suffixIcon: GestureDetector(
217 - onTap: () => setState(() {
218 - obscurePassphrase = !obscurePassphrase;
219 - }),
220 - child: Icon(
221 - Icons.remove_red_eye,
222 - color: obscurePassphrase ? Colors.black54 : Colors.black26,
223 - ),
205 + if (widget.privacySettingsViewModel.hasPassphraseOption)
206 + Padding(
207 + padding: EdgeInsets.all(24),
208 + child: Form(
209 + key: _passphraseFormKey,
210 + child: Column(
211 + children: [
212 + BaseTextFormField(
213 + hintText: S.of(context).passphrase,
214 + controller: passphraseController,
215 + obscureText: obscurePassphrase,
216 + suffixIcon: GestureDetector(
217 + onTap: () => setState(() {
218 + obscurePassphrase = !obscurePassphrase;
219 + }),
220 + child: Icon(
221 + Icons.remove_red_eye,
222 + color: obscurePassphrase ? Colors.black54 : Colors.black26,
223 ),
224 ),
226 - const SizedBox(height: 10),
227 - BaseTextFormField(
228 - hintText: S.of(context).confirm_passphrase,
229 - controller: confirmPassphraseController,
230 - obscureText: obscurePassphrase,
231 - validator: (text) {
232 - if (text == passphraseController.text) {
233 - return null;
234 - }
225 + ),
226 + const SizedBox(height: 10),
227 + BaseTextFormField(
228 + hintText: S.of(context).confirm_passphrase,
229 + controller: confirmPassphraseController,
230 + obscureText: obscurePassphrase,
231 + validator: (text) {
232 + if (text == passphraseController.text) {
233 + return null;
234 + }
235
236 - return S.of(context).passphrases_doesnt_match;
237 - },
238 - suffixIcon: GestureDetector(
239 - onTap: () => setState(() {
240 - obscurePassphrase = !obscurePassphrase;
241 - }),
242 - child: Icon(
243 - Icons.remove_red_eye,
244 - color: obscurePassphrase ? Colors.black54 : Colors.black26,
245 - ),
236 + return S.of(context).passphrases_doesnt_match;
237 + },
238 + suffixIcon: GestureDetector(
239 + onTap: () => setState(() {
240 + obscurePassphrase = !obscurePassphrase;
241 + }),
242 + child: Icon(
243 + Icons.remove_red_eye,
244 + color: obscurePassphrase ? Colors.black54 : Colors.black26,
245 ),
246 ),
248 - ],
249 - ),
247 + ),
248 + ],
249 ),
250 ),
252 - ],
251 + ),
252 Observer(builder: (_) {
253 return Column(
254 children: [
@@ -311,13 +310,14 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
310 widget.nodeViewModel.save();
311 }
312 if (passphraseController.text.isNotEmpty) {
314 - if (_passphraseFormKey.currentState != null && !_passphraseFormKey.currentState!.validate()) {
313 + if (_passphraseFormKey.currentState != null &&
314 + !_passphraseFormKey.currentState!.validate()) {
315 return;
316 }
317 -
318 - widget.seedTypeViewModel.setPassphrase(passphraseController.text);
317 }
318
319 + widget.seedTypeViewModel.setPassphrase(passphraseController.text);
320 +
321 Navigator.pop(context);
322 },
323 text: S.of(context).continue_text,
lib/src/screens/restore/wallet_restore_from_seed_form.dart
-29
@@ -19,7 +19,6 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
19 WalletRestoreFromSeedForm({Key? key,
20 required this.displayLanguageSelector,
21 required this.displayBlockHeightSelector,
22 - required this.displayPassphrase,
22 required this.type,
23 required this.displayWalletPassword,
24 required this.seedSettingsViewModel,
@@ -35,7 +34,6 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
34 final bool displayLanguageSelector;
35 final bool displayBlockHeightSelector;
36 final bool displayWalletPassword;
38 - final bool displayPassphrase;
37 final SeedSettingsViewModel seedSettingsViewModel;
38 final FocusNode? blockHeightFocusNode;
39 final Function(bool)? onHeightOrDateEntered;
@@ -60,7 +58,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
58 repeatedPasswordTextEditingController = displayWalletPassword
59 ? TextEditingController()
60 : null,
63 - passphraseController = TextEditingController(),
61 seedTypeController = TextEditingController();
62
63 final GlobalKey<SeedWidgetState> seedWidgetStateKey;
@@ -70,15 +67,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
67 final TextEditingController? passwordTextEditingController;
68 final TextEditingController? repeatedPasswordTextEditingController;
69 final TextEditingController seedTypeController;
73 - final TextEditingController passphraseController;
70 final GlobalKey<FormState> formKey;
71 late ReactionDisposer moneroSeedTypeReaction;
72 String language;
73 void Function()? passwordListener;
74 void Function()? repeatedPasswordListener;
79 - void Function()? passphraseListener;
80 -
81 - bool obscurePassphrase = true;
75
76 @override
77 void initState() {
@@ -96,9 +89,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
89 repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
90 }
91
99 - passphraseListener = () => widget.seedSettingsViewModel.setPassphrase(passphraseController.text);
100 - passphraseController.addListener(passphraseListener!);
101 -
92 moneroSeedTypeReaction =
93 reaction((_) => widget.seedSettingsViewModel.moneroSeedType, (MoneroSeedType item) {
94 _setSeedType(item);
@@ -120,8 +110,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
110 repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
111 }
112
123 - passphraseController.removeListener(passphraseListener!);
124 -
113 super.dispose();
114 }
115
@@ -280,23 +268,6 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
268 hasDatePicker: widget.type == WalletType.monero || widget.type == WalletType.wownero,
269 walletType: widget.type,
270 ),
283 - if (widget.displayPassphrase) ...[
284 - const SizedBox(height: 10),
285 - BaseTextFormField(
286 - hintText: S.current.passphrase,
287 - controller: passphraseController,
288 - obscureText: obscurePassphrase,
289 - suffixIcon: GestureDetector(
290 - onTap: () => setState(() {
291 - obscurePassphrase = !obscurePassphrase;
292 - }),
293 - child: Icon(
294 - Icons.remove_red_eye,
295 - color: obscurePassphrase ? Colors.black54 : Colors.black26,
296 - ),
297 - ),
298 - ),
299 - ]
271 ]));
272 }
273
lib/src/screens/restore/wallet_restore_page.dart
+1 -4
@@ -37,7 +37,6 @@ class WalletRestorePage extends BasePage {
37 displayBlockHeightSelector:
38 walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
39 displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
40 - displayPassphrase: walletRestoreViewModel.hasPassphrase,
40 type: walletRestoreViewModel.type,
41 key: walletRestoreFromSeedFormKey,
42 blockHeightFocusNode: _blockHeightFocusNode,
@@ -320,9 +319,7 @@ class WalletRestorePage extends BasePage {
319 -1;
320 }
321
323 - if (walletRestoreViewModel.hasPassphrase) {
324 - credentials['passphrase'] = seedSettingsViewModel.passphrase;
325 - }
322 + credentials['passphrase'] = seedSettingsViewModel.passphrase;
323
324 credentials['name'] =
325 walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
lib/tron/cw_tron.dart
+9 -1
@@ -15,12 +15,14 @@ class CWTron extends Tron {
15 String? password,
16 String? mnemonic,
17 String? parentAddress,
18 + String? passphrase,
19 }) =>
20 TronNewWalletCredentials(
21 name: name,
22 walletInfo: walletInfo,
23 password: password,
24 mnemonic: mnemonic,
25 + passphrase: passphrase,
26 parentAddress: parentAddress);
27
28 @override
@@ -28,8 +30,14 @@ class CWTron extends Tron {
30 required String name,
31 required String mnemonic,
32 required String password,
33 + String? passphrase,
34 }) =>
32 - TronRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
35 + TronRestoreWalletFromSeedCredentials(
36 + name: name,
37 + password: password,
38 + mnemonic: mnemonic,
39 + passphrase: passphrase,
40 + );
41
42 @override
43 WalletCredentials createTronRestoreWalletFromPrivateKey({
lib/view_model/advanced_privacy_settings_view_model.dart
+3
@@ -75,6 +75,9 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
75 WalletType.bitcoin,
76 WalletType.litecoin,
77 WalletType.bitcoinCash,
78 + WalletType.ethereum,
79 + WalletType.polygon,
80 + WalletType.tron,
81 ].contains(type);
82
83 @computed
lib/view_model/restore/restore_from_qr_vm.dart
+31 -8
@@ -13,7 +13,7 @@ import 'package:hive/hive.dart';
13 import 'package:mobx/mobx.dart';
14 import 'package:cake_wallet/monero/monero.dart';
15 import 'package:cake_wallet/store/app_store.dart';
16 -import 'package:cw_core/wallet_base.dart';
16 +import 'package:cw_core/wallet_base.dart';
17 import 'package:cake_wallet/core/generate_wallet_password.dart';
18 import 'package:cake_wallet/core/wallet_creation_service.dart';
19 import 'package:cw_core/wallet_credentials.dart';
@@ -26,14 +26,19 @@ part 'restore_from_qr_vm.g.dart';
26 class WalletRestorationFromQRVM = WalletRestorationFromQRVMBase with _$WalletRestorationFromQRVM;
27
28 abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store {
29 - WalletRestorationFromQRVMBase(AppStore appStore, WalletCreationService walletCreationService,
30 - Box<WalletInfo> walletInfoSource, WalletType type, SeedSettingsViewModel seedSettingsViewModel)
29 + WalletRestorationFromQRVMBase(
30 + AppStore appStore,
31 + WalletCreationService walletCreationService,
32 + Box<WalletInfo> walletInfoSource,
33 + WalletType type,
34 + SeedSettingsViewModel seedSettingsViewModel)
35 : height = 0,
36 viewKey = '',
37 spendKey = '',
38 wif = '',
39 address = '',
36 - super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
40 + super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
41 + type: type, isRecovery: true);
42
43 @observable
44 int height;
@@ -124,26 +129,44 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
129 name: name,
130 mnemonic: restoreWallet.mnemonicSeed ?? '',
131 password: password,
132 + passphrase: restoreWallet.passphrase,
133 );
134 case WalletType.ethereum:
135 return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
130 - name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
136 + name: name,
137 + mnemonic: restoreWallet.mnemonicSeed ?? '',
138 + password: password,
139 + passphrase: restoreWallet.passphrase,
140 + );
141 case WalletType.nano:
142 return nano!.createNanoRestoreWalletFromSeedCredentials(
143 name: name,
144 mnemonic: restoreWallet.mnemonicSeed ?? '',
145 password: password,
146 derivationType: derivationInfo!.derivationType!,
147 + passphrase: restoreWallet.passphrase,
148 );
149 case WalletType.polygon:
150 return polygon!.createPolygonRestoreWalletFromSeedCredentials(
140 - name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
151 + name: name,
152 + mnemonic: restoreWallet.mnemonicSeed ?? '',
153 + password: password,
154 + passphrase: restoreWallet.passphrase,
155 + );
156 case WalletType.solana:
157 return solana!.createSolanaRestoreWalletFromSeedCredentials(
143 - name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
158 + name: name,
159 + mnemonic: restoreWallet.mnemonicSeed ?? '',
160 + password: password,
161 + passphrase: restoreWallet.passphrase,
162 + );
163 case WalletType.tron:
164 return tron!.createTronRestoreWalletFromSeedCredentials(
146 - name: name, mnemonic: restoreWallet.mnemonicSeed ?? '', password: password);
165 + name: name,
166 + mnemonic: restoreWallet.mnemonicSeed ?? '',
167 + password: password,
168 + passphrase: restoreWallet.passphrase,
169 + );
170 case WalletType.wownero:
171 return wownero!.createWowneroRestoreWalletFromSeedCredentials(
172 name: name,
lib/view_model/wallet_new_vm.dart
+5
@@ -106,6 +106,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
106 password: walletPassword,
107 mnemonic: newWalletArguments!.mnemonic,
108 parentAddress: newWalletArguments!.parentAddress,
109 + passphrase: passphrase,
110 );
111 case WalletType.bitcoinCash:
112 return bitcoinCash!.createBitcoinCashNewWalletCredentials(
@@ -122,6 +123,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
123 password: walletPassword,
124 mnemonic: newWalletArguments!.mnemonic,
125 parentAddress: newWalletArguments!.parentAddress,
126 + passphrase: passphrase,
127 );
128 case WalletType.polygon:
129 return polygon!.createPolygonNewWalletCredentials(
@@ -129,6 +131,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
131 password: walletPassword,
132 mnemonic: newWalletArguments!.mnemonic,
133 parentAddress: newWalletArguments!.parentAddress,
134 + passphrase: passphrase,
135 );
136 case WalletType.solana:
137 return solana!.createSolanaNewWalletCredentials(
@@ -136,6 +139,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
139 password: walletPassword,
140 mnemonic: newWalletArguments!.mnemonic,
141 parentAddress: newWalletArguments!.parentAddress,
142 + passphrase: passphrase,
143 );
144 case WalletType.tron:
145 return tron!.createTronNewWalletCredentials(
@@ -143,6 +147,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
147 password: walletPassword,
148 mnemonic: newWalletArguments!.mnemonic,
149 parentAddress: newWalletArguments!.parentAddress,
150 + passphrase: passphrase,
151 );
152 case WalletType.wownero:
153 return wownero!.createWowneroNewWalletCredentials(
lib/view_model/wallet_restore_view_model.dart
+14 -5
@@ -78,9 +78,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
78 final bool hasBlockchainHeightLanguageSelector;
79 final bool hasRestoreFromPrivateKey;
80
81 - bool get hasPassphrase =>
82 - [WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(type);
83 -
81 @observable
82 WalletRestoreMode mode;
83
@@ -116,10 +113,18 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
113 name: name, height: height, mnemonic: seed, password: password);
114 case WalletType.ethereum:
115 return ethereum!.createEthereumRestoreWalletFromSeedCredentials(
119 - name: name, mnemonic: seed, password: password);
116 + name: name,
117 + mnemonic: seed,
118 + password: password,
119 + passphrase: passphrase,
120 + );
121 case WalletType.bitcoinCash:
122 return bitcoinCash!.createBitcoinCashRestoreWalletFromSeedCredentials(
122 - name: name, mnemonic: seed, password: password);
123 + name: name,
124 + mnemonic: seed,
125 + password: password,
126 + passphrase: passphrase,
127 + );
128 case WalletType.nano:
129 case WalletType.banano:
130 return nano!.createNanoRestoreWalletFromSeedCredentials(
@@ -127,24 +132,28 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
132 mnemonic: seed,
133 password: password,
134 derivationType: derivationInfo!.derivationType!,
135 + passphrase: passphrase,
136 );
137 case WalletType.polygon:
138 return polygon!.createPolygonRestoreWalletFromSeedCredentials(
139 name: name,
140 mnemonic: seed,
141 password: password,
142 + passphrase: passphrase,
143 );
144 case WalletType.solana:
145 return solana!.createSolanaRestoreWalletFromSeedCredentials(
146 name: name,
147 mnemonic: seed,
148 password: password,
149 + passphrase: passphrase,
150 );
151 case WalletType.tron:
152 return tron!.createTronRestoreWalletFromSeedCredentials(
153 name: name,
154 mnemonic: seed,
155 password: password,
156 + passphrase: passphrase,
157 );
158 case WalletType.wownero:
159 return wownero!.createWowneroRestoreWalletFromSeedCredentials(
tool/configure.dart
+10 -9
@@ -843,8 +843,8 @@ import 'package:eth_sig_util/util/utils.dart';
843 abstract class Ethereum {
844 List<String> getEthereumWordList(String language);
845 WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
846 - WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
847 - WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
846 + WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
847 + WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
848 WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
849 WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
850 String getAddress(WalletBase wallet);
@@ -947,8 +947,8 @@ import 'package:eth_sig_util/util/utils.dart';
947 abstract class Polygon {
948 List<String> getPolygonWordList(String language);
949 WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
950 - WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
951 - WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
950 + WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
951 + WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
952 WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
953 WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
954 String getAddress(WalletBase wallet);
@@ -1119,6 +1119,7 @@ abstract class Nano {
1119 String? mnemonic,
1120 String? parentAddress,
1121 WalletInfo? walletInfo,
1122 + String? passphrase,
1123 });
1124
1125 WalletCredentials createNanoRestoreWalletFromSeedCredentials({
@@ -1126,6 +1127,7 @@ abstract class Nano {
1127 required String password,
1128 required String mnemonic,
1129 required DerivationType derivationType,
1130 + String? passphrase,
1131 });
1132
1133 WalletCredentials createNanoRestoreWalletFromKeysCredentials({
@@ -1234,9 +1236,9 @@ abstract class Solana {
1236 List<String> getSolanaWordList(String language);
1237 WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
1238 WalletCredentials createSolanaNewWalletCredentials(
1237 - {required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress,});
1239 + {required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
1240 WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
1239 - {required String name, required String mnemonic, required String password});
1241 + {required String name, required String mnemonic, required String password, String? passphrase});
1242 WalletCredentials createSolanaRestoreWalletFromPrivateKey(
1243 {required String name, required String privateKey, required String password});
1244
@@ -1320,9 +1322,8 @@ import 'package:cw_tron/tron_wallet_service.dart';
1322 abstract class Tron {
1323 List<String> getTronWordList(String language);
1324 WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
1323 - WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic,
1324 - String? parentAddress});
1325 - WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
1325 + WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
1326 + WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
1327 WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
1328 String getAddress(WalletBase wallet);
1329