Cw 488 seed offset (#1631)

* CW-488 minor code cleanup

* Add Derivation Path selector for BTC and LTC

* CW-488 Initial Passphrase Impl

* CW-488 Final Passphrase Impl

* Quick Fix of language Service

* CW-488 Implement PR Suggestions

* CW-488 Implement PR Suggestions

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* CW-488 Implement Passphrase for Bitcoin Cash

* remove monero and wownero support for passphrase until merged [skip ci]

* CW-488 Apply requested change

* CW-488 Add Passphrase to QR

* CW-488 Fix Seed generation

* CW-488 Implement Electrum Passphrases

* CW-488 Add Seed Length Selector to BIP39 Seeds

* CW-488 Minor fix [skip ci]

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
Konstantin Ullrich 2024-08-26 19:06:54 +02:00 committed by GitHub
parent 40f85d215b
commit ce21098e98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
67 changed files with 741 additions and 438 deletions

View file

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:cryptography/cryptography.dart' as cryptography;
import 'package:cw_core/sec_random_native.dart';
@ -59,11 +60,7 @@ void maskBytes(Uint8List bytes, int bits) {
}
}
String bufferToBin(Uint8List data) {
final q1 = data.map((e) => e.toRadixString(2).padLeft(8, '0'));
final q2 = q1.join('');
return q2;
}
String bufferToBin(Uint8List data) => data.map((e) => e.toRadixString(2).padLeft(8, '0')).join('');
String encode(Uint8List data) {
final dataBitLen = data.length * 8;
@ -112,17 +109,18 @@ Future<bool> checkIfMnemonicIsElectrum2(String mnemonic) async {
Future<String> getMnemonicHash(String mnemonic) async {
final hmacSha512 = Hmac(sha512, utf8.encode('Seed version'));
final digest = hmacSha512.convert(utf8.encode(normalizeText(mnemonic)));
final hx = digest.toString();
return hx;
return digest.toString();
}
Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
Future<Uint8List> mnemonicToSeedBytes(String mnemonic,
{String prefix = segwit, String passphrase = ''}) async {
final pbkdf2 =
cryptography.Pbkdf2(macAlgorithm: cryptography.Hmac.sha512(), iterations: 2048, bits: 512);
final text = normalizeText(mnemonic);
// pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
final passphraseBytes = utf8.encode(normalizeText(passphrase));
final key = await pbkdf2.deriveKey(
secretKey: cryptography.SecretKey(text.codeUnits), nonce: 'electrum'.codeUnits);
secretKey: cryptography.SecretKey(text.codeUnits),
nonce: [...'electrum'.codeUnits, ...passphraseBytes]);
final bytes = await key.extractBytes();
return Uint8List.fromList(bytes);
}

View file

@ -7,5 +7,6 @@ class MnemonicBip39 {
static String generate({int strength = 128}) => bip39.generateMnemonic(strength: strength);
/// Create root seed from mnemonic
static Uint8List toSeed(String mnemonic) => bip39.mnemonicToSeed(mnemonic);
static Uint8List toSeed(String mnemonic, {String? passphrase}) =>
bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
}

View file

@ -115,7 +115,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
break;
case DerivationType.electrum:
default:
seedBytes = await mnemonicToSeedBytes(mnemonic);
seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
}
return BitcoinWallet(
@ -195,7 +195,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
if (mnemonic != null) {
switch (walletInfo.derivationInfo!.derivationType) {
case DerivationType.electrum:
seedBytes = await mnemonicToSeedBytes(mnemonic);
seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
case DerivationType.bip39:
default:

View file

@ -3,16 +3,18 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
class BitcoinNewWalletCredentials extends WalletCredentials {
BitcoinNewWalletCredentials(
{required String name,
WalletInfo? walletInfo,
String? password,
DerivationType? derivationType,
String? derivationPath})
: super(
BitcoinNewWalletCredentials({
required String name,
WalletInfo? walletInfo,
String? password,
DerivationType? derivationType,
String? derivationPath,
String? passphrase,
}) : super(
name: name,
walletInfo: walletInfo,
password: password,
passphrase: passphrase,
);
}

View file

@ -1,6 +1,7 @@
import 'dart:io';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
import 'package:cw_bitcoin/mnemonic_is_incorrect_exception.dart';
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cw_core/encryption_file_utils.dart';
@ -35,8 +36,21 @@ class BitcoinWalletService extends WalletService<
final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
credentials.walletInfo?.network = network.value;
final String mnemonic;
switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
case DerivationType.bip39:
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
mnemonic = await MnemonicBip39.generate(strength: strength);
break;
case DerivationType.electrum:
default:
mnemonic = await generateElectrumMnemonic();
break;
}
final wallet = await BitcoinWalletBase.create(
mnemonic: await generateElectrumMnemonic(),
mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
walletInfo: credentials.walletInfo!,

View file

@ -109,5 +109,4 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
],
};
String electrum_path = electrum_derivations[DerivationType.electrum]!.first.derivationPath!;

View file

@ -137,6 +137,8 @@ abstract class ElectrumWalletBase
Bip32Slip10Secp256k1 get sideHd => accountHD.childKey(Bip32KeyIndex(1));
final EncryptionFileUtils encryptionFileUtils;
@override
final String? passphrase;
@override

View file

@ -7,6 +7,7 @@ import 'package:bip39/bip39.dart' as bip39;
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_bitcoin/electrum_derivations.dart';
import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_coins_info.dart';
@ -36,6 +37,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required Uint8List seedBytes,
required EncryptionFileUtils encryptionFileUtils,
String? passphrase,
String? addressPageType,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
@ -51,6 +53,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
initialBalance: initialBalance,
seedBytes: seedBytes,
encryptionFileUtils: encryptionFileUtils,
passphrase: passphrase,
currency: CryptoCurrency.ltc) {
walletAddresses = LitecoinWalletAddresses(
walletInfo,
@ -89,7 +92,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
break;
case DerivationType.electrum:
default:
seedBytes = await mnemonicToSeedBytes(mnemonic);
seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
}
return LitecoinWallet(
@ -100,6 +103,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
initialAddresses: initialAddresses,
initialBalance: initialBalance,
encryptionFileUtils: encryptionFileUtils,
passphrase: passphrase,
seedBytes: seedBytes,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
@ -143,6 +147,31 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
);
}
walletInfo.derivationInfo ??= DerivationInfo();
// set the default if not present:
walletInfo.derivationInfo!.derivationPath ??= snp?.derivationPath ?? electrum_path;
walletInfo.derivationInfo!.derivationType ??= snp?.derivationType ?? DerivationType.electrum;
Uint8List? seedBytes = null;
final mnemonic = keysData.mnemonic;
final passphrase = keysData.passphrase;
if (mnemonic != null) {
switch (walletInfo.derivationInfo?.derivationType) {
case DerivationType.bip39:
seedBytes = await bip39.mnemonicToSeed(
mnemonic,
passphrase: passphrase ?? "",
);
break;
case DerivationType.electrum:
default:
seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
break;
}
}
return LitecoinWallet(
mnemonic: keysData.mnemonic!,
password: password,
@ -150,7 +179,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: snp?.addresses,
initialBalance: snp?.balance,
seedBytes: await mnemonicToSeedBytes(keysData.mnemonic!),
seedBytes: seedBytes!,
passphrase: passphrase,
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: snp?.regularAddressIndex,
initialChangeAddressIndex: snp?.changeAddressIndex,

View file

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:hive/hive.dart';
@ -30,8 +31,21 @@ class LitecoinWalletService extends WalletService<
@override
Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials, {bool? isTestnet}) async {
final String mnemonic;
switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
case DerivationType.bip39:
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
mnemonic = await MnemonicBip39.generate(strength: strength);
break;
case DerivationType.electrum:
default:
mnemonic = await generateElectrumMnemonic();
break;
}
final wallet = await LitecoinWalletBase.create(
mnemonic: await generateElectrumMnemonic(),
mnemonic: mnemonic,
password: credentials.password!,
passphrase: credentials.passphrase,
walletInfo: credentials.walletInfo!,

View file

@ -3,5 +3,4 @@ export 'bitcoin_cash_wallet_addresses.dart';
export 'bitcoin_cash_wallet_creation_credentials.dart';
export 'bitcoin_cash_wallet_service.dart';
export 'exceptions/exceptions.dart';
export 'mnemonic.dart';
export 'bitcoin_cash_address_utils.dart';

View file

@ -1,13 +1,14 @@
import 'package:bitbox/bitbox.dart' as bitbox;
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:cw_bitcoin/electrum_wallet.dart';
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart';
@ -30,6 +31,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required Uint8List seedBytes,
required EncryptionFileUtils encryptionFileUtils,
String? passphrase,
BitcoinAddressType? addressPageType,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
@ -45,7 +47,8 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
initialBalance: initialBalance,
seedBytes: seedBytes,
currency: CryptoCurrency.bch,
encryptionFileUtils: encryptionFileUtils) {
encryptionFileUtils: encryptionFileUtils,
passphrase: passphrase) {
walletAddresses = BitcoinCashWalletAddresses(
walletInfo,
initialAddresses: initialAddresses,
@ -67,6 +70,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
required WalletInfo walletInfo,
required Box<UnspentCoinsInfo> unspentCoinsInfo,
required EncryptionFileUtils encryptionFileUtils,
String? passphrase,
String? addressPageType,
List<BitcoinAddressRecord>? initialAddresses,
ElectrumBalance? initialBalance,
@ -79,11 +83,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
unspentCoinsInfo: unspentCoinsInfo,
initialAddresses: initialAddresses,
initialBalance: initialBalance,
seedBytes: await MnemonicBip39.toSeed(mnemonic),
seedBytes: await MnemonicBip39.toSeed(mnemonic, passphrase: passphrase),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: initialRegularAddressIndex,
initialChangeAddressIndex: initialChangeAddressIndex,
addressPageType: P2pkhAddressType.p2pkh,
passphrase: passphrase,
);
}
@ -150,11 +155,12 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
}
}).toList(),
initialBalance: snp?.balance,
seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!),
seedBytes: await MnemonicBip39.toSeed(keysData.mnemonic!, passphrase: keysData.passphrase),
encryptionFileUtils: encryptionFileUtils,
initialRegularAddressIndex: snp?.regularAddressIndex,
initialChangeAddressIndex: snp?.changeAddressIndex,
addressPageType: P2pkhAddressType.p2pkh,
passphrase: keysData.passphrase,
);
}

View file

@ -2,17 +2,19 @@ import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
class BitcoinCashNewWalletCredentials extends WalletCredentials {
BitcoinCashNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
: super(name: name, walletInfo: walletInfo, password: password);
BitcoinCashNewWalletCredentials(
{required String name, WalletInfo? walletInfo, String? password, String? passphrase})
: super(name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
}
class BitcoinCashRestoreWalletFromSeedCredentials extends WalletCredentials {
BitcoinCashRestoreWalletFromSeedCredentials(
{required String name,
required String password,
required this.mnemonic,
WalletInfo? walletInfo})
: super(name: name, password: password, walletInfo: walletInfo);
BitcoinCashRestoreWalletFromSeedCredentials({
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

@ -1,6 +1,8 @@
import 'dart:io';
import 'package:bip39/bip39.dart';
import 'package:collection/collection.dart';
import 'package:cw_bitcoin/bitcoin_mnemonics_bip39.dart';
import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart';
import 'package:cw_core/encryption_file_utils.dart';
import 'package:cw_core/pathForWallet.dart';
@ -9,7 +11,6 @@ import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:collection/collection.dart';
import 'package:hive/hive.dart';
class BitcoinCashWalletService extends WalletService<
@ -35,11 +36,12 @@ class BitcoinCashWalletService extends WalletService<
final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
final wallet = await BitcoinCashWalletBase.create(
mnemonic: await MnemonicBip39.generate(strength: strength),
mnemonic: await MnemonicBip39.generate(strength: strength),
password: credentials.password!,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
passphrase: credentials.passphrase,
);
await wallet.save();
await wallet.init();
@ -54,11 +56,11 @@ class BitcoinCashWalletService extends WalletService<
try {
final wallet = await BitcoinCashWalletBase.open(
password: password,
name: name,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
password: password,
name: name,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
saveBackup(name);
@ -66,11 +68,11 @@ class BitcoinCashWalletService extends WalletService<
} catch (_) {
await restoreWalletFilesFromBackup(name);
final wallet = await BitcoinCashWalletBase.open(
password: password,
name: name,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
password: password,
name: name,
walletInfo: walletInfo,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
);
await wallet.init();
return wallet;
@ -130,7 +132,9 @@ class BitcoinCashWalletService extends WalletService<
mnemonic: credentials.mnemonic,
walletInfo: credentials.walletInfo!,
unspentCoinsInfo: unspentCoinsInfoSource,
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
passphrase: credentials.passphrase
);
await wallet.save();
await wallet.init();
return wallet;

View file

@ -46,6 +46,8 @@ abstract class WalletBase<BalanceType extends Balance, HistoryType extends Trans
String? get hexSeed => null;
String? get passphrase => null;
Object get keys;
WalletAddresses get walletAddresses;

View file

@ -29,8 +29,9 @@ class CWBitcoin extends Bitcoin {
@override
WalletCredentials createBitcoinNewWalletCredentials(
{required String name, WalletInfo? walletInfo, String? password}) =>
BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
{required String name, WalletInfo? walletInfo, String? password, String? passphrase}) =>
BitcoinNewWalletCredentials(
name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
@override
WalletCredentials createBitcoinHardwareWalletCredentials(
@ -202,8 +203,8 @@ class CWBitcoin extends Bitcoin {
await bitcoinWallet.updateAllUnspents();
}
WalletService createBitcoinWalletService(
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource,
Box<UnspentCoinsInfo> unspentCoinSource, bool alwaysScan, bool isDirect) {
return BitcoinWalletService(walletInfoSource, unspentCoinSource, alwaysScan, isDirect);
}
@ -315,7 +316,7 @@ class CWBitcoin extends Bitcoin {
for (DerivationType dType in electrum_derivations.keys) {
late Uint8List seedBytes;
if (dType == DerivationType.electrum) {
seedBytes = await mnemonicToSeedBytes(mnemonic);
seedBytes = await mnemonicToSeedBytes(mnemonic, passphrase: passphrase ?? "");
} else if (dType == DerivationType.bip39) {
seedBytes = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase ?? '');
}

View file

@ -15,14 +15,16 @@ class CWBitcoinCash extends BitcoinCash {
required String name,
WalletInfo? walletInfo,
String? password,
String? passphrase,
}) =>
BitcoinCashNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
BitcoinCashNewWalletCredentials(
name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
@override
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
{required String name, required String mnemonic, required String password}) =>
{required String name, required String mnemonic, required String password, String? passphrase}) =>
BitcoinCashRestoreWalletFromSeedCredentials(
name: name, mnemonic: mnemonic, password: password);
name: name, mnemonic: mnemonic, password: password, passphrase: passphrase);
@override
TransactionPriority deserializeBitcoinCashTransactionPriority(int raw) =>

View file

@ -75,8 +75,10 @@ class WalletCreationService {
bool get _hasSeedPhraseLengthOption {
switch (type) {
case WalletType.ethereum:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.bitcoinCash:
case WalletType.ethereum:
case WalletType.polygon:
case WalletType.solana:
case WalletType.tron:
@ -84,8 +86,6 @@ class WalletCreationService {
case WalletType.monero:
case WalletType.wownero:
case WalletType.none:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.haven:
case WalletType.nano:
case WalletType.banano:

View file

@ -146,7 +146,7 @@ import 'package:cake_wallet/view_model/cake_pay/cake_pay_purchase_view_model.dar
import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
@ -179,6 +179,7 @@ import 'package:cake_wallet/store/dashboard/trades_store.dart';
import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart';
import 'package:cake_wallet/store/node_list_store.dart';
import 'package:cake_wallet/store/secret_store.dart';
import 'package:cake_wallet/store/seed_settings_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/store/templates/send_template_store.dart';
@ -331,6 +332,7 @@ Future<void> setup({
YatStore(appStore: getIt.get<AppStore>(), secureStorage: getIt.get<SecureStorage>())..init());
getIt.registerSingleton<AnonpayTransactionsStore>(
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
getIt.registerSingleton<SeedSettingsStore>(SeedSettingsStore());
getIt.registerLazySingleton(() => LedgerViewModel());
@ -361,6 +363,7 @@ Future<void> setup({
getIt.get<WalletCreationService>(param1: type),
_walletInfoSource,
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
getIt.get<SeedSettingsViewModel>(),
type: type));
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
@ -422,14 +425,21 @@ Future<void> setup({
walletType: args.walletType ?? currentWalletType);
});
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
});
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) =>
WalletRestorationFromQRVM(
getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type),
_walletInfoSource,
type,
getIt.get<SeedSettingsViewModel>()));
getIt.registerFactoryParam<WalletHardwareRestoreViewModel, WalletType, void>((type, _) =>
WalletHardwareRestoreViewModel(getIt.get<LedgerViewModel>(), getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
WalletHardwareRestoreViewModel(
getIt.get<LedgerViewModel>(),
getIt.get<AppStore>(),
getIt.get<WalletCreationService>(param1: type),
_walletInfoSource,
getIt.get<SeedSettingsViewModel>(),
type: type));
getIt.registerFactory<WalletAddressListViewModel>(() => WalletAddressListViewModel(
@ -833,7 +843,7 @@ Future<void> setup({
getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
getIt.registerFactory<SeedTypeViewModel>(() => SeedTypeViewModel(getIt.get<AppStore>()));
getIt.registerFactory<SeedSettingsViewModel>(() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
getIt.registerFactoryParam<WalletSeedPage, bool, void>((bool isWalletCreated, _) =>
WalletSeedPage(getIt.get<WalletSeedViewModel>(), isNewWalletCreated: isWalletCreated));
@ -1018,12 +1028,12 @@ Future<void> setup({
getIt.registerFactory(() => FaqPage(getIt.get<SettingsStore>()));
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>((type, _) =>
WalletRestoreViewModel(
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
WalletRestoreViewModel(getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type),
_walletInfoSource, getIt.get<SeedSettingsViewModel>(),
type: type));
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>((type, _) => WalletRestorePage(
getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedTypeViewModel>()));
getIt.get<WalletRestoreViewModel>(param1: type), getIt.get<SeedSettingsViewModel>()));
getIt.registerFactoryParam<WalletRestoreChooseDerivationViewModel, List<DerivationInfo>, void>(
(derivations, _) => WalletRestoreChooseDerivationViewModel(derivationInfos: derivations));

View file

@ -60,7 +60,7 @@ class LanguageService {
'yo': 'nga',
'ha': 'hau',
'tl': 'phl',
'hy': 'arm'
'hy': 'arm',
};
static final list = <String, String>{};

View file

@ -77,6 +77,7 @@ class PreferencesKey {
static const exchangeProvidersSelection = 'exchange-providers-selection';
static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
static const moneroSeedType = 'monero_seed_type';
static const bitcoinSeedType = 'bitcoin_seed_type';
static const clearnetDonationLink = 'clearnet_donation_link';
static const onionDonationLink = 'onion_donation_link';
static const donationLinkWalletName = 'donation_link_wallet_name';

View file

@ -1,18 +1,19 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/enumerable_item.dart';
import 'package:cw_core/wallet_info.dart';
class SeedType extends EnumerableItem<int> with Serializable<int> {
const SeedType({required String title, required int raw}) : super(title: title, raw: raw);
class MoneroSeedType extends EnumerableItem<int> with Serializable<int> {
const MoneroSeedType({required String title, required int raw}) : super(title: title, raw: raw);
static const all = [SeedType.legacy, SeedType.polyseed];
static const all = [MoneroSeedType.legacy, MoneroSeedType.polyseed];
static const defaultSeedType = polyseed;
static const legacy = SeedType(raw: 0, title: 'Legacy (25 words)');
static const polyseed = SeedType(raw: 1, title: 'Polyseed (16 words)');
static const wowneroSeed = SeedType(raw: 2, title: 'Wownero (14 words)');
static const legacy = MoneroSeedType(raw: 0, title: 'Legacy (25 words)');
static const polyseed = MoneroSeedType(raw: 1, title: 'Polyseed (16 words)');
static const wowneroSeed = MoneroSeedType(raw: 2, title: 'Wownero (14 words)');
static SeedType deserialize({required int raw}) {
static MoneroSeedType deserialize({required int raw}) {
switch (raw) {
case 0:
return legacy;
@ -28,14 +29,39 @@ class SeedType extends EnumerableItem<int> with Serializable<int> {
@override
String toString() {
switch (this) {
case SeedType.legacy:
case MoneroSeedType.legacy:
return S.current.seedtype_legacy;
case SeedType.polyseed:
case MoneroSeedType.polyseed:
return S.current.seedtype_polyseed;
case SeedType.wowneroSeed:
case MoneroSeedType.wowneroSeed:
return S.current.seedtype_wownero;
default:
return '';
}
}
}
class BitcoinSeedType extends EnumerableItem<int> with Serializable<int> {
const BitcoinSeedType(this.type, {required String title, required int raw})
: super(title: title, raw: raw);
final DerivationType type;
static const all = [BitcoinSeedType.electrum, BitcoinSeedType.bip39];
static const defaultDerivationType = bip39;
static const electrum = BitcoinSeedType(DerivationType.electrum, raw: 0, title: 'Electrum');
static const bip39 = BitcoinSeedType(DerivationType.bip39, raw: 1, title: 'BIP39');
static BitcoinSeedType deserialize({required int raw}) {
switch (raw) {
case 0:
return electrum;
case 1:
return bip39;
default:
throw Exception('Unexpected token: $raw for SeedType deserialize');
}
}
}

View file

@ -17,6 +17,8 @@ import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_options_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart';
import 'package:cake_wallet/src/screens/connect_device/select_hardware_wallet_account_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
@ -27,8 +29,8 @@ import 'package:cake_wallet/src/screens/dashboard/edit_token_page.dart';
import 'package:cake_wallet/src/screens/dashboard/home_settings_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_details_page.dart';
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/transactions_page.dart';
import 'package:cake_wallet/src/screens/dashboard/sign_page.dart';
import 'package:cake_wallet/src/screens/disclaimer/disclaimer_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
@ -43,10 +45,9 @@ import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_receive_page.dart';
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
@ -69,11 +70,9 @@ import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart';
import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
@ -85,19 +84,18 @@ import 'package:cake_wallet/src/screens/support/support_page.dart';
import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_page.dart';
import 'package:cake_wallet/src/screens/welcome/create_welcome_page.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
@ -106,7 +104,7 @@ import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
@ -120,7 +118,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
import 'src/screens/dashboard/pages/nft_import_page.dart';
late RouteSettings currentRouteSettings;
@ -135,7 +133,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newWalletFromWelcome:
if (SettingsStoreBase.walletPasswordDirectInput) {
if (availableWalletTypes.length == 1) {
return createRoute(RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
return createRoute(
RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
} else {
return createRoute(RouteSettings(name: Routes.newWalletType));
}
@ -162,10 +161,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.newWallet:
final type = settings.arguments as WalletType;
final walletNewVM = getIt.get<WalletNewVM>(param1: type);
final seedTypeViewModel = getIt.get<SeedTypeViewModel>();
final seedSettingsViewModel = getIt.get<SeedSettingsViewModel>();
return CupertinoPageRoute<void>(
builder: (_) => NewWalletPage(walletNewVM, seedTypeViewModel));
builder: (_) => NewWalletPage(walletNewVM, seedSettingsViewModel));
case Routes.chooseHardwareWalletAccount:
final arguments = settings.arguments as List<dynamic>;
@ -348,16 +347,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.auth:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
=> SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
builder: (_) => SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
callback: settings.arguments as OnAuthenticationFinished),
instanceName: 'wallet_unlock_verifiable',
param2: true)
: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: true));
instanceName: 'wallet_unlock_verifiable',
param2: true)
: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished, param2: true));
case Routes.totpAuthCodePage:
final args = settings.arguments as TotpAuthArgumentsModel;
@ -371,28 +368,25 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.walletUnlockLoadable:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
=> getIt.get<WalletUnlockPage>(
builder: (_) => getIt.get<WalletUnlockPage>(
param1: settings.arguments as WalletUnlockArguments,
instanceName: 'wallet_unlock_loadable',
instanceName: 'wallet_unlock_loadable',
param2: true));
case Routes.unlock:
return MaterialPageRoute<void>(
fullscreenDialog: true,
builder: (_)
=> SettingsStoreBase.walletPasswordDirectInput
? WillPopScope(
child: getIt.get<WalletUnlockPage>(
builder: (_) => SettingsStoreBase.walletPasswordDirectInput
? WillPopScope(
child: getIt.get<WalletUnlockPage>(
param1: WalletUnlockArguments(
callback: settings.arguments as OnAuthenticationFinished),
callback: settings.arguments as OnAuthenticationFinished),
param2: false,
instanceName: 'wallet_unlock_verifiable'),
onWillPop: () async => false)
: WillPopScope(
child: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished,
param2: false),
onWillPop: () async => false)
: WillPopScope(
child: getIt.get<AuthPage>(
param1: settings.arguments as OnAuthenticationFinished, param2: false),
onWillPop: () async => false));
case Routes.silentPaymentsSettings:
@ -437,11 +431,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>(
builder: (context) => WillPopScope(
child: SettingsStoreBase.walletPasswordDirectInput
? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
: getIt.get<AuthPage>(instanceName: 'login'),
? getIt.get<WalletUnlockPage>(instanceName: 'wallet_password_login')
: getIt.get<AuthPage>(instanceName: 'login'),
onWillPop: () async =>
// FIX-ME: Additional check does it works correctly
(await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ?? false)),
// FIX-ME: Additional check does it works correctly
(await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ??
false)),
fullscreenDialog: true);
case Routes.newPowNode:
@ -537,8 +532,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.support:
return CupertinoPageRoute<void>(
fullscreenDialog: true,
builder: (_) => getIt.get<SupportPage>());
fullscreenDialog: true, builder: (_) => getIt.get<SupportPage>());
case Routes.supportLiveChat:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<SupportChatPage>());
@ -567,8 +561,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.cakePayBuyCardPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<CakePayBuyCardPage>(param1: args));
return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayBuyCardPage>(param1: args));
case Routes.cakePayBuyCardDetailPage:
final args = settings.arguments as List;
@ -582,7 +575,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.cakePayVerifyOtpPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayVerifyOtpPage>(param1: args));
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<CakePayVerifyOtpPage>(param1: args));
case Routes.cakePayAccountPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayAccountPage>());
@ -597,16 +591,19 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.advancedPrivacySettings:
final args = settings.arguments as Map<String, dynamic>;
final type = args['type'] as WalletType;
final isFromRestore = args['isFromRestore'] as bool? ?? false;
final useTestnet = args['useTestnet'] as bool;
final toggleTestnet = args['toggleTestnet'] as Function(bool? val);
return CupertinoPageRoute<void>(
builder: (_) => AdvancedPrivacySettingsPage(
useTestnet,
toggleTestnet,
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
getIt.get<SeedTypeViewModel>(),
isFromRestore: isFromRestore,
useTestnet: useTestnet,
toggleUseTestnet: toggleTestnet,
advancedPrivacySettingsViewModel:
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
nodeViewModel: getIt.get<NodeCreateOrEditViewModel>(param1: type, param2: false),
seedSettingsViewModel: getIt.get<SeedSettingsViewModel>(),
));
case Routes.anonPayInvoicePage:

View file

@ -1,23 +1,7 @@
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/widgets/address_text_field.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/themes/extensions/address_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
class VerifyForm extends StatefulWidget {
VerifyForm({

View file

@ -3,52 +3,61 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class AdvancedPrivacySettingsPage extends BasePage {
AdvancedPrivacySettingsPage(this.useTestnet, this.toggleUseTestnet,
this.advancedPrivacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel);
AdvancedPrivacySettingsPage({
required this.isFromRestore,
required this.useTestnet,
required this.toggleUseTestnet,
required this.advancedPrivacySettingsViewModel,
required this.nodeViewModel,
required this.seedSettingsViewModel,
});
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
@override
String get title => S.current.privacy_settings;
final bool isFromRestore;
final bool useTestnet;
final Function(bool? val) toggleUseTestnet;
@override
Widget body(BuildContext context) => AdvancedPrivacySettingsBody(useTestnet, toggleUseTestnet,
advancedPrivacySettingsViewModel, nodeViewModel, seedTypeViewModel);
Widget body(BuildContext context) => _AdvancedPrivacySettingsBody(isFromRestore, useTestnet,
toggleUseTestnet, advancedPrivacySettingsViewModel, nodeViewModel, seedSettingsViewModel);
}
class AdvancedPrivacySettingsBody extends StatefulWidget {
const AdvancedPrivacySettingsBody(this.useTestnet, this.toggleUseTestnet,
class _AdvancedPrivacySettingsBody extends StatefulWidget {
const _AdvancedPrivacySettingsBody(this.isFromRestore, this.useTestnet, this.toggleUseTestnet,
this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
{Key? key})
: super(key: key);
final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedTypeViewModel;
final bool isFromRestore;
final bool useTestnet;
final Function(bool? val) toggleUseTestnet;
@ -56,15 +65,23 @@ class AdvancedPrivacySettingsBody extends StatefulWidget {
_AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
}
class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBody> {
_AdvancedPrivacySettingsBodyState();
class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBody> {
final TextEditingController passphraseController = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool? testnetValue;
@override
void initState() {
passphraseController.text = widget.seedTypeViewModel.passphrase ?? '';
passphraseController
.addListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
super.initState();
}
@override
Widget build(BuildContext context) {
if (testnetValue == null && widget.useTestnet != null) {
if (testnetValue == null && widget.useTestnet) {
testnetValue = widget.useTestnet;
}
@ -97,6 +114,52 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
),
);
}),
if (widget.privacySettingsViewModel.hasSeedTypeOption)
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<MoneroSeedType>(
title: S.current.seedtype,
items: MoneroSeedType.all,
selectedItem: widget.seedTypeViewModel.moneroSeedType,
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
),
);
}),
if ([WalletType.bitcoin, WalletType.litecoin]
.contains(widget.privacySettingsViewModel.type))
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<BitcoinSeedType>(
title: S.current.seedtype,
items: BitcoinSeedType.all,
selectedItem: widget.seedTypeViewModel.bitcoinSeedType,
onItemSelected: widget.seedTypeViewModel.setBitcoinSeedType,
),
);
}),
if (!widget.isFromRestore) ...[
Observer(builder: (_) {
if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
return SettingsPickerCell<SeedPhraseLength>(
title: S.current.seed_phrase_length,
items: SeedPhraseLength.values,
selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
onItemSelected: (SeedPhraseLength length) {
widget.privacySettingsViewModel.setSeedPhraseLength(length);
},
);
return Container();
}),
if (widget.privacySettingsViewModel.hasPassphraseOption)
Padding(
padding: EdgeInsets.all(24),
child: BaseTextFormField(
hintText: S.current.passphrase,
controller: passphraseController,
obscureText: true,
),
),
],
Observer(builder: (_) {
return Column(
children: [
@ -122,31 +185,9 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
],
);
}),
if (widget.privacySettingsViewModel.hasSeedPhraseLengthOption)
Observer(builder: (_) {
return SettingsPickerCell<SeedPhraseLength>(
title: S.current.seed_phrase_length,
items: SeedPhraseLength.values,
selectedItem: widget.privacySettingsViewModel.seedPhraseLength,
onItemSelected: (SeedPhraseLength length) {
widget.privacySettingsViewModel.setSeedPhraseLength(length);
},
);
}),
if (widget.privacySettingsViewModel.hasSeedTypeOption)
Observer(builder: (_) {
return SettingsChoicesCell(
ChoicesListItem<SeedType>(
title: S.current.seedtype,
items: SeedType.all,
selectedItem: widget.seedTypeViewModel.moneroSeedType,
onItemSelected: widget.seedTypeViewModel.setMoneroSeedType,
),
);
}),
if (widget.privacySettingsViewModel.type == WalletType.bitcoin)
Builder(builder: (_) {
final val = testnetValue!;
final val = testnetValue ?? false;
return SettingsSwitcherCell(
title: S.current.use_testnet,
value: val,
@ -154,7 +195,7 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
setState(() {
testnetValue = !val;
});
widget.toggleUseTestnet!.call(testnetValue);
widget.toggleUseTestnet.call(testnetValue);
});
}),
],
@ -203,4 +244,11 @@ class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBod
),
);
}
@override
void dispose() {
passphraseController
.removeListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
super.dispose();
}
}

View file

@ -1,36 +1,35 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/main.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/wallet_name_validator.dart';
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/src/widgets/seed_language_selector.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class NewWalletPage extends BasePage {
NewWalletPage(this._walletNewVM, this._seedTypeViewModel);
NewWalletPage(this._walletNewVM, this._seedSettingsViewModel);
final WalletNewVM _walletNewVM;
final SeedTypeViewModel _seedTypeViewModel;
final SeedSettingsViewModel _seedSettingsViewModel;
final walletNameImage = Image.asset('assets/images/wallet_name.png');
@ -51,15 +50,15 @@ class NewWalletPage extends BasePage {
Widget body(BuildContext context) => WalletNameForm(
_walletNewVM,
currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage,
_seedTypeViewModel);
_seedSettingsViewModel);
}
class WalletNameForm extends StatefulWidget {
WalletNameForm(this._walletNewVM, this.walletImage, this._seedTypeViewModel);
WalletNameForm(this._walletNewVM, this.walletImage, this._seedSettingsViewModel);
final WalletNewVM _walletNewVM;
final Image walletImage;
final SeedTypeViewModel _seedTypeViewModel;
final SeedSettingsViewModel _seedSettingsViewModel;
@override
_WalletNameFormState createState() => _WalletNameFormState(_walletNewVM);
@ -110,7 +109,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
}
});
_setSeedType(SeedType.defaultSeedType);
_setSeedType(MoneroSeedType.defaultSeedType);
super.initState();
}
@ -285,12 +284,12 @@ class _WalletNameFormState extends State<WalletNameForm> {
builder: (BuildContext build) => Padding(
padding: EdgeInsets.only(top: 24),
child: SelectButton(
text: widget._seedTypeViewModel.moneroSeedType.title,
text: widget._seedSettingsViewModel.moneroSeedType.title,
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
items: SeedType.all,
items: MoneroSeedType.all,
selectedAtIndex: isPolyseed ? 1 : 0,
onItemSelected: _setSeedType,
isSeparated: false,
@ -308,8 +307,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
key: _languageSelectorKey,
initialSelected: defaultSeedLanguage,
seedType: _walletNewVM.hasSeedType
? widget._seedTypeViewModel.moneroSeedType
: SeedType.legacy,
? widget._seedSettingsViewModel.moneroSeedType
: MoneroSeedType.legacy,
),
),
)
@ -380,10 +379,10 @@ class _WalletNameFormState extends State<WalletNameForm> {
_formProcessing = false;
}
bool get isPolyseed => widget._seedTypeViewModel.moneroSeedType == SeedType.polyseed;
bool get isPolyseed => widget._seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed;
void _setSeedType(SeedType item) {
widget._seedTypeViewModel.setMoneroSeedType(item);
void _setSeedType(MoneroSeedType item) {
widget._seedSettingsViewModel.setMoneroSeedType(item);
_languageSelectorKey.currentState?.selected = defaultSeedLanguage; // Reset Seed language
}
}

View file

@ -9,35 +9,34 @@ import 'package:cake_wallet/src/widgets/seed_language_picker.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
class WalletRestoreFromSeedForm extends StatefulWidget {
WalletRestoreFromSeedForm(
{Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type,
required this.displayWalletPassword,
required this.seedTypeViewModel,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange,
this.onPasswordChange,
this.onRepeatedPasswordChange})
: super(key: key);
WalletRestoreFromSeedForm({Key? key,
required this.displayLanguageSelector,
required this.displayBlockHeightSelector,
required this.displayPassphrase,
required this.type,
required this.displayWalletPassword,
required this.seedSettingsViewModel,
this.blockHeightFocusNode,
this.onHeightOrDateEntered,
this.onSeedChange,
this.onLanguageChange,
this.onPasswordChange,
this.onRepeatedPasswordChange,
}) : super(key: key);
final WalletType type;
final bool displayLanguageSelector;
final bool displayBlockHeightSelector;
final bool displayWalletPassword;
final bool displayPassphrase;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
final FocusNode? blockHeightFocusNode;
final Function(bool)? onHeightOrDateEntered;
final void Function(String)? onSeedChange;
@ -58,7 +57,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
languageController = TextEditingController(),
nameTextEditingController = TextEditingController(),
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null,
repeatedPasswordTextEditingController = displayWalletPassword
? TextEditingController()
: null,
passphraseController = TextEditingController(),
seedTypeController = TextEditingController();
@ -75,10 +76,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
String language;
void Function()? passwordListener;
void Function()? repeatedPasswordListener;
void Function()? passphraseListener;
@override
void initState() {
_setSeedType(widget.seedTypeViewModel.moneroSeedType);
_setSeedType(widget.seedSettingsViewModel.moneroSeedType);
_setLanguageLabel(language);
if (passwordTextEditingController != null) {
@ -87,14 +89,19 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
}
if (repeatedPasswordTextEditingController != null) {
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordListener =
() => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
}
passphraseListener = () => widget.seedSettingsViewModel.setPassphrase(passphraseController.text);
passphraseController.addListener(passphraseListener!);
moneroSeedTypeReaction =
reaction((_) => widget.seedTypeViewModel.moneroSeedType, (SeedType item) {
_setSeedType(item);
_changeLanguage('English');
});
reaction((_) => widget.seedSettingsViewModel.moneroSeedType, (MoneroSeedType item) {
_setSeedType(item);
_changeLanguage('English');
});
super.initState();
}
@ -110,6 +117,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
if (repeatedPasswordListener != null) {
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
}
passphraseController.removeListener(passphraseListener!);
super.dispose();
}
@ -118,11 +128,13 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
Polyseed.isValidSeed(seed)) {
final lang = PolyseedLang.getByPhrase(seed);
_changeSeedType(SeedType.polyseed);
_changeSeedType(MoneroSeedType.polyseed);
_changeLanguage(lang.nameEnglish);
}
if (widget.type == WalletType.wownero && seed.split(" ").length == 14) {
_changeSeedType(SeedType.wowneroSeed);
if (widget.type == WalletType.wownero && seed
.split(" ")
.length == 14) {
_changeSeedType(MoneroSeedType.wowneroSeed);
_changeLanguage("English");
}
widget.onSeedChange?.call(seed);
@ -140,7 +152,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
children: [
BaseTextFormField(
controller: nameTextEditingController,
hintText: S.of(context).wallet_name,
hintText: S
.of(context)
.wallet_name,
suffixIcon: IconButton(
onPressed: () async {
final rName = await generateName();
@ -156,7 +170,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
color: Theme.of(context).hintColor,
color: Theme
.of(context)
.hintColor,
),
width: 34,
height: 34,
@ -183,13 +199,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => Picker(
builder: (_) =>
Picker(
items: _getItems(),
selectedAtIndex: isPolyseed
? 1
: seedTypeController.value.text.contains("14")
? 2
: 0,
? 2
: 0,
mainAxisAlignment: MainAxisAlignment.start,
onItemSelected: _changeSeedType,
isSeparated: false,
@ -211,37 +228,43 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
if (widget.displayWalletPassword)
...[BaseTextFormField(
controller: passwordTextEditingController,
hintText: S.of(context).password,
hintText: S
.of(context)
.password,
obscureText: true),
BaseTextFormField(
controller: repeatedPasswordTextEditingController,
hintText: S.of(context).repeat_wallet_password,
obscureText: true)],
hintText: S
.of(context)
.repeat_wallet_password,
obscureText: true)
],
if (widget.displayLanguageSelector)
if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
GestureDetector(
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) => SeedLanguagePicker(
selected: language,
onItemSelected: _changeLanguage,
seedType: isPolyseed ? SeedType.polyseed : SeedType.legacy,
));
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 20.0),
child: IgnorePointer(
child: BaseTextFormField(
controller: languageController,
enableInteractiveSelection: false,
readOnly: true,
suffixIcon: expandIcon,
if (!seedTypeController.value.text.contains("14") && widget.displayLanguageSelector)
GestureDetector(
onTap: () async {
await showPopUp<void>(
context: context,
builder: (_) =>
SeedLanguagePicker(
selected: language,
onItemSelected: _changeLanguage,
seedType: isPolyseed ? MoneroSeedType.polyseed : MoneroSeedType.legacy,
));
},
child: Container(
color: Colors.transparent,
padding: EdgeInsets.only(top: 20.0),
child: IgnorePointer(
child: BaseTextFormField(
controller: languageController,
enableInteractiveSelection: false,
readOnly: true,
suffixIcon: expandIcon,
),
),
),
),
),
if ((!isPolyseed) && widget.displayBlockHeightSelector)
BlockchainHeightWidget(
focusNode: widget.blockHeightFocusNode,
@ -262,17 +285,20 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
}
bool get isPolyseed =>
widget.seedTypeViewModel.moneroSeedType == SeedType.polyseed &&
(widget.type == WalletType.monero || widget.type == WalletType.wownero);
widget.seedSettingsViewModel.moneroSeedType == MoneroSeedType.polyseed &&
(widget.type == WalletType.monero || widget.type == WalletType.wownero);
Widget get expandIcon => Container(
Widget get expandIcon =>
Container(
padding: EdgeInsets.all(18),
width: 24,
height: 24,
child: Image.asset(
'assets/images/arrow_bottom_purple_icon.png',
height: 8,
color: Theme.of(context).hintColor,
color: Theme
.of(context)
.hintColor,
),
);
@ -280,8 +306,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
final setLang = isPolyseed
? "POLYSEED_$language"
: seedTypeController.value.text.contains("14")
? "WOWSEED_" + language
: language;
? "WOWSEED_" + language
: language;
setState(() {
this.language = setLang;
seedWidgetStateKey.currentState!.changeSeedLanguage(setLang);
@ -293,24 +319,24 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
void _setLanguageLabel(String language) =>
languageController.text = '${language.replaceAll("POLYSEED_", "")} (Seed language)';
void _changeSeedType(SeedType item) {
void _changeSeedType(MoneroSeedType item) {
_setSeedType(item);
_changeLanguage('English');
widget.seedTypeViewModel.setMoneroSeedType(item);
widget.seedSettingsViewModel.setMoneroSeedType(item);
}
void _setSeedType(SeedType item) {
void _setSeedType(MoneroSeedType item) {
seedTypeController.text = item.toString();
}
List<SeedType> _getItems() {
List<MoneroSeedType> _getItems() {
switch (widget.type) {
case WalletType.monero:
return [SeedType.legacy, SeedType.polyseed];
return [MoneroSeedType.legacy, MoneroSeedType.polyseed];
case WalletType.wownero:
return [SeedType.legacy, SeedType.polyseed, SeedType.wowneroSeed];
return [MoneroSeedType.legacy, MoneroSeedType.polyseed, MoneroSeedType.wowneroSeed];
default:
return [SeedType.legacy];
return [MoneroSeedType.legacy];
}
}
}

View file

@ -12,7 +12,7 @@ import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
@ -23,7 +23,7 @@ import 'package:mobx/mobx.dart';
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
class WalletRestorePage extends BasePage {
WalletRestorePage(this.walletRestoreViewModel, this.seedTypeViewModel)
WalletRestorePage(this.walletRestoreViewModel, this.seedSettingsViewModel)
: walletRestoreFromSeedFormKey = GlobalKey<WalletRestoreFromSeedFormState>(),
walletRestoreFromKeysFormKey = GlobalKey<WalletRestoreFromKeysFromState>(),
_pages = [],
@ -33,7 +33,7 @@ class WalletRestorePage extends BasePage {
switch (mode) {
case WalletRestoreMode.seed:
_pages.add(WalletRestoreFromSeedForm(
seedTypeViewModel: seedTypeViewModel,
seedSettingsViewModel: seedSettingsViewModel,
displayBlockHeightSelector:
walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
displayLanguageSelector: walletRestoreViewModel.hasSeedLanguageSelector,
@ -96,7 +96,7 @@ class WalletRestorePage extends BasePage {
));
final WalletRestoreViewModel walletRestoreViewModel;
final SeedTypeViewModel seedTypeViewModel;
final SeedSettingsViewModel seedSettingsViewModel;
final PageController _controller;
final List<Widget> _pages;
final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
@ -233,6 +233,7 @@ class WalletRestorePage extends BasePage {
onTap: () {
Navigator.of(context)
.pushNamed(Routes.advancedPrivacySettings, arguments: {
'isFromRestore': true,
'type': walletRestoreViewModel.type,
'useTestnet': walletRestoreViewModel.useTestnet,
'toggleTestnet': walletRestoreViewModel.toggleUseTestnet
@ -322,8 +323,7 @@ class WalletRestorePage extends BasePage {
}
if (walletRestoreViewModel.hasPassphrase) {
credentials['passphrase'] =
walletRestoreFromSeedFormKey.currentState!.passphraseController.text;
credentials['passphrase'] = seedSettingsViewModel.passphrase;
}
credentials['name'] =
@ -426,6 +426,7 @@ class WalletRestorePage extends BasePage {
}
await walletRestoreViewModel.create(options: _credentials());
seedSettingsViewModel.setPassphrase(null);
} catch (e) {
_formProcessing = false;
rethrow;

View file

@ -11,36 +11,36 @@ class SeedLanguagePickerOption {
final String name;
final String nameLocalized;
final Image image;
final List<SeedType> supportedSeedTypes;
final List<MoneroSeedType> supportedSeedTypes;
}
final List<SeedLanguagePickerOption> seedLanguages = [
SeedLanguagePickerOption('English', S.current.seed_language_english,
Image.asset('assets/images/flags/usa.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/usa.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Simplified)', S.current.seed_language_chinese,
Image.asset('assets/images/flags/chn.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Chinese (Traditional)', S.current.seed_language_chinese_traditional,
Image.asset('assets/images/flags/chn.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/chn.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Dutch', S.current.seed_language_dutch,
Image.asset('assets/images/flags/nld.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/nld.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('German', S.current.seed_language_german,
Image.asset('assets/images/flags/deu.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/deu.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('Japanese', S.current.seed_language_japanese,
Image.asset('assets/images/flags/jpn.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/jpn.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Korean', S.current.seed_language_korean,
Image.asset('assets/images/flags/kor.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/kor.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Portuguese', S.current.seed_language_portuguese,
Image.asset('assets/images/flags/prt.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/prt.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Russian', S.current.seed_language_russian,
Image.asset('assets/images/flags/rus.png'), [SeedType.legacy]),
Image.asset('assets/images/flags/rus.png'), [MoneroSeedType.legacy]),
SeedLanguagePickerOption('Czech', S.current.seed_language_czech,
Image.asset('assets/images/flags/czk.png'), [SeedType.polyseed]),
Image.asset('assets/images/flags/czk.png'), [MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Spanish', S.current.seed_language_spanish,
Image.asset('assets/images/flags/esp.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/esp.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('French', S.current.seed_language_french,
Image.asset('assets/images/flags/fra.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/fra.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
SeedLanguagePickerOption('Italian', S.current.seed_language_italian,
Image.asset('assets/images/flags/ita.png'), [SeedType.legacy, SeedType.polyseed]),
Image.asset('assets/images/flags/ita.png'), [MoneroSeedType.legacy, MoneroSeedType.polyseed]),
];
const defaultSeedLanguage = 'English';
@ -51,11 +51,11 @@ class SeedLanguagePicker extends StatefulWidget {
SeedLanguagePicker(
{Key? key,
this.selected = defaultSeedLanguage,
this.seedType = SeedType.defaultSeedType,
this.seedType = MoneroSeedType.defaultSeedType,
required this.onItemSelected})
: super(key: key);
final SeedType seedType;
final MoneroSeedType seedType;
final String selected;
final Function(String) onItemSelected;
@ -68,7 +68,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
SeedLanguagePickerState(
{required this.selected, required this.onItemSelected, required this.seedType});
final SeedType seedType;
final MoneroSeedType seedType;
final String selected;
final Function(String) onItemSelected;

View file

@ -7,11 +7,11 @@ import 'package:flutter/material.dart';
class SeedLanguageSelector extends StatefulWidget {
SeedLanguageSelector(
{Key? key, required this.initialSelected, this.seedType = SeedType.defaultSeedType})
{Key? key, required this.initialSelected, this.seedType = MoneroSeedType.defaultSeedType})
: super(key: key);
final String initialSelected;
final SeedType seedType;
final MoneroSeedType seedType;
@override
SeedLanguageSelectorState createState() => SeedLanguageSelectorState(selected: initialSelected);

View file

@ -0,0 +1,11 @@
import 'package:mobx/mobx.dart';
part 'seed_settings_store.g.dart';
class SeedSettingsStore = SeedSettingsStoreBase with _$SeedSettingsStore;
abstract class SeedSettingsStoreBase with Store {
@observable
String? passphrase;
}

View file

@ -1,45 +1,46 @@
import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/action_list_display_mode.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
import 'package:cake_wallet/entities/background_tasks.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:cake_wallet/entities/cake_2fa_preset_options.dart';
import 'package:cake_wallet/entities/exchange_api_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/entities/pin_code_required_duration.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/entities/provider_types.dart';
import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/entities/seed_phrase_length.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/entities/sort_balance_types.dart';
import 'package:cake_wallet/entities/wallet_list_order_types.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cake_wallet/exchange/provider/trocador_exchange_provider.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/package_info.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/set_app_secure_native.dart';
import 'package:cw_core/transaction_priority.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/utils/package_info.dart';
import 'package:cake_wallet/di.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:cake_wallet/entities/language_service.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cw_core/node.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/entities/action_list_display_mode.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cw_core/set_app_secure_native.dart';
part 'settings_store.g.dart';
@ -55,7 +56,8 @@ abstract class SettingsStoreBase with Store {
required BalanceDisplayMode initialBalanceDisplayMode,
required bool initialSaveRecipientAddress,
required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
required SeedType initialMoneroSeedType,
required MoneroSeedType initialMoneroSeedType,
required BitcoinSeedType initialBitcoinSeedType,
required bool initialAppSecure,
required bool initialDisableBuy,
required bool initialDisableSell,
@ -128,6 +130,7 @@ abstract class SettingsStoreBase with Store {
shouldSaveRecipientAddress = initialSaveRecipientAddress,
autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
moneroSeedType = initialMoneroSeedType,
bitcoinSeedType = initialBitcoinSeedType,
fiatApiMode = initialFiatMode,
allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
selectedCake2FAPreset = initialCake2FAPresetOptions,
@ -329,9 +332,14 @@ abstract class SettingsStoreBase with Store {
reaction(
(_) => moneroSeedType,
(SeedType moneroSeedType) =>
(MoneroSeedType moneroSeedType) =>
sharedPreferences.setInt(PreferencesKey.moneroSeedType, moneroSeedType.raw));
reaction(
(_) => bitcoinSeedType,
(BitcoinSeedType bitcoinSeedType) => sharedPreferences.setInt(
PreferencesKey.bitcoinSeedType, bitcoinSeedType.raw));
reaction(
(_) => fiatApiMode,
(FiatApiMode mode) =>
@ -555,7 +563,8 @@ abstract class SettingsStoreBase with Store {
static const defaultAutoGenerateSubaddressStatus = AutoGenerateSubaddressStatus.initialized;
static final walletPasswordDirectInput = Platform.isLinux;
static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
static const defaultMoneroSeedType = SeedType.defaultSeedType;
static const defaultMoneroSeedType = MoneroSeedType.defaultSeedType;
static const defaultBitcoinSeedType = BitcoinSeedType.defaultDerivationType;
@observable
FiatCurrency fiatCurrency;
@ -585,7 +594,10 @@ abstract class SettingsStoreBase with Store {
AutoGenerateSubaddressStatus autoGenerateSubaddressStatus;
@observable
SeedType moneroSeedType;
MoneroSeedType moneroSeedType;
@observable
BitcoinSeedType bitcoinSeedType;
@observable
bool isAppSecure;
@ -945,9 +957,15 @@ abstract class SettingsStoreBase with Store {
final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
final moneroSeedType = _moneroSeedType != null
? SeedType.deserialize(raw: _moneroSeedType)
? MoneroSeedType.deserialize(raw: _moneroSeedType)
: defaultMoneroSeedType;
final _bitcoinSeedType = sharedPreferences.getInt(PreferencesKey.bitcoinSeedType);
final bitcoinSeedType = _bitcoinSeedType != null
? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
: defaultBitcoinSeedType;
final nodes = <WalletType, Node>{};
final powNodes = <WalletType, Node>{};
@ -1111,6 +1129,7 @@ abstract class SettingsStoreBase with Store {
initialSaveRecipientAddress: shouldSaveRecipientAddress,
initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
initialMoneroSeedType: moneroSeedType,
initialBitcoinSeedType: bitcoinSeedType,
initialAppSecure: isAppSecure,
initialDisableBuy: disableBuy,
initialDisableSell: disableSell,
@ -1233,9 +1252,15 @@ abstract class SettingsStoreBase with Store {
final _moneroSeedType = sharedPreferences.getInt(PreferencesKey.moneroSeedType);
moneroSeedType = _moneroSeedType != null
? SeedType.deserialize(raw: _moneroSeedType)
? MoneroSeedType.deserialize(raw: _moneroSeedType)
: defaultMoneroSeedType;
final _bitcoinSeedType = sharedPreferences.getInt(PreferencesKey.bitcoinSeedType);
bitcoinSeedType = _bitcoinSeedType != null
? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
: defaultBitcoinSeedType;
balanceDisplayMode = BalanceDisplayMode.deserialize(
raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
shouldSaveRecipientAddress =

View file

@ -30,6 +30,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
final SettingsStore _settingsStore;
@computed
bool get hasSeedPhraseLengthOption {
// convert to switch case so that it give a syntax error when adding a new wallet type
// thus we don't forget about it
@ -40,11 +41,14 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
case WalletType.solana:
case WalletType.tron:
return true;
case WalletType.bitcoin:
case WalletType.litecoin:
return _settingsStore.bitcoinSeedType == BitcoinSeedType.bip39;
case WalletType.monero:
case WalletType.wownero:
case WalletType.none:
case WalletType.bitcoin:
case WalletType.litecoin:
case WalletType.haven:
case WalletType.nano:
case WalletType.banano:
@ -52,7 +56,13 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
}
}
bool get hasSeedTypeOption => type == WalletType.monero || type == WalletType.wownero;
bool get hasSeedTypeOption => [WalletType.monero, WalletType.wownero].contains(type);
bool get hasPassphraseOption => [
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash,
].contains(type);
@computed
bool get addCustomNode => _addCustomNode;
@ -61,7 +71,7 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
SeedPhraseLength get seedPhraseLength => _settingsStore.seedPhraseLength;
@computed
bool get isPolySeed => _settingsStore.moneroSeedType == SeedType.polyseed;
bool get isPolySeed => _settingsStore.moneroSeedType == MoneroSeedType.polyseed;
@action
void setFiatApiMode(FiatApiMode fiatApiMode) => _settingsStore.fiatApiMode = fiatApiMode;

View file

@ -7,6 +7,7 @@ import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
@ -26,13 +27,13 @@ class WalletRestorationFromQRVM = WalletRestorationFromQRVMBase with _$WalletRes
abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store {
WalletRestorationFromQRVMBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource, WalletType type)
Box<WalletInfo> walletInfoSource, WalletType type, SeedSettingsViewModel seedSettingsViewModel)
: height = 0,
viewKey = '',
spendKey = '',
wif = '',
address = '',
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
@observable
int height;

View file

@ -0,0 +1,34 @@
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/seed_settings_store.dart';
import 'package:mobx/mobx.dart';
part 'seed_settings_view_model.g.dart';
class SeedSettingsViewModel = SeedSettingsViewModelBase with _$SeedSettingsViewModel;
abstract class SeedSettingsViewModelBase with Store {
SeedSettingsViewModelBase(this._appStore, this._seedSettingsStore);
@computed
MoneroSeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
@action
void setMoneroSeedType(MoneroSeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
@computed
BitcoinSeedType get bitcoinSeedType => _appStore.settingsStore.bitcoinSeedType;
@action
void setBitcoinSeedType(BitcoinSeedType derivationType) =>
_appStore.settingsStore.bitcoinSeedType = derivationType;
@computed
String? get passphrase => this._seedSettingsStore.passphrase;
@action
void setPassphrase(String? passphrase) => this._seedSettingsStore.passphrase = passphrase;
final AppStore _appStore;
final SeedSettingsStore _seedSettingsStore;
}

View file

@ -1,19 +0,0 @@
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:mobx/mobx.dart';
part 'seed_type_view_model.g.dart';
class SeedTypeViewModel = SeedTypeViewModelBase with _$SeedTypeViewModel;
abstract class SeedTypeViewModelBase with Store {
SeedTypeViewModelBase(this._appStore);
@computed
SeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
@action
void setMoneroSeedType(SeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
final AppStore _appStore;
}

View file

@ -1,20 +1,21 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/background_tasks.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/pathForWallet.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/entities/generate_name.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:polyseed/polyseed.dart';
part 'wallet_creation_vm.g.dart';
@ -23,6 +24,7 @@ class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
abstract class WalletCreationVMBase with Store {
WalletCreationVMBase(this._appStore, this._walletInfoSource, this.walletCreationService,
this.seedSettingsViewModel,
{required this.type, required this.isRecovery})
: state = InitialExecutionState(),
name = '';
@ -44,7 +46,6 @@ abstract class WalletCreationVMBase with Store {
@observable
String? repeatedWalletPassword;
bool get hasWalletPassword => SettingsStoreBase.walletPasswordDirectInput;
WalletType type;
@ -52,6 +53,7 @@ abstract class WalletCreationVMBase with Store {
final WalletCreationService walletCreationService;
final Box<WalletInfo> _walletInfoSource;
final AppStore _appStore;
final SeedSettingsViewModel seedSettingsViewModel;
bool isPolyseed(String seed) =>
(type == WalletType.monero || type == WalletType.wownero) &&
@ -109,17 +111,35 @@ abstract class WalletCreationVMBase with Store {
getIt.get<BackgroundTasks>().registerSyncTask();
_appStore.authenticationStore.allowed();
state = ExecutedSuccessfullyState();
} catch (e, s) {
} catch (e, _) {
state = FailureState(e.toString());
}
}
DerivationInfo? getDefaultDerivation() {
switch (this.type) {
final useBip39 = seedSettingsViewModel.bitcoinSeedType.type == DerivationType.bip39;
switch (type) {
case WalletType.nano:
return DerivationInfo(derivationType: DerivationType.nano);
case WalletType.bitcoin:
if (useBip39) {
return DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'",
description: "Standard BIP84 native segwit",
scriptType: "p2wpkh",
);
}
return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
case WalletType.litecoin:
if (useBip39) {
return DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/84'/2'/0'",
description: "Default Litecoin",
scriptType: "p2wpkh",
);
}
return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
default:
return null;

View file

@ -5,6 +5,7 @@ import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:cw_core/wallet_base.dart';
@ -25,10 +26,15 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
int _nextIndex = 0;
WalletHardwareRestoreViewModelBase(this.ledgerViewModel, AppStore appStore,
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
WalletHardwareRestoreViewModelBase(
this.ledgerViewModel,
AppStore appStore,
WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
SeedSettingsViewModel seedSettingsViewModel,
{required WalletType type})
: super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
: super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
type: type, isRecovery: true);
@observable
String name = "";

View file

@ -276,7 +276,8 @@ abstract class WalletKeysViewModelBase with Store {
if (_appStore.wallet!.seed == null &&
_appStore.wallet!.privateKey != null)
'private_key': _appStore.wallet!.privateKey!,
if (restoreHeightResult != null) ...{'height': restoreHeightResult}
if (restoreHeightResult != null) ...{'height': restoreHeightResult},
if (_appStore.wallet!.passphrase != null) 'passphrase': _appStore.wallet!.passphrase!
};
}

View file

@ -1,35 +1,42 @@
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'advanced_privacy_settings_view_model.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import '../polygon/polygon.dart';
import 'advanced_privacy_settings_view_model.dart';
part 'wallet_new_vm.g.dart';
class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
abstract class WalletNewVMBase extends WalletCreationVM with Store {
WalletNewVMBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource, this.advancedPrivacySettingsViewModel,
WalletNewVMBase(
AppStore appStore,
WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
this.advancedPrivacySettingsViewModel,
SeedSettingsViewModel seedSettingsViewModel,
{required WalletType type})
: selectedMnemonicLanguage = '',
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: false);
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
type: type, isRecovery: false);
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
@ -37,47 +44,58 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
String selectedMnemonicLanguage;
bool get hasLanguageSelector =>
type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero;
[WalletType.monero, WalletType.haven, WalletType.wownero].contains(type);
int get seedPhraseWordsLength {
switch (type) {
case WalletType.monero:
case WalletType.wownero:
if (advancedPrivacySettingsViewModel.isPolySeed) {
return 16;
}
return 25;
return advancedPrivacySettingsViewModel.isPolySeed ? 16 : 25;
case WalletType.tron:
case WalletType.solana:
case WalletType.polygon:
case WalletType.ethereum:
case WalletType.bitcoinCash:
return advancedPrivacySettingsViewModel.seedPhraseLength.value;
case WalletType.bitcoin:
case WalletType.litecoin:
return seedSettingsViewModel.bitcoinSeedType == BitcoinSeedType.bip39
? advancedPrivacySettingsViewModel.seedPhraseLength.value
: 24;
default:
return 24;
}
}
bool get hasSeedType => type == WalletType.monero || type == WalletType.wownero;
bool get hasSeedType => [WalletType.monero, WalletType.wownero].contains(type);
@override
WalletCredentials getCredentials(dynamic _options) {
final options = _options as List<dynamic>?;
final passphrase = seedSettingsViewModel.passphrase;
seedSettingsViewModel.setPassphrase(null);
switch (type) {
case WalletType.monero:
return monero!.createMoneroNewWalletCredentials(
name: name, language: options!.first as String, password: walletPassword, isPolyseed: options.last as bool);
name: name,
language: options!.first as String,
password: walletPassword,
isPolyseed: options.last as bool);
case WalletType.bitcoin:
return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
return bitcoin!.createBitcoinNewWalletCredentials(
name: name, password: walletPassword, passphrase: passphrase);
case WalletType.litecoin:
return bitcoin!.createBitcoinNewWalletCredentials(name: name, password: walletPassword);
return bitcoin!.createBitcoinNewWalletCredentials(
name: name, password: walletPassword, passphrase: passphrase);
case WalletType.haven:
return haven!.createHavenNewWalletCredentials(
name: name, language: options!.first as String, password: walletPassword);
case WalletType.ethereum:
return ethereum!.createEthereumNewWalletCredentials(name: name, password: walletPassword);
case WalletType.bitcoinCash:
return bitcoinCash!.createBitcoinCashNewWalletCredentials(name: name, password: walletPassword);
return bitcoinCash!.createBitcoinCashNewWalletCredentials(
name: name, password: walletPassword, passphrase: passphrase);
case WalletType.nano:
case WalletType.banano:
return nano!.createNanoNewWalletCredentials(name: name);

View file

@ -1,25 +1,26 @@
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/store/app_store.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';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/wownero/wownero.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
part 'wallet_restore_view_model.g.dart';
@ -27,7 +28,7 @@ class WalletRestoreViewModel = WalletRestoreViewModelBase with _$WalletRestoreVi
abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
Box<WalletInfo> walletInfoSource, SeedSettingsViewModel seedSettingsViewModel,
{required WalletType type})
: hasSeedLanguageSelector =
type == WalletType.monero || type == WalletType.haven || type == WalletType.wownero,
@ -41,7 +42,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
type == WalletType.tron,
isButtonEnabled = false,
mode = WalletRestoreMode.seed,
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true) {
switch (type) {
case WalletType.monero:
availableModes = WalletRestoreMode.values;
@ -76,7 +77,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
final bool hasBlockchainHeightLanguageSelector;
final bool hasRestoreFromPrivateKey;
bool get hasPassphrase => [WalletType.bitcoin, WalletType.litecoin].contains(type);
bool get hasPassphrase =>
[WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash].contains(type);
@observable
WalletRestoreMode mode;

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "هل أنت متأكد أنك تريد حذف محفظة ${wallet_name}؟",
"deleteConnectionConfirmationPrompt": "ـﺑ ﻝﺎﺼﺗﻻﺍ ﻑﺬﺣ ﺪﻳﺮﺗ ﻚﻧﺃ ﺪﻛﺄﺘﻣ ﺖﻧﺃ ﻞﻫ",
"denominations": "الطوائف",
"derivationpath": "مسار الاشتقاق",
"descending": "النزول",
"description": "ﻒﺻﻭ",
"destination_tag": "علامة الوجهة:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Сигурни ли сте, че искате да изтриете протфейла ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Сигурни ли сте, че искате да изтриете връзката към",
"denominations": "Деноминации",
"derivationpath": "Пътят на производно",
"descending": "Низходящ",
"description": "Описание",
"destination_tag": "Destination tag:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Opravdu chcete smazat ${wallet_name} peněženku?",
"deleteConnectionConfirmationPrompt": "Jste si jisti, že chcete smazat připojení k?",
"denominations": "Označení",
"derivationpath": "Derivační cesta",
"descending": "Klesající",
"description": "Popis",
"destination_tag": "Destination Tag:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?",
"deleteConnectionConfirmationPrompt": "Sind Sie sicher, dass Sie die Verbindung zu löschen möchten?",
"denominations": "Konfessionen",
"derivationpath": "Ableitungspfad",
"descending": "Absteigend",
"description": "Beschreibung",
"destination_tag": "Ziel-Tag:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Are you sure that you want to delete ${wallet_name} wallet?",
"deleteConnectionConfirmationPrompt": "Are you sure that you want to delete the connection to",
"denominations": "Denominations",
"derivationpath": "Derivation Path",
"descending": "Descending",
"description": "Description",
"destination_tag": "Destination tag:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "¿Está seguro de que desea eliminar la billetera ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "¿Está seguro de que desea eliminar la conexión a",
"denominations": "Denominaciones",
"derivationpath": "Ruta de derivación",
"descending": "Descendente",
"description": "Descripción",
"destination_tag": "Etiqueta de destino:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Êtes-vous sûr de vouloir supprimer le portefeuille (wallet) ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Êtes-vous sûr de vouloir supprimer la connexion à",
"denominations": "Dénominations",
"derivationpath": "Chemin de dérivation",
"descending": "Descendant",
"description": "Description",
"destination_tag": "Tag de destination :",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Shin kun tabbata cewa kuna son share jakar ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Shin kun tabbata cewa kuna son share haɗin zuwa",
"denominations": "Denominations",
"derivationpath": "Hanyar Nasara",
"descending": "Saukowa",
"description": "Bayani",
"destination_tag": "Tambarin makoma:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "क्या आप वाकई ${wallet_name} वॉलेट हटाना चाहते हैं?",
"deleteConnectionConfirmationPrompt": "क्या आप वाकई कनेक्शन हटाना चाहते हैं?",
"denominations": "मूल्यवर्ग",
"derivationpath": "व्युत्पत्ति पथ",
"descending": "अवरोही",
"description": "विवरण",
"destination_tag": "गंतव्य टैग:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Jeste li sigurni da želite izbrisati ${wallet_name} novčanik?",
"deleteConnectionConfirmationPrompt": "Jeste li sigurni da želite izbrisati vezu s",
"denominations": "Denominacije",
"derivationpath": "Put derivacije",
"descending": "Silazni",
"description": "Opis",
"destination_tag": "Odredišna oznaka:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Apakah Anda yakin ingin menghapus dompet ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Apakah Anda yakin ingin menghapus koneksi ke",
"denominations": "Denominasi",
"derivationpath": "Jalur derivasi",
"descending": "Menurun",
"description": "Keterangan",
"destination_tag": "Tag tujuan:",

View file

@ -196,6 +196,7 @@
"delete_wallet_confirm_message": "Sei sicuro di voler eliminare il portafoglio ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Sei sicuro di voler eliminare la connessione a",
"denominations": "Denominazioni",
"derivationpath": "Percorso di derivazione",
"descending": "Discendente",
"description": "Descrizione",
"destination_tag": "Tag destinazione:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "${wallet_name} ウォレットを削除してもよろしいですか?",
"deleteConnectionConfirmationPrompt": "への接続を削除してもよろしいですか?",
"denominations": "宗派",
"derivationpath": "派生パス",
"descending": "下降",
"description": "説明",
"destination_tag": "宛先タグ:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "${wallet_name} 지갑을 삭제하시겠습니까?",
"deleteConnectionConfirmationPrompt": "다음 연결을 삭제하시겠습니까?",
"denominations": "교파",
"derivationpath": "파생 경로",
"descending": "내림차순",
"description": "설명",
"destination_tag": "목적지 태그:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
"deleteConnectionConfirmationPrompt": "ချိတ်ဆက်မှုကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
"denominations": "ဂိုဏ်းချုပ်ပစ္စည်းများ",
"derivationpath": "derivation လမ်းကြောင်း",
"descending": "ဆင်း",
"description": "ဖော်ပြချက်",
"destination_tag": "ခရီးဆုံးအမှတ်-",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Weet u zeker dat u de portemonnee van ${wallet_name} wilt verwijderen?",
"deleteConnectionConfirmationPrompt": "Weet u zeker dat u de verbinding met",
"denominations": "Denominaties",
"derivationpath": "Afleidingspad",
"descending": "Aflopend",
"description": "Beschrijving",
"destination_tag": "Bestemmingstag:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Czy na pewno chcesz usunąć portfel ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Czy na pewno chcesz usunąć połączenie z",
"denominations": "Wyznaczenia",
"derivationpath": "Ścieżka pochodna",
"descending": "Schodzenie",
"description": "Opis",
"destination_tag": "Tag docelowy:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Tem certeza de que deseja excluir a carteira ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Tem certeza de que deseja excluir a conexão com",
"denominations": "Denominações",
"derivationpath": "Caminho de derivação",
"descending": "descendente",
"description": "Descrição",
"destination_tag": "Tag de destino:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Вы уверены, что хотите удалить кошелек ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Вы уверены, что хотите удалить подключение к",
"denominations": "Деноминации",
"derivationpath": "Путь получения",
"descending": "Нисходящий",
"description": "Описание",
"destination_tag": "Целевой тег:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "คุณแน่ใจหรือว่าต้องการลบกระเป๋า${wallet_name}?",
"deleteConnectionConfirmationPrompt": "คุณแน่ใจหรือไม่ว่าต้องการลบการเชื่อมต่อไปยัง",
"denominations": "นิกาย",
"derivationpath": "เส้นทางที่ได้มา",
"descending": "ลงมา",
"description": "คำอธิบาย",
"destination_tag": "แท็กปลายทาง:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Sigurado ka ba na gusto mong tanggalin ang iyong ${wallet_name} wallet?",
"deleteConnectionConfirmationPrompt": "Sigurado ka bang gusto mong tanggalin ang koneksyon sa",
"denominations": "Mga Denominasyon",
"derivationpath": "Landas ng derivation",
"descending": "Pababang",
"description": "Paglalarawan",
"destination_tag": "Tag ng patutunguhan:",
@ -661,14 +662,14 @@
"show_details": "Ipakita ang mga detalye",
"show_keys": "Ipakita ang mga seed/key",
"show_market_place": "Ipakita ang Marketplace",
"show_seed": "Ipakita ang seed",
"sign_message": "Mag -sign Message",
"sign_up": "Mag-sign Up",
"sign_verify_message": "Mag -sign o i -verify ang mensahe",
"sign_verify_message_sub": "Mag -sign o i -verify ang isang mensahe gamit ang iyong pribadong key",
"sign_verify_title": "Mag -sign / Mag -verify",
"signature": "Lagda",
"signature_invalid_error": "Ang lagda ay hindi wasto para sa ibinigay na mensahe",
"show_seed": "Ipakita ang seed",
"sign_up": "Mag-sign Up",
"signTransaction": "Mag-sign ang Transaksyon",
"signup_for_card_accept_terms": "Mag-sign up para sa card at tanggapin ang mga tuntunin.",
"silent_payments": "Tahimik na pagbabayad",
@ -827,9 +828,9 @@
"use_testnet": "Gumamit ng testnet",
"value": "Halaga",
"value_type": "Uri ng halaga",
"verify_message": "I -verify ang mensahe",
"variable_pair_not_supported": "Ang variable na pares na ito ay hindi suportado sa mga napiling exchange",
"verification": "Pag-verify",
"verify_message": "I -verify ang mensahe",
"verify_with_2fa": "Mag-verify sa Cake 2FA",
"version": "Bersyon ${currentVersion}",
"view_all": "Tingnan lahat",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "${wallet_name} isimli cüzdanını silmek istediğinden emin misin?",
"deleteConnectionConfirmationPrompt": "Bağlantıyı silmek istediğinizden emin misiniz?",
"denominations": "Mezhepler",
"derivationpath": "Türev yolu",
"descending": "Azalan",
"description": "Tanım",
"destination_tag": "Hedef Etiketi:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Ви впевнені, що хочете видалити гаманець ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Ви впевнені, що хочете видалити з’єднання з",
"denominations": "Конфесія",
"derivationpath": "Шлях виведення",
"descending": "Низхідний",
"description": "опис",
"destination_tag": "Тег призначення:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "کیا آپ واقعی ${wallet_name} والیٹ کو حذف کرنا چاہتے ہیں؟",
"deleteConnectionConfirmationPrompt": "۔ﮟﯿﮨ ﮯﺘﮨﺎﭼ ﺎﻧﺮﮐ ﻑﺬﺣ ﻮﮐ ﻦﺸﮑﻨﮐ ﭖﺁ ﮧﮐ ﮯﮨ ﻦﯿﻘﯾ ﻮﮐ ﭖﺁ ﺎﯿﮐ",
"denominations": "فرق",
"derivationpath": "مشتق راستہ",
"descending": "اترتے ہوئے",
"description": "ﻞﯿﺼﻔﺗ",
"destination_tag": "منزل کا ٹیگ:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "Ṣó dá ẹ lójú pé ẹ fẹ́ pa àpamọ́wọ́ ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Ṣe o da ọ loju pe o fẹ paarẹ asopọ si",
"denominations": "Awọn ede",
"derivationpath": "Ọna Deriji",
"descending": "Sọkalẹ",
"description": "Apejuwe",
"destination_tag": "Orúkọ tí ìbí tó a ránṣẹ́ sí:",

View file

@ -195,6 +195,7 @@
"delete_wallet_confirm_message": "您确定要删除 ${wallet_name} 钱包吗?",
"deleteConnectionConfirmationPrompt": "您确定要删除与",
"denominations": "教派",
"derivationpath": "推导路径",
"descending": "下降",
"description": "描述",
"destination_tag": "目标Tag:",

View file

@ -151,7 +151,7 @@ abstract class Bitcoin {
String? passphrase,
});
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase});
WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
List<String> getWordList();
Map<String, String> getWalletKeys(Object wallet);
@ -1021,10 +1021,10 @@ abstract class BitcoinCash {
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
WalletCredentials createBitcoinCashNewWalletCredentials(
{required String name, WalletInfo? walletInfo, String? password});
{required String name, WalletInfo? walletInfo, String? password, String? passphrase});
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
{required String name, required String mnemonic, required String password});
{required String name, required String mnemonic, required String password, String? passphrase});
TransactionPriority deserializeBitcoinCashTransactionPriority(int raw);