mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-18 16:55:58 +00:00
Change encryption method for electrum wallets is wallet password provides directly. Add ability to user for repeat wallets password and compare with original wallet password before wallet creation for cases when wallet password provides directly.
This commit is contained in:
parent
3b82a390c1
commit
f52c45b167
38 changed files with 287 additions and 39 deletions
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
|
@ -23,6 +24,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
required Uint8List seedBytes,
|
required Uint8List seedBytes,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
|
@ -36,7 +38,8 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance,
|
||||||
seedBytes: seedBytes,
|
seedBytes: seedBytes,
|
||||||
currency: CryptoCurrency.btc) {
|
currency: CryptoCurrency.btc,
|
||||||
|
encryptionFileUtils: encryptionFileUtils) {
|
||||||
walletAddresses = BitcoinWalletAddresses(
|
walletAddresses = BitcoinWalletAddresses(
|
||||||
walletInfo,
|
walletInfo,
|
||||||
electrumClient: electrumClient,
|
electrumClient: electrumClient,
|
||||||
|
@ -54,6 +57,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
required String password,
|
required String password,
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
|
@ -66,6 +70,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
unspentCoinsInfo: unspentCoinsInfo,
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance,
|
||||||
|
encryptionFileUtils: encryptionFileUtils,
|
||||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||||
|
@ -76,8 +81,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
required String password,
|
required String password,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils
|
||||||
}) async {
|
}) async {
|
||||||
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
final snp = await ElectrumWallletSnapshot.load(encryptionFileUtils, name, walletInfo.type, password);
|
||||||
return BitcoinWallet(
|
return BitcoinWallet(
|
||||||
mnemonic: snp.mnemonic,
|
mnemonic: snp.mnemonic,
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -86,6 +92,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialAddresses: snp.addresses,
|
initialAddresses: snp.addresses,
|
||||||
initialBalance: snp.balance,
|
initialBalance: snp.balance,
|
||||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||||
|
encryptionFileUtils: encryptionFileUtils,
|
||||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart';
|
import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
|
import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:cw_core/wallet_base.dart';
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_service.dart';
|
import 'package:cw_core/wallet_service.dart';
|
||||||
|
@ -16,10 +17,11 @@ class BitcoinWalletService extends WalletService<
|
||||||
BitcoinNewWalletCredentials,
|
BitcoinNewWalletCredentials,
|
||||||
BitcoinRestoreWalletFromSeedCredentials,
|
BitcoinRestoreWalletFromSeedCredentials,
|
||||||
BitcoinRestoreWalletFromWIFCredentials> {
|
BitcoinRestoreWalletFromWIFCredentials> {
|
||||||
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
BitcoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
|
||||||
|
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||||
|
final bool isDirect;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletType getType() => WalletType.bitcoin;
|
WalletType getType() => WalletType.bitcoin;
|
||||||
|
@ -30,7 +32,8 @@ class BitcoinWalletService extends WalletService<
|
||||||
mnemonic: await generateMnemonic(),
|
mnemonic: await generateMnemonic(),
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
walletInfo: credentials.walletInfo!,
|
walletInfo: credentials.walletInfo!,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
|
@ -46,7 +49,8 @@ class BitcoinWalletService extends WalletService<
|
||||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||||
final wallet = await BitcoinWalletBase.open(
|
final wallet = await BitcoinWalletBase.open(
|
||||||
password: password, name: name, walletInfo: walletInfo,
|
password: password, name: name, walletInfo: walletInfo,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
@ -72,7 +76,8 @@ class BitcoinWalletService extends WalletService<
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
mnemonic: credentials.mnemonic,
|
mnemonic: credentials.mnemonic,
|
||||||
walletInfo: credentials.walletInfo!,
|
walletInfo: credentials.walletInfo!,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cw_core/transaction_history.dart';
|
import 'package:cw_core/transaction_history.dart';
|
||||||
import 'package:cw_bitcoin/file.dart';
|
|
||||||
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
import 'package:cw_bitcoin/electrum_transaction_info.dart';
|
||||||
|
|
||||||
part 'electrum_transaction_history.g.dart';
|
part 'electrum_transaction_history.g.dart';
|
||||||
|
@ -17,13 +16,14 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
|
||||||
abstract class ElectrumTransactionHistoryBase
|
abstract class ElectrumTransactionHistoryBase
|
||||||
extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
|
extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
|
||||||
ElectrumTransactionHistoryBase(
|
ElectrumTransactionHistoryBase(
|
||||||
{required this.walletInfo, required String password})
|
{required this.walletInfo, required String password, required this.encryptionFileUtils})
|
||||||
: _password = password,
|
: _password = password,
|
||||||
_height = 0 {
|
_height = 0 {
|
||||||
transactions = ObservableMap<String, ElectrumTransactionInfo>();
|
transactions = ObservableMap<String, ElectrumTransactionInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
final WalletInfo walletInfo;
|
final WalletInfo walletInfo;
|
||||||
|
final EncryptionFileUtils encryptionFileUtils;
|
||||||
String _password;
|
String _password;
|
||||||
int _height;
|
int _height;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
final path = '$dirPath/$_transactionsHistoryFileName';
|
||||||
final data =
|
final data =
|
||||||
json.encode({'height': _height, 'transactions': transactions});
|
json.encode({'height': _height, 'transactions': transactions});
|
||||||
await writeData(path: path, password: _password, data: data);
|
await encryptionFileUtils.write(path: path, password: _password, data: data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error while save bitcoin transaction history: ${e.toString()}');
|
print('Error while save bitcoin transaction history: ${e.toString()}');
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ abstract class ElectrumTransactionHistoryBase
|
||||||
final dirPath =
|
final dirPath =
|
||||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
final path = '$dirPath/$_transactionsHistoryFileName';
|
||||||
final content = await read(path: path, password: _password);
|
final content = await encryptionFileUtils.read(path: path, password: _password);
|
||||||
return json.decode(content) as Map<String, dynamic>;
|
return json.decode(content) as Map<String, dynamic>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
|
@ -22,7 +23,6 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_transaction_wrong_balance_exception.dart';
|
import 'package:cw_bitcoin/bitcoin_transaction_wrong_balance_exception.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
|
import 'package:cw_bitcoin/bitcoin_wallet_keys.dart';
|
||||||
import 'package:cw_bitcoin/file.dart';
|
|
||||||
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
||||||
import 'package:cw_bitcoin/script_hash.dart';
|
import 'package:cw_bitcoin/script_hash.dart';
|
||||||
import 'package:cw_bitcoin/utils.dart';
|
import 'package:cw_bitcoin/utils.dart';
|
||||||
|
@ -49,6 +49,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
required this.networkType,
|
required this.networkType,
|
||||||
required this.mnemonic,
|
required this.mnemonic,
|
||||||
required Uint8List seedBytes,
|
required Uint8List seedBytes,
|
||||||
|
required this.encryptionFileUtils,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
ElectrumClient? electrumClient,
|
ElectrumClient? electrumClient,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
|
@ -70,7 +71,10 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
this.electrumClient = electrumClient ?? ElectrumClient();
|
this.electrumClient = electrumClient ?? ElectrumClient();
|
||||||
this.walletInfo = walletInfo;
|
this.walletInfo = walletInfo;
|
||||||
transactionHistory =
|
transactionHistory =
|
||||||
ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
|
ElectrumTransactionHistory(
|
||||||
|
walletInfo: walletInfo,
|
||||||
|
password: password,
|
||||||
|
encryptionFileUtils: encryptionFileUtils);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||||
|
@ -78,6 +82,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
|
|
||||||
final bitcoin.HDWallet hd;
|
final bitcoin.HDWallet hd;
|
||||||
final String mnemonic;
|
final String mnemonic;
|
||||||
|
final EncryptionFileUtils encryptionFileUtils;
|
||||||
|
|
||||||
late ElectrumClient electrumClient;
|
late ElectrumClient electrumClient;
|
||||||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||||
|
@ -428,7 +433,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||||
@override
|
@override
|
||||||
Future<void> save() async {
|
Future<void> save() async {
|
||||||
final path = await makePath();
|
final path = await makePath();
|
||||||
await write(path: path, password: _password, data: toJSON());
|
await encryptionFileUtils.write(path: path, password: _password, data: toJSON());
|
||||||
await transactionHistory.save();
|
await transactionHistory.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||||
import 'package:cw_bitcoin/file.dart';
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/pathForWallet.dart';
|
import 'package:cw_core/pathForWallet.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
|
||||||
|
@ -26,9 +26,9 @@ class ElectrumWallletSnapshot {
|
||||||
int regularAddressIndex;
|
int regularAddressIndex;
|
||||||
int changeAddressIndex;
|
int changeAddressIndex;
|
||||||
|
|
||||||
static Future<ElectrumWallletSnapshot> load(String name, WalletType type, String password) async {
|
static Future<ElectrumWallletSnapshot> load(EncryptionFileUtils encryptionFileUtils, String name, WalletType type, String password) async {
|
||||||
final path = await pathForWallet(name: name, type: type);
|
final path = await pathForWallet(name: name, type: type);
|
||||||
final jsonSource = await read(path: path, password: password);
|
final jsonSource = await encryptionFileUtils.read(path: path, password: password);
|
||||||
final data = json.decode(jsonSource) as Map;
|
final data = json.decode(jsonSource) as Map;
|
||||||
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
||||||
final mnemonic = data['mnemonic'] as String;
|
final mnemonic = data['mnemonic'] as String;
|
||||||
|
|
42
cw_bitcoin/lib/encryption_file_utils.dart
Normal file
42
cw_bitcoin/lib/encryption_file_utils.dart
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import 'dart:io';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:cw_bitcoin/file.dart' as bf;
|
||||||
|
import 'package:cake_backup/backup.dart' as cwb;
|
||||||
|
|
||||||
|
EncryptionFileUtils encryptionFileUtilsFor(bool direct)
|
||||||
|
=> direct
|
||||||
|
? XChaCha20EncryptionFileUtils()
|
||||||
|
: Salsa20EncryhptionFileUtils();
|
||||||
|
|
||||||
|
abstract class EncryptionFileUtils {
|
||||||
|
Future<void> write({required String path, required String password, required String data});
|
||||||
|
Future<String> read({required String path, required String password});
|
||||||
|
}
|
||||||
|
|
||||||
|
class Salsa20EncryhptionFileUtils extends EncryptionFileUtils {
|
||||||
|
// Requires legacy complex key + iv as password
|
||||||
|
@override
|
||||||
|
Future<void> write({required String path, required String password, required String data}) async
|
||||||
|
=> await bf.write(path: path, password: password, data: data);
|
||||||
|
|
||||||
|
// Requires legacy complex key + iv as password
|
||||||
|
@override
|
||||||
|
Future<String> read({required String path, required String password}) async
|
||||||
|
=> await bf.read(path: path, password: password);
|
||||||
|
}
|
||||||
|
|
||||||
|
class XChaCha20EncryptionFileUtils extends EncryptionFileUtils {
|
||||||
|
@override
|
||||||
|
Future<void> write({required String path, required String password, required String data}) async {
|
||||||
|
final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits));
|
||||||
|
await File(path).writeAsBytes(encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<String> read({required String path, required String password}) async {
|
||||||
|
final file = File(path);
|
||||||
|
final encrypted = await file.readAsBytes();
|
||||||
|
final bytes = await cwb.decrypt(password, encrypted);
|
||||||
|
return String.fromCharCodes(bytes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
||||||
import 'package:cw_core/key.dart';
|
import 'package:cw_core/key.dart';
|
||||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||||
|
|
||||||
|
// Do not use directly, move to Salsa20EncryhptionFile
|
||||||
Future<void> write(
|
Future<void> write(
|
||||||
{required String path,
|
{required String path,
|
||||||
required String password,
|
required String password,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
||||||
|
@ -26,6 +27,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
required Uint8List seedBytes,
|
required Uint8List seedBytes,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
|
@ -39,6 +41,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance,
|
||||||
seedBytes: seedBytes,
|
seedBytes: seedBytes,
|
||||||
|
encryptionFileUtils: encryptionFileUtils,
|
||||||
currency: CryptoCurrency.ltc) {
|
currency: CryptoCurrency.ltc) {
|
||||||
walletAddresses = LitecoinWalletAddresses(
|
walletAddresses = LitecoinWalletAddresses(
|
||||||
walletInfo,
|
walletInfo,
|
||||||
|
@ -58,6 +61,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
required String password,
|
required String password,
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
|
@ -71,6 +75,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance,
|
||||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||||
|
encryptionFileUtils: encryptionFileUtils,
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||||
}
|
}
|
||||||
|
@ -80,8 +85,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
required String password,
|
required String password,
|
||||||
|
required EncryptionFileUtils encryptionFileUtils
|
||||||
}) async {
|
}) async {
|
||||||
final snp = await ElectrumWallletSnapshot.load (name, walletInfo.type, password);
|
final snp = await ElectrumWallletSnapshot.load(encryptionFileUtils, name, walletInfo.type, password);
|
||||||
return LitecoinWallet(
|
return LitecoinWallet(
|
||||||
mnemonic: snp.mnemonic,
|
mnemonic: snp.mnemonic,
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -90,6 +96,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||||
initialAddresses: snp.addresses,
|
initialAddresses: snp.addresses,
|
||||||
initialBalance: snp.balance,
|
initialBalance: snp.balance,
|
||||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||||
|
encryptionFileUtils: encryptionFileUtils,
|
||||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:cw_bitcoin/encryption_file_utils.dart';
|
||||||
import 'package:cw_core/unspent_coins_info.dart';
|
import 'package:cw_core/unspent_coins_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||||
|
@ -16,10 +17,11 @@ class LitecoinWalletService extends WalletService<
|
||||||
BitcoinNewWalletCredentials,
|
BitcoinNewWalletCredentials,
|
||||||
BitcoinRestoreWalletFromSeedCredentials,
|
BitcoinRestoreWalletFromSeedCredentials,
|
||||||
BitcoinRestoreWalletFromWIFCredentials> {
|
BitcoinRestoreWalletFromWIFCredentials> {
|
||||||
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource);
|
LitecoinWalletService(this.walletInfoSource, this.unspentCoinsInfoSource, this.isDirect);
|
||||||
|
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
|
||||||
|
final bool isDirect;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletType getType() => WalletType.litecoin;
|
WalletType getType() => WalletType.litecoin;
|
||||||
|
@ -30,7 +32,8 @@ class LitecoinWalletService extends WalletService<
|
||||||
mnemonic: await generateMnemonic(),
|
mnemonic: await generateMnemonic(),
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
walletInfo: credentials.walletInfo!,
|
walletInfo: credentials.walletInfo!,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
|
|
||||||
|
@ -47,7 +50,8 @@ class LitecoinWalletService extends WalletService<
|
||||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||||
final wallet = await LitecoinWalletBase.open(
|
final wallet = await LitecoinWalletBase.open(
|
||||||
password: password, name: name, walletInfo: walletInfo,
|
password: password, name: name, walletInfo: walletInfo,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
}
|
}
|
||||||
|
@ -73,7 +77,8 @@ class LitecoinWalletService extends WalletService<
|
||||||
password: credentials.password!,
|
password: credentials.password!,
|
||||||
mnemonic: credentials.mnemonic,
|
mnemonic: credentials.mnemonic,
|
||||||
walletInfo: credentials.walletInfo!,
|
walletInfo: credentials.walletInfo!,
|
||||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
unspentCoinsInfo: unspentCoinsInfoSource,
|
||||||
|
encryptionFileUtils: encryptionFileUtilsFor(isDirect));
|
||||||
await wallet.save();
|
await wallet.save();
|
||||||
await wallet.init();
|
await wallet.init();
|
||||||
return wallet;
|
return wallet;
|
||||||
|
|
|
@ -155,6 +155,15 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.4.4"
|
version: "8.4.4"
|
||||||
|
cake_backup:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
path: "."
|
||||||
|
ref: main
|
||||||
|
resolved-ref: "3aba867dcab6737f6707782f5db15d71f303db38"
|
||||||
|
url: "https://github.com/cake-tech/cake_backup.git"
|
||||||
|
source: git
|
||||||
|
version: "1.0.0+1"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -219,6 +228,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.5.0"
|
||||||
|
cupertino_icons:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cupertino_icons
|
||||||
|
sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.5"
|
||||||
cw_core:
|
cw_core:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -681,6 +698,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
tuple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: tuple
|
||||||
|
sha256: "0ea99cd2f9352b2586583ab2ce6489d1f95a5f6de6fb9492faaf97ae2060f0aa"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -27,6 +27,11 @@ dependencies:
|
||||||
unorm_dart: ^0.2.0
|
unorm_dart: ^0.2.0
|
||||||
cryptography: ^2.0.5
|
cryptography: ^2.0.5
|
||||||
encrypt: ^5.0.1
|
encrypt: ^5.0.1
|
||||||
|
cake_backup:
|
||||||
|
git:
|
||||||
|
url: https://github.com/cake-tech/cake_backup.git
|
||||||
|
ref: main
|
||||||
|
version: 1.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -138,12 +138,12 @@ class CWBitcoin extends Bitcoin {
|
||||||
await bitcoinWallet.updateUnspent();
|
await bitcoinWallet.updateUnspent();
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
|
||||||
return BitcoinWalletService(walletInfoSource, unspentCoinSource);
|
return BitcoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource) {
|
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
|
||||||
return LitecoinWalletService(walletInfoSource, unspentCoinSource);
|
return LitecoinWalletService(walletInfoSource, unspentCoinSource, isDirect);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -583,10 +583,12 @@ Future setup(
|
||||||
return monero!.createMoneroWalletService(_walletInfoSource);
|
return monero!.createMoneroWalletService(_walletInfoSource);
|
||||||
case WalletType.bitcoin:
|
case WalletType.bitcoin:
|
||||||
return bitcoin!.createBitcoinWalletService(
|
return bitcoin!.createBitcoinWalletService(
|
||||||
_walletInfoSource, _unspentCoinsInfoSource!);
|
_walletInfoSource, _unspentCoinsInfoSource!,
|
||||||
|
SettingsStoreBase.walletPasswordDirectInput);
|
||||||
case WalletType.litecoin:
|
case WalletType.litecoin:
|
||||||
return bitcoin!.createLitecoinWalletService(
|
return bitcoin!.createLitecoinWalletService(
|
||||||
_walletInfoSource, _unspentCoinsInfoSource!);
|
_walletInfoSource, _unspentCoinsInfoSource!,
|
||||||
|
SettingsStoreBase.walletPasswordDirectInput);
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
|
throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
: _formKey = GlobalKey<FormState>(),
|
: _formKey = GlobalKey<FormState>(),
|
||||||
_languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
|
_languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
|
||||||
_nameController = TextEditingController(),
|
_nameController = TextEditingController(),
|
||||||
_passwordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null;
|
_passwordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null,
|
||||||
|
_repeatedPasswordController = _walletNewVM.hasWalletPassword ? TextEditingController() : null;
|
||||||
|
|
||||||
static const aspectRatioImage = 1.22;
|
static const aspectRatioImage = 1.22;
|
||||||
|
|
||||||
|
@ -59,6 +60,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
final WalletNewVM _walletNewVM;
|
final WalletNewVM _walletNewVM;
|
||||||
final TextEditingController _nameController;
|
final TextEditingController _nameController;
|
||||||
final TextEditingController? _passwordController;
|
final TextEditingController? _passwordController;
|
||||||
|
final TextEditingController? _repeatedPasswordController;
|
||||||
ReactionDisposer? _stateReaction;
|
ReactionDisposer? _stateReaction;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -171,7 +173,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
validator: WalletNameValidator(),
|
validator: WalletNameValidator(),
|
||||||
),
|
),
|
||||||
if (_walletNewVM.hasWalletPassword)
|
if (_walletNewVM.hasWalletPassword)
|
||||||
TextFormField(
|
...[TextFormField(
|
||||||
onChanged: (value) => _walletNewVM.walletPassword = value,
|
onChanged: (value) => _walletNewVM.walletPassword = value,
|
||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
|
@ -203,6 +205,38 @@ class _WalletNameFormState extends State<WalletNameForm> {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
TextFormField(
|
||||||
|
onChanged: (value) => _walletNewVM.repeatedWalletPassword = value,
|
||||||
|
controller: _repeatedPasswordController,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
obscureText: true,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20.0,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: Theme.of(context).primaryTextTheme!.headline6!.color!),
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 18.0,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).accentTextTheme!.headline2!.color!),
|
||||||
|
hintText: S.of(context).repeate_wallet_password,
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.accentTextTheme!
|
||||||
|
.headline2!
|
||||||
|
.decorationColor!,
|
||||||
|
width: 1.0)),
|
||||||
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.accentTextTheme!
|
||||||
|
.headline2!
|
||||||
|
.decorationColor!,
|
||||||
|
width: 1.0),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -15,6 +15,7 @@ class WalletRestoreFromKeysFrom extends StatefulWidget {
|
||||||
WalletRestoreFromKeysFrom({
|
WalletRestoreFromKeysFrom({
|
||||||
required this.walletRestoreViewModel,
|
required this.walletRestoreViewModel,
|
||||||
required this.displayWalletPassword,
|
required this.displayWalletPassword,
|
||||||
|
required this.onRepeatedPasswordChange,
|
||||||
this.onPasswordChange,
|
this.onPasswordChange,
|
||||||
Key? key,
|
Key? key,
|
||||||
this.onHeightOrDateEntered,})
|
this.onHeightOrDateEntered,})
|
||||||
|
@ -24,6 +25,7 @@ class WalletRestoreFromKeysFrom extends StatefulWidget {
|
||||||
final WalletRestoreViewModel walletRestoreViewModel;
|
final WalletRestoreViewModel walletRestoreViewModel;
|
||||||
final bool displayWalletPassword;
|
final bool displayWalletPassword;
|
||||||
final void Function(String)? onPasswordChange;
|
final void Function(String)? onPasswordChange;
|
||||||
|
final void Function(String)? onRepeatedPasswordChange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletRestoreFromKeysFromState createState() =>
|
WalletRestoreFromKeysFromState createState() =>
|
||||||
|
@ -39,7 +41,8 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
viewKeyController = TextEditingController(),
|
viewKeyController = TextEditingController(),
|
||||||
spendKeyController = TextEditingController(),
|
spendKeyController = TextEditingController(),
|
||||||
nameTextEditingController = TextEditingController(),
|
nameTextEditingController = TextEditingController(),
|
||||||
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null;
|
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
|
||||||
|
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
|
||||||
|
|
||||||
final GlobalKey<FormState> formKey;
|
final GlobalKey<FormState> formKey;
|
||||||
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
|
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
|
||||||
|
@ -49,7 +52,9 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
final TextEditingController spendKeyController;
|
final TextEditingController spendKeyController;
|
||||||
final TextEditingController nameTextEditingController;
|
final TextEditingController nameTextEditingController;
|
||||||
final TextEditingController? passwordTextEditingController;
|
final TextEditingController? passwordTextEditingController;
|
||||||
|
final TextEditingController? repeatedPasswordTextEditingController;
|
||||||
void Function()? passwordListener;
|
void Function()? passwordListener;
|
||||||
|
void Function()? repeatedPasswordListener;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -57,6 +62,11 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
|
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
|
||||||
passwordTextEditingController?.addListener(passwordListener!);
|
passwordTextEditingController?.addListener(passwordListener!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repeatedPasswordTextEditingController != null) {
|
||||||
|
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
|
||||||
|
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
|
||||||
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +81,10 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
if (passwordListener != null) {
|
if (passwordListener != null) {
|
||||||
passwordTextEditingController?.removeListener(passwordListener!);
|
passwordTextEditingController?.removeListener(passwordListener!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repeatedPasswordListener != null) {
|
||||||
|
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,12 +135,18 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
if (widget.displayWalletPassword)
|
if (widget.displayWalletPassword)
|
||||||
Container(
|
...[Container(
|
||||||
padding: EdgeInsets.only(top: 20.0),
|
padding: EdgeInsets.only(top: 20.0),
|
||||||
child: BaseTextFormField(
|
child: BaseTextFormField(
|
||||||
controller: passwordTextEditingController,
|
controller: passwordTextEditingController,
|
||||||
hintText: S.of(context).password,
|
hintText: S.of(context).password,
|
||||||
obscureText: true)),
|
obscureText: true)),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(top: 20.0),
|
||||||
|
child: BaseTextFormField(
|
||||||
|
controller: repeatedPasswordTextEditingController,
|
||||||
|
hintText: S.of(context).repeate_wallet_password,
|
||||||
|
obscureText: true))],
|
||||||
Container(height: 20),
|
Container(height: 20),
|
||||||
BaseTextFormField(
|
BaseTextFormField(
|
||||||
controller: addressController,
|
controller: addressController,
|
||||||
|
|
|
@ -23,7 +23,8 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
|
||||||
this.onHeightOrDateEntered,
|
this.onHeightOrDateEntered,
|
||||||
this.onSeedChange,
|
this.onSeedChange,
|
||||||
this.onLanguageChange,
|
this.onLanguageChange,
|
||||||
this.onPasswordChange})
|
this.onPasswordChange,
|
||||||
|
this.onRepeatedPasswordChange})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
final WalletType type;
|
final WalletType type;
|
||||||
|
@ -35,6 +36,7 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
|
||||||
final void Function(String)? onSeedChange;
|
final void Function(String)? onSeedChange;
|
||||||
final void Function(String)? onLanguageChange;
|
final void Function(String)? onLanguageChange;
|
||||||
final void Function(String)? onPasswordChange;
|
final void Function(String)? onPasswordChange;
|
||||||
|
final void Function(String)? onRepeatedPasswordChange;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletRestoreFromSeedFormState createState() =>
|
WalletRestoreFromSeedFormState createState() =>
|
||||||
|
@ -48,16 +50,19 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||||
formKey = GlobalKey<FormState>(),
|
formKey = GlobalKey<FormState>(),
|
||||||
languageController = TextEditingController(),
|
languageController = TextEditingController(),
|
||||||
nameTextEditingController = TextEditingController(),
|
nameTextEditingController = TextEditingController(),
|
||||||
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null;
|
passwordTextEditingController = displayWalletPassword ? TextEditingController() : null,
|
||||||
|
repeatedPasswordTextEditingController = displayWalletPassword ? TextEditingController() : null;
|
||||||
|
|
||||||
final GlobalKey<SeedWidgetState> seedWidgetStateKey;
|
final GlobalKey<SeedWidgetState> seedWidgetStateKey;
|
||||||
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
|
final GlobalKey<BlockchainHeightState> blockchainHeightKey;
|
||||||
final TextEditingController languageController;
|
final TextEditingController languageController;
|
||||||
final TextEditingController nameTextEditingController;
|
final TextEditingController nameTextEditingController;
|
||||||
final TextEditingController? passwordTextEditingController;
|
final TextEditingController? passwordTextEditingController;
|
||||||
|
final TextEditingController? repeatedPasswordTextEditingController;
|
||||||
final GlobalKey<FormState> formKey;
|
final GlobalKey<FormState> formKey;
|
||||||
String language;
|
String language;
|
||||||
void Function()? passwordListener;
|
void Function()? passwordListener;
|
||||||
|
void Function()? repeatedPasswordListener;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -66,6 +71,11 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||||
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
|
passwordListener = () => widget.onPasswordChange?.call(passwordTextEditingController!.text);
|
||||||
passwordTextEditingController?.addListener(passwordListener!);
|
passwordTextEditingController?.addListener(passwordListener!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repeatedPasswordTextEditingController != null) {
|
||||||
|
repeatedPasswordListener = () => widget.onRepeatedPasswordChange?.call(repeatedPasswordTextEditingController!.text);
|
||||||
|
repeatedPasswordTextEditingController?.addListener(repeatedPasswordListener!);
|
||||||
|
}
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +84,10 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||||
if (passwordListener != null) {
|
if (passwordListener != null) {
|
||||||
passwordTextEditingController?.removeListener(passwordListener!);
|
passwordTextEditingController?.removeListener(passwordListener!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (repeatedPasswordListener != null) {
|
||||||
|
repeatedPasswordTextEditingController?.removeListener(repeatedPasswordListener!);
|
||||||
|
}
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,10 +144,14 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||||
type: widget.type,
|
type: widget.type,
|
||||||
onSeedChange: widget.onSeedChange),
|
onSeedChange: widget.onSeedChange),
|
||||||
if (widget.displayWalletPassword)
|
if (widget.displayWalletPassword)
|
||||||
BaseTextFormField(
|
...[BaseTextFormField(
|
||||||
controller: passwordTextEditingController,
|
controller: passwordTextEditingController,
|
||||||
hintText: S.of(context).password,
|
hintText: S.of(context).password,
|
||||||
obscureText: true),
|
obscureText: true),
|
||||||
|
BaseTextFormField(
|
||||||
|
controller: repeatedPasswordTextEditingController,
|
||||||
|
hintText: S.of(context).repeate_wallet_password,
|
||||||
|
obscureText: true)],
|
||||||
if (widget.displayLanguageSelector)
|
if (widget.displayLanguageSelector)
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
|
|
|
@ -68,7 +68,8 @@ class WalletRestorePage extends BasePage {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
|
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
|
||||||
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password));
|
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
|
||||||
|
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword));
|
||||||
break;
|
break;
|
||||||
case WalletRestoreMode.keys:
|
case WalletRestoreMode.keys:
|
||||||
_pages.add(WalletRestoreFromKeysFrom(
|
_pages.add(WalletRestoreFromKeysFrom(
|
||||||
|
@ -76,6 +77,7 @@ class WalletRestorePage extends BasePage {
|
||||||
walletRestoreViewModel: walletRestoreViewModel,
|
walletRestoreViewModel: walletRestoreViewModel,
|
||||||
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
|
displayWalletPassword: walletRestoreViewModel.hasWalletPassword,
|
||||||
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
|
onPasswordChange: (String password) => walletRestoreViewModel.walletPassword = password,
|
||||||
|
onRepeatedPasswordChange: (String repeatedPassword) => walletRestoreViewModel.repeatedWalletPassword = repeatedPassword,
|
||||||
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
|
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -124,6 +126,8 @@ class WalletRestorePage extends BasePage {
|
||||||
|
|
||||||
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
|
reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
|
||||||
walletRestoreViewModel.isButtonEnabled = false;
|
walletRestoreViewModel.isButtonEnabled = false;
|
||||||
|
walletRestoreViewModel.walletPassword = null;
|
||||||
|
walletRestoreViewModel.repeatedWalletPassword = null;
|
||||||
|
|
||||||
walletRestoreFromSeedFormKey
|
walletRestoreFromSeedFormKey
|
||||||
.currentState!.blockchainHeightKey.currentState!.restoreHeightController.text = '';
|
.currentState!.blockchainHeightKey.currentState!.restoreHeightController.text = '';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:cake_wallet/core/wallet_creation_service.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/store/settings_store.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
import 'package:cake_wallet/core/execution_state.dart';
|
||||||
|
@ -31,6 +31,9 @@ abstract class WalletCreationVMBase with Store {
|
||||||
@observable
|
@observable
|
||||||
String? walletPassword;
|
String? walletPassword;
|
||||||
|
|
||||||
|
@observable
|
||||||
|
String? repeatedWalletPassword;
|
||||||
|
|
||||||
bool get hasWalletPassword => SettingsStoreBase.walletPasswordDirectInput;
|
bool get hasWalletPassword => SettingsStoreBase.walletPasswordDirectInput;
|
||||||
|
|
||||||
WalletType type;
|
WalletType type;
|
||||||
|
@ -52,6 +55,14 @@ abstract class WalletCreationVMBase with Store {
|
||||||
name = await generateName();
|
name = await generateName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasWalletPassword && (walletPassword?.isEmpty ?? true)) {
|
||||||
|
throw Exception(S.current.wallet_password_is_empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasWalletPassword && walletPassword != repeatedWalletPassword) {
|
||||||
|
throw Exception(S.current.repeated_password_is_incorrect);
|
||||||
|
}
|
||||||
|
|
||||||
walletCreationService.checkIfExists(name);
|
walletCreationService.checkIfExists(name);
|
||||||
final dirPath = await pathForWalletDir(name: name, type: type);
|
final dirPath = await pathForWalletDir(name: name, type: type);
|
||||||
final path = await pathForWallet(name: name, type: type);
|
final path = await pathForWallet(name: name, type: type);
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "رمز مرور خاطئ",
|
"invalid_password" : "رمز مرور خاطئ",
|
||||||
"unlock" : "الغاء القفل",
|
"unlock" : "الغاء القفل",
|
||||||
"enter_wallet_password" : "أدخل كلمة مرور المحفظة",
|
"enter_wallet_password" : "أدخل كلمة مرور المحفظة",
|
||||||
|
"repeate_wallet_password" : "كرر كلمة مرور المحفظة",
|
||||||
|
"wallet_password_is_empty" : "كلمة مرور المحفظة فارغة. يجب ألا تكون كلمة مرور المحفظة فارغة",
|
||||||
|
"repeated_password_is_incorrect" : "كلمة المرور المتكررة غير صحيحة. يرجى إعادة كلمة مرور المحفظة مرة أخرى.",
|
||||||
|
|
||||||
"full_balance":"الرصيد الكامل",
|
"full_balance":"الرصيد الكامل",
|
||||||
"available_balance":"الرصيد المتوفر",
|
"available_balance":"الرصيد المتوفر",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Ongeldig wachtwoord",
|
"invalid_password" : "Ongeldig wachtwoord",
|
||||||
"unlock" : "Freischalten",
|
"unlock" : "Freischalten",
|
||||||
"enter_wallet_password" : "Geben Sie das Wallet-Passwort ein",
|
"enter_wallet_password" : "Geben Sie das Wallet-Passwort ein",
|
||||||
|
"repeat_wallet_password" : "Wiederholen Sie das Wallet-Passwort",
|
||||||
|
"wallet_password_is_empty" : "Wallet-Passwort ist leer. Wallet-Passwort darf nicht leer sein",
|
||||||
|
"repeated_password_is_incorrect" : "Wiederholtes Passwort ist falsch. Bitte wiederholen Sie das Wallet-Passwort noch einmal.",
|
||||||
|
|
||||||
"full_balance" : "Gesamtguthaben",
|
"full_balance" : "Gesamtguthaben",
|
||||||
"available_balance" : "Verfügbares Guthaben",
|
"available_balance" : "Verfügbares Guthaben",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Invalid password",
|
"invalid_password" : "Invalid password",
|
||||||
"unlock" : "Unlock",
|
"unlock" : "Unlock",
|
||||||
"enter_wallet_password" : "Enter the wallet password",
|
"enter_wallet_password" : "Enter the wallet password",
|
||||||
|
"repeate_wallet_password" : "Repeat the wallet password",
|
||||||
|
"wallet_password_is_empty" : "Wallet password is empty. Wallet password should not be empty",
|
||||||
|
"repeated_password_is_incorrect" : "Repeated password is incorrect. Please repeat the wallet password again.",
|
||||||
|
|
||||||
"full_balance" : "Full Balance",
|
"full_balance" : "Full Balance",
|
||||||
"available_balance" : "Available Balance",
|
"available_balance" : "Available Balance",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Contraseña invalida",
|
"invalid_password" : "Contraseña invalida",
|
||||||
"unlock" : "desbloquear",
|
"unlock" : "desbloquear",
|
||||||
"enter_wallet_password" : "Ingrese la contraseña de la billetera",
|
"enter_wallet_password" : "Ingrese la contraseña de la billetera",
|
||||||
|
"repeate_wallet_password" : "Repita la contraseña de la billetera",
|
||||||
|
"wallet_password_is_empty" : "La contraseña de la billetera está vacía. La contraseña de la billetera no debe estar vacía",
|
||||||
|
"repeated_password_is_incorrect" : "La contraseña repetida es incorrecta. Repita la contraseña de la billetera nuevamente.",
|
||||||
|
|
||||||
"full_balance" : "Balance completo",
|
"full_balance" : "Balance completo",
|
||||||
"available_balance" : "Balance disponible",
|
"available_balance" : "Balance disponible",
|
||||||
|
|
|
@ -344,6 +344,9 @@
|
||||||
"invalid_password" : "Mot de passe incorrect",
|
"invalid_password" : "Mot de passe incorrect",
|
||||||
"unlock" : "Ouvrir",
|
"unlock" : "Ouvrir",
|
||||||
"enter_wallet_password" : "Entrez le mot de passe du portefeuille",
|
"enter_wallet_password" : "Entrez le mot de passe du portefeuille",
|
||||||
|
"repeate_wallet_password" : "Répétez le mot de passe du portefeuille",
|
||||||
|
"wallet_password_is_empty" : "Le mot de passe du portefeuille est vide. Le mot de passe du portefeuille ne doit pas être vide",
|
||||||
|
"repeated_password_is_incorrect" : "Le mot de passe répété est incorrect. Veuillez répéter le mot de passe du portefeuille.",
|
||||||
|
|
||||||
"full_balance" : "Solde Complet",
|
"full_balance" : "Solde Complet",
|
||||||
"available_balance" : "Solde Disponible",
|
"available_balance" : "Solde Disponible",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "अवैध पासवर्ड",
|
"invalid_password" : "अवैध पासवर्ड",
|
||||||
"unlock" : "अनलॉक",
|
"unlock" : "अनलॉक",
|
||||||
"enter_wallet_password" : "वॉलेट पासवर्ड दर्ज करें",
|
"enter_wallet_password" : "वॉलेट पासवर्ड दर्ज करें",
|
||||||
|
"repeate_wallet_password" : "वॉलेट पासवर्ड दोहराएं",
|
||||||
|
"wallet_password_is_empty" : "वॉलेट पासवर्ड खाली है। वॉलेट पासवर्ड खाली नहीं होना चाहिए",
|
||||||
|
"repeated_password_is_incorrect" : "दोहराया गया पासवर्ड गलत है। कृपया वॉलेट पासवर्ड दोबारा दोहराएं।",
|
||||||
|
|
||||||
"full_balance" : "पूर्ण संतुलन",
|
"full_balance" : "पूर्ण संतुलन",
|
||||||
"available_balance" : "उपलब्ध शेष राशि",
|
"available_balance" : "उपलब्ध शेष राशि",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Érvénytelen jelszó",
|
"invalid_password" : "Érvénytelen jelszó",
|
||||||
"unlock" : "Kinyit",
|
"unlock" : "Kinyit",
|
||||||
"enter_wallet_password" : "Adja meg a pénztárca jelszavát",
|
"enter_wallet_password" : "Adja meg a pénztárca jelszavát",
|
||||||
|
"repeate_wallet_password" : "Az ismételt jelszó helytelen. Kérjük, ismételje meg újra a pénztárca jelszavát.",
|
||||||
|
"wallet_password_is_empty" : "A Wallet jelszó üres. A Wallet jelszó nem lehet üres",
|
||||||
|
"repeated_password_is_incorrect" : "Az ismételt jelszó helytelen. Kérjük, ismételje meg újra a pénztárca jelszavát.",
|
||||||
|
|
||||||
"full_balance" : "Pun iznos",
|
"full_balance" : "Pun iznos",
|
||||||
"available_balance" : "Raspoloživ iznos",
|
"available_balance" : "Raspoloživ iznos",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Password non valida",
|
"invalid_password" : "Password non valida",
|
||||||
"unlock" : "Sbloccare",
|
"unlock" : "Sbloccare",
|
||||||
"enter_wallet_password" : "Inserisci la password del portafoglio",
|
"enter_wallet_password" : "Inserisci la password del portafoglio",
|
||||||
|
"repeate_wallet_password" : "Ripeti la password del portafoglio",
|
||||||
|
"wallet_password_is_empty" : "La password del portafoglio è vuota. La password del portafoglio non deve essere vuota",
|
||||||
|
"repeated_password_is_incorrect" : "La password ripetuta non è corretta. Ripeti di nuovo la password del portafoglio.",
|
||||||
|
|
||||||
"full_balance" : "Saldo Completo",
|
"full_balance" : "Saldo Completo",
|
||||||
"available_balance" : "Saldo Disponibile",
|
"available_balance" : "Saldo Disponibile",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "無効なパスワード",
|
"invalid_password" : "無効なパスワード",
|
||||||
"unlock" : "ロック解除",
|
"unlock" : "ロック解除",
|
||||||
"enter_wallet_password" : "ウォレットのパスワードを入力してください",
|
"enter_wallet_password" : "ウォレットのパスワードを入力してください",
|
||||||
|
"repeate_wallet_password" : "ウォレットのパスワードを繰り返す",
|
||||||
|
"wallet_password_is_empty" : "ウォレットのパスワードが空です。 ウォレットのパスワードを空にすることはできません",
|
||||||
|
"repeated_password_is_incorrect" : "繰り返されるパスワードが正しくありません。 ウォレットのパスワードをもう一度入力してください。",
|
||||||
|
|
||||||
"full_balance" : "フルバランス",
|
"full_balance" : "フルバランス",
|
||||||
"available_balance" : "利用可能残高",
|
"available_balance" : "利用可能残高",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "유효하지 않은 비밀번호",
|
"invalid_password" : "유효하지 않은 비밀번호",
|
||||||
"unlock" : "터놓다",
|
"unlock" : "터놓다",
|
||||||
"enter_wallet_password" : "지갑 비밀번호를 입력하세요",
|
"enter_wallet_password" : "지갑 비밀번호를 입력하세요",
|
||||||
|
"repeate_wallet_password" : "지갑 비밀번호를 반복하십시오",
|
||||||
|
"wallet_password_is_empty" : "지갑 비밀번호가 비어 있습니다. 월렛 비밀번호는 비워둘 수 없습니다.",
|
||||||
|
"repeated_password_is_incorrect" : "반복되는 비밀번호가 올바르지 않습니다. 지갑 비밀번호를 다시 한번 입력해주세요.",
|
||||||
|
|
||||||
"full_balance" : "풀 밸런스",
|
"full_balance" : "풀 밸런스",
|
||||||
"available_balance" : "사용 가능한 잔액",
|
"available_balance" : "사용 가능한 잔액",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "စကားဝှက် မမှန်ကန်ပါ။",
|
"invalid_password" : "စကားဝှက် မမှန်ကန်ပါ။",
|
||||||
"unlock" : "သော့ဖွင့်ပါ။",
|
"unlock" : "သော့ဖွင့်ပါ။",
|
||||||
"enter_wallet_password" : "ပိုက်ဆံအိတ်စကားဝှက်ကိုထည့်ပါ။",
|
"enter_wallet_password" : "ပိုက်ဆံအိတ်စကားဝှက်ကိုထည့်ပါ။",
|
||||||
|
"repeate_wallet_password" : "ပိုက်ဆံအိတ်စကားဝှက်ကို ပြန်လုပ်ပါ။",
|
||||||
|
"wallet_password_is_empty" : "ပိုက်ဆံအိတ်စကားဝှက်သည် ဗလာဖြစ်နေသည်။ ပိုက်ဆံအိတ်စကားဝှက်သည် ဗလာမဖြစ်သင့်ပါ။",
|
||||||
|
"repeated_password_is_incorrect" : "ထပ်ခါတလဲလဲ စကားဝှက် မမှန်ပါ။ ပိုက်ဆံအိတ်စကားဝှက်ကို ထပ်လုပ်ပါ။",
|
||||||
|
|
||||||
"full_balance" : "Balance အပြည့်",
|
"full_balance" : "Balance အပြည့်",
|
||||||
"available_balance" : "လက်ကျန်ငွေ ရရှိနိုင်",
|
"available_balance" : "လက်ကျန်ငွေ ရရှိနိုင်",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Ongeldig wachtwoord",
|
"invalid_password" : "Ongeldig wachtwoord",
|
||||||
"unlock" : "Ontgrendelen",
|
"unlock" : "Ontgrendelen",
|
||||||
"enter_wallet_password" : "Voer het portemonnee-wachtwoord in",
|
"enter_wallet_password" : "Voer het portemonnee-wachtwoord in",
|
||||||
|
"repeate_wallet_password" : "Herhaal het wachtwoord van de portemonnee",
|
||||||
|
"wallet_password_is_empty" : "Wallet-wachtwoord is leeg. Wallet-wachtwoord mag niet leeg zijn",
|
||||||
|
"repeated_password_is_incorrect" : "Herhaald wachtwoord is onjuist. Herhaal het wachtwoord van de portemonnee nogmaals.",
|
||||||
|
|
||||||
"full_balance" : "Volledig saldo",
|
"full_balance" : "Volledig saldo",
|
||||||
"available_balance" : "Beschikbaar saldo",
|
"available_balance" : "Beschikbaar saldo",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Nieprawidłowe hasło",
|
"invalid_password" : "Nieprawidłowe hasło",
|
||||||
"unlock" : "Odblokować",
|
"unlock" : "Odblokować",
|
||||||
"enter_wallet_password" : "Wprowadź hasło do portfela",
|
"enter_wallet_password" : "Wprowadź hasło do portfela",
|
||||||
|
"repeate_wallet_password" : "Powtórz hasło do portfela",
|
||||||
|
"wallet_password_is_empty" : "Hasło portfela jest puste. Hasło portfela nie powinno być puste",
|
||||||
|
"repeated_password_is_incorrect" : "Powtórzone hasło jest nieprawidłowe. Powtórz hasło do portfela jeszcze raz.",
|
||||||
|
|
||||||
"full_balance" : "Pełne saldo",
|
"full_balance" : "Pełne saldo",
|
||||||
"available_balance" : "Dostępne środki",
|
"available_balance" : "Dostępne środki",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Senha inválida",
|
"invalid_password" : "Senha inválida",
|
||||||
"unlock" : "desbloquear",
|
"unlock" : "desbloquear",
|
||||||
"enter_wallet_password" : "Digite a senha da carteira",
|
"enter_wallet_password" : "Digite a senha da carteira",
|
||||||
|
"repeate_wallet_password" : "Repita a senha da carteira",
|
||||||
|
"wallet_password_is_empty" : "A senha da carteira está vazia. A senha da carteira não deve estar vazia",
|
||||||
|
"repeated_password_is_incorrect" : "A senha repetida está incorreta. Por favor, repita a senha da carteira novamente.",
|
||||||
|
|
||||||
"full_balance" : "Saldo total",
|
"full_balance" : "Saldo total",
|
||||||
"available_balance" : "Saldo disponível",
|
"available_balance" : "Saldo disponível",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Invalid password",
|
"invalid_password" : "Invalid password",
|
||||||
"unlock" : "Unlock",
|
"unlock" : "Unlock",
|
||||||
"enter_wallet_password" : "Enter the wallet password",
|
"enter_wallet_password" : "Enter the wallet password",
|
||||||
|
"repeate_wallet_password" : "Repeat the wallet password",
|
||||||
|
"wallet_password_is_empty" : "Wallet password is empty. Wallet password should not be empty",
|
||||||
|
"repeated_password_is_incorrect" : "Repeated password is incorrect. Please repeat the wallet password again.",
|
||||||
|
|
||||||
"full_balance" : "Весь баланс",
|
"full_balance" : "Весь баланс",
|
||||||
"available_balance" : "Доступный баланс",
|
"available_balance" : "Доступный баланс",
|
||||||
|
|
|
@ -344,6 +344,9 @@
|
||||||
"invalid_password" : "รหัสผ่านไม่ถูกต้อง",
|
"invalid_password" : "รหัสผ่านไม่ถูกต้อง",
|
||||||
"unlock" : "ปลดล็อค",
|
"unlock" : "ปลดล็อค",
|
||||||
"enter_wallet_password" : "ป้อนรหัสผ่านกระเป๋าเงิน",
|
"enter_wallet_password" : "ป้อนรหัสผ่านกระเป๋าเงิน",
|
||||||
|
"repeate_wallet_password" : "ทำซ้ำรหัสผ่านกระเป๋าเงิน",
|
||||||
|
"wallet_password_is_empty" : "รหัสผ่าน Wallet ว่างเปล่า รหัสผ่าน Wallet ไม่ควรว่างเปล่า",
|
||||||
|
"repeated_password_is_incorrect" : "รหัสผ่านซ้ำไม่ถูกต้อง กรุณากรอกรหัสผ่านกระเป๋าเงินซ้ำอีกครั้ง",
|
||||||
|
|
||||||
"full_balance" : "ยอดคงเหลือทั้งหมด",
|
"full_balance" : "ยอดคงเหลือทั้งหมด",
|
||||||
"available_balance" : "ยอดคงเหลือที่ใช้งานได้",
|
"available_balance" : "ยอดคงเหลือที่ใช้งานได้",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "Geçersiz şifre",
|
"invalid_password" : "Geçersiz şifre",
|
||||||
"unlock" : "Kilidini aç",
|
"unlock" : "Kilidini aç",
|
||||||
"enter_wallet_password" : "cüzdan şifresini girin",
|
"enter_wallet_password" : "cüzdan şifresini girin",
|
||||||
|
"repeate_wallet_password" : "M-cüzdan şifresini tekrarla",
|
||||||
|
"wallet_password_is_empty" : "Cüzdan şifresi boş. Cüzdan şifresi boş olmamalıdır",
|
||||||
|
"repeated_password_is_incorrect" : "Tekrarlanan şifre yanlış. Lütfen cüzdan şifresini tekrar tekrarlayın.",
|
||||||
|
|
||||||
"full_balance" : "Tüm bakiye",
|
"full_balance" : "Tüm bakiye",
|
||||||
"available_balance" : "Kullanılabilir Bakiye",
|
"available_balance" : "Kullanılabilir Bakiye",
|
||||||
|
|
|
@ -345,6 +345,9 @@
|
||||||
"invalid_password" : "Невірний пароль",
|
"invalid_password" : "Невірний пароль",
|
||||||
"unlock" : "Розблокувати",
|
"unlock" : "Розблокувати",
|
||||||
"enter_wallet_password" : "Введіть пароль гаманця",
|
"enter_wallet_password" : "Введіть пароль гаманця",
|
||||||
|
"repeate_wallet_password" : "Повторіть пароль гаманця",
|
||||||
|
"wallet_password_is_empty" : "Пароль гаманця порожній. Пароль гаманця не повинен бути порожнім",
|
||||||
|
"repeated_password_is_incorrect" : "Повторний пароль неправильний. Будь ласка, повторіть пароль гаманця ще раз.",
|
||||||
|
|
||||||
"full_balance" : "Весь баланс",
|
"full_balance" : "Весь баланс",
|
||||||
"available_balance" : "Доступний баланс",
|
"available_balance" : "Доступний баланс",
|
||||||
|
|
|
@ -346,6 +346,9 @@
|
||||||
"invalid_password" : "无效的密码",
|
"invalid_password" : "无效的密码",
|
||||||
"unlock" : "开锁",
|
"unlock" : "开锁",
|
||||||
"enter_wallet_password" : "输入钱包密码",
|
"enter_wallet_password" : "输入钱包密码",
|
||||||
|
"repeate_wallet_password" : "重复钱包密码",
|
||||||
|
"wallet_password_is_empty" : "钱包密码为空。 钱包密码不能为空",
|
||||||
|
"repeated_password_is_incorrect" : "重复的密码不正确。 请再次输入钱包密码。",
|
||||||
|
|
||||||
"full_balance" : "全部余额",
|
"full_balance" : "全部余额",
|
||||||
"available_balance" : "可用余额",
|
"available_balance" : "可用余额",
|
||||||
|
|
|
@ -94,8 +94,8 @@ abstract class Bitcoin {
|
||||||
|
|
||||||
List<Unspent> getUnspents(Object wallet);
|
List<Unspent> getUnspents(Object wallet);
|
||||||
void updateUnspents(Object wallet);
|
void updateUnspents(Object wallet);
|
||||||
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
|
WalletService createBitcoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
||||||
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource);
|
WalletService createLitecoinWalletService(Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
||||||
TransactionPriority getBitcoinTransactionPriorityMedium();
|
TransactionPriority getBitcoinTransactionPriorityMedium();
|
||||||
TransactionPriority getLitecoinTransactionPriorityMedium();
|
TransactionPriority getLitecoinTransactionPriorityMedium();
|
||||||
TransactionPriority getBitcoinTransactionPrioritySlow();
|
TransactionPriority getBitcoinTransactionPrioritySlow();
|
||||||
|
|
Loading…
Reference in a new issue