mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
Add restore from private key to Ethereum (#1055)
* Add restore from private key to Ethereum Add restore from QR code for Ethereum in both seeds/keys * Add node network issue to ignored errors [skip ci]
This commit is contained in:
parent
43cf8a896e
commit
3577730de8
24 changed files with 250 additions and 433 deletions
|
@ -42,7 +42,9 @@ abstract class WalletBase<
|
||||||
|
|
||||||
set syncStatus(SyncStatus status);
|
set syncStatus(SyncStatus status);
|
||||||
|
|
||||||
String get seed;
|
String? get seed;
|
||||||
|
|
||||||
|
String? get privateKey => null;
|
||||||
|
|
||||||
Object get keys;
|
Object get keys;
|
||||||
|
|
||||||
|
|
|
@ -44,12 +44,14 @@ abstract class EthereumWalletBase
|
||||||
with Store {
|
with Store {
|
||||||
EthereumWalletBase({
|
EthereumWalletBase({
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required String mnemonic,
|
String? mnemonic,
|
||||||
|
String? privateKey,
|
||||||
required String password,
|
required String password,
|
||||||
ERC20Balance? initialBalance,
|
ERC20Balance? initialBalance,
|
||||||
}) : syncStatus = NotConnectedSyncStatus(),
|
}) : syncStatus = NotConnectedSyncStatus(),
|
||||||
_password = password,
|
_password = password,
|
||||||
_mnemonic = mnemonic,
|
_mnemonic = mnemonic,
|
||||||
|
_hexPrivateKey = privateKey,
|
||||||
_isTransactionUpdating = false,
|
_isTransactionUpdating = false,
|
||||||
_client = EthereumClient(),
|
_client = EthereumClient(),
|
||||||
walletAddresses = EthereumWalletAddresses(walletInfo),
|
walletAddresses = EthereumWalletAddresses(walletInfo),
|
||||||
|
@ -66,12 +68,13 @@ abstract class EthereumWalletBase
|
||||||
_sharedPrefs.complete(SharedPreferences.getInstance());
|
_sharedPrefs.complete(SharedPreferences.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
final String _mnemonic;
|
final String? _mnemonic;
|
||||||
|
final String? _hexPrivateKey;
|
||||||
final String _password;
|
final String _password;
|
||||||
|
|
||||||
late final Box<Erc20Token> erc20TokensBox;
|
late final Box<Erc20Token> erc20TokensBox;
|
||||||
|
|
||||||
late final EthPrivateKey _privateKey;
|
late final EthPrivateKey _ethPrivateKey;
|
||||||
|
|
||||||
late EthereumClient _client;
|
late EthereumClient _client;
|
||||||
|
|
||||||
|
@ -99,8 +102,12 @@ abstract class EthereumWalletBase
|
||||||
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
|
erc20TokensBox = await CakeHive.openBox<Erc20Token>(Erc20Token.boxName);
|
||||||
await walletAddresses.init();
|
await walletAddresses.init();
|
||||||
await transactionHistory.init();
|
await transactionHistory.init();
|
||||||
_privateKey = await getPrivateKey(_mnemonic, _password);
|
_ethPrivateKey = await getPrivateKey(
|
||||||
walletAddresses.address = _privateKey.address.toString();
|
mnemonic: _mnemonic,
|
||||||
|
privateKey: _hexPrivateKey,
|
||||||
|
password: _password,
|
||||||
|
);
|
||||||
|
walletAddresses.address = _ethPrivateKey.address.toString();
|
||||||
await save();
|
await save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +115,7 @@ abstract class EthereumWalletBase
|
||||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||||
try {
|
try {
|
||||||
if (priority is EthereumTransactionPriority) {
|
if (priority is EthereumTransactionPriority) {
|
||||||
final priorityFee =
|
final priorityFee = EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt();
|
||||||
EtherAmount.fromUnitAndValue(EtherUnit.gwei, priority.tip).getInWei.toInt();
|
|
||||||
return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0);
|
return (_gasPrice! + priorityFee) * (_estimatedGas ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +148,7 @@ abstract class EthereumWalletBase
|
||||||
throw Exception("Ethereum Node connection failed");
|
throw Exception("Ethereum Node connection failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
_client.setListeners(_privateKey.address, _onNewTransaction);
|
_client.setListeners(_ethPrivateKey.address, _onNewTransaction);
|
||||||
|
|
||||||
_setTransactionUpdateTimer();
|
_setTransactionUpdateTimer();
|
||||||
|
|
||||||
|
@ -202,7 +208,7 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
final pendingEthereumTransaction = await _client.signTransaction(
|
final pendingEthereumTransaction = await _client.signTransaction(
|
||||||
privateKey: _privateKey,
|
privateKey: _ethPrivateKey,
|
||||||
toAddress: _credentials.outputs.first.isParsedAddress
|
toAddress: _credentials.outputs.first.isParsedAddress
|
||||||
? _credentials.outputs.first.extractedAddress!
|
? _credentials.outputs.first.extractedAddress!
|
||||||
: _credentials.outputs.first.address,
|
: _credentials.outputs.first.address,
|
||||||
|
@ -240,7 +246,7 @@ abstract class EthereumWalletBase
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async {
|
Future<Map<String, EthereumTransactionInfo>> fetchTransactions() async {
|
||||||
final address = _privateKey.address.hex;
|
final address = _ethPrivateKey.address.hex;
|
||||||
final transactions = await _client.fetchTransactions(address);
|
final transactions = await _client.fetchTransactions(address);
|
||||||
|
|
||||||
final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = [];
|
final List<Future<List<EthereumTransactionModel>>> erc20TokensTransactions = [];
|
||||||
|
@ -300,7 +306,10 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get seed => _mnemonic;
|
String? get seed => _mnemonic;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get privateKey => HEX.encode(_ethPrivateKey.privateKey);
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@override
|
@override
|
||||||
|
@ -327,6 +336,7 @@ abstract class EthereumWalletBase
|
||||||
|
|
||||||
String toJSON() => json.encode({
|
String toJSON() => json.encode({
|
||||||
'mnemonic': _mnemonic,
|
'mnemonic': _mnemonic,
|
||||||
|
'private_key': privateKey,
|
||||||
'balance': balance[currency]!.toJSON(),
|
'balance': balance[currency]!.toJSON(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -338,13 +348,15 @@ abstract class EthereumWalletBase
|
||||||
final path = await pathForWallet(name: name, type: walletInfo.type);
|
final path = await pathForWallet(name: name, type: walletInfo.type);
|
||||||
final jsonSource = await read(path: path, password: password);
|
final jsonSource = await read(path: path, password: password);
|
||||||
final data = json.decode(jsonSource) as Map;
|
final data = json.decode(jsonSource) as Map;
|
||||||
final mnemonic = data['mnemonic'] as String;
|
final mnemonic = data['mnemonic'] as String?;
|
||||||
|
final privateKey = data['private_key'] as String?;
|
||||||
final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
|
final balance = ERC20Balance.fromJSON(data['balance'] as String) ?? ERC20Balance(BigInt.zero);
|
||||||
|
|
||||||
return EthereumWallet(
|
return EthereumWallet(
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
|
privateKey: privateKey,
|
||||||
initialBalance: balance,
|
initialBalance: balance,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +369,7 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ERC20Balance> _fetchEthBalance() async {
|
Future<ERC20Balance> _fetchEthBalance() async {
|
||||||
final balance = await _client.getBalance(_privateKey.address);
|
final balance = await _client.getBalance(_ethPrivateKey.address);
|
||||||
return ERC20Balance(balance.getInWei);
|
return ERC20Balance(balance.getInWei);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,7 +378,7 @@ abstract class EthereumWalletBase
|
||||||
try {
|
try {
|
||||||
if (token.enabled) {
|
if (token.enabled) {
|
||||||
balance[token] = await _client.fetchERC20Balances(
|
balance[token] = await _client.fetchERC20Balances(
|
||||||
_privateKey.address,
|
_ethPrivateKey.address,
|
||||||
token.contractAddress,
|
token.contractAddress,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,8 +388,15 @@ abstract class EthereumWalletBase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<EthPrivateKey> getPrivateKey(String mnemonic, String password) async {
|
Future<EthPrivateKey> getPrivateKey(
|
||||||
final seed = bip39.mnemonicToSeed(mnemonic);
|
{String? mnemonic, String? privateKey, required String password}) async {
|
||||||
|
assert(mnemonic != null || privateKey != null);
|
||||||
|
|
||||||
|
if (privateKey != null) {
|
||||||
|
return EthPrivateKey.fromHex(privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
final seed = bip39.mnemonicToSeed(mnemonic!);
|
||||||
|
|
||||||
final root = bip32.BIP32.fromSeed(seed);
|
final root = bip32.BIP32.fromSeed(seed);
|
||||||
|
|
||||||
|
@ -413,7 +432,7 @@ abstract class EthereumWalletBase
|
||||||
|
|
||||||
if (_token.enabled) {
|
if (_token.enabled) {
|
||||||
balance[_token] = await _client.fetchERC20Balances(
|
balance[_token] = await _client.fetchERC20Balances(
|
||||||
_privateKey.address,
|
_ethPrivateKey.address,
|
||||||
_token.contractAddress,
|
_token.contractAddress,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,16 +8,22 @@ class EthereumNewWalletCredentials extends WalletCredentials {
|
||||||
|
|
||||||
class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
|
class EthereumRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||||
EthereumRestoreWalletFromSeedCredentials(
|
EthereumRestoreWalletFromSeedCredentials(
|
||||||
{required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
|
{required String name,
|
||||||
|
required String password,
|
||||||
|
required this.mnemonic,
|
||||||
|
WalletInfo? walletInfo})
|
||||||
: super(name: name, password: password, walletInfo: walletInfo);
|
: super(name: name, password: password, walletInfo: walletInfo);
|
||||||
|
|
||||||
final String mnemonic;
|
final String mnemonic;
|
||||||
}
|
}
|
||||||
|
|
||||||
class EthereumRestoreWalletFromWIFCredentials extends WalletCredentials {
|
class EthereumRestoreWalletFromPrivateKey extends WalletCredentials {
|
||||||
EthereumRestoreWalletFromWIFCredentials(
|
EthereumRestoreWalletFromPrivateKey(
|
||||||
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
{required String name,
|
||||||
|
required String password,
|
||||||
|
required this.privateKey,
|
||||||
|
WalletInfo? walletInfo})
|
||||||
: super(name: name, password: password, walletInfo: walletInfo);
|
: super(name: name, password: password, walletInfo: walletInfo);
|
||||||
|
|
||||||
final String wif;
|
final String privateKey;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import 'package:bip39/bip39.dart' as bip39;
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
|
||||||
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
||||||
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromWIFCredentials> {
|
EthereumRestoreWalletFromSeedCredentials, EthereumRestoreWalletFromPrivateKey> {
|
||||||
EthereumWalletService(this.walletInfoSource);
|
EthereumWalletService(this.walletInfoSource);
|
||||||
|
|
||||||
final Box<WalletInfo> walletInfoSource;
|
final Box<WalletInfo> walletInfoSource;
|
||||||
|
@ -66,8 +66,18 @@ class EthereumWalletService extends WalletService<EthereumNewWalletCredentials,
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<EthereumWallet> restoreFromKeys(credentials) {
|
Future<EthereumWallet> restoreFromKeys(EthereumRestoreWalletFromPrivateKey credentials) async {
|
||||||
throw UnimplementedError();
|
final wallet = EthereumWallet(
|
||||||
|
password: credentials.password!,
|
||||||
|
privateKey: credentials.privateKey,
|
||||||
|
walletInfo: credentials.walletInfo!,
|
||||||
|
);
|
||||||
|
|
||||||
|
await wallet.init();
|
||||||
|
wallet.addInitialTokens();
|
||||||
|
await wallet.save();
|
||||||
|
|
||||||
|
return wallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -174,12 +174,12 @@ DEPENDENCIES:
|
||||||
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
||||||
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
|
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
|
||||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
|
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
|
||||||
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
|
- sensitive_clipboard (from `.symlinks/plugins/sensitive_clipboard/ios`)
|
||||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
|
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||||
- uni_links (from `.symlinks/plugins/uni_links/ios`)
|
- uni_links (from `.symlinks/plugins/uni_links/ios`)
|
||||||
- UnstoppableDomainsResolution (~> 4.0.0)
|
- UnstoppableDomainsResolution (~> 4.0.0)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
|
@ -236,7 +236,7 @@ EXTERNAL SOURCES:
|
||||||
package_info:
|
package_info:
|
||||||
:path: ".symlinks/plugins/package_info/ios"
|
:path: ".symlinks/plugins/package_info/ios"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
:path: ".symlinks/plugins/path_provider_foundation/ios"
|
:path: ".symlinks/plugins/path_provider_foundation/darwin"
|
||||||
permission_handler_apple:
|
permission_handler_apple:
|
||||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
platform_device_id:
|
platform_device_id:
|
||||||
|
@ -246,7 +246,7 @@ EXTERNAL SOURCES:
|
||||||
share_plus:
|
share_plus:
|
||||||
:path: ".symlinks/plugins/share_plus/ios"
|
:path: ".symlinks/plugins/share_plus/ios"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
:path: ".symlinks/plugins/shared_preferences_foundation/ios"
|
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||||
uni_links:
|
uni_links:
|
||||||
:path: ".symlinks/plugins/uni_links/ios"
|
:path: ".symlinks/plugins/uni_links/ios"
|
||||||
url_launcher_ios:
|
url_launcher_ios:
|
||||||
|
|
21
lib/di.dart
21
lib/di.dart
|
@ -177,8 +177,6 @@ import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
|
|
||||||
import 'package:cake_wallet/view_model/wallet_restoration_from_keys_vm.dart';
|
|
||||||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -320,25 +318,6 @@ Future setup({
|
||||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
||||||
type: type));
|
type: type));
|
||||||
|
|
||||||
getIt.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
|
|
||||||
final type = args.first as WalletType;
|
|
||||||
final language = args[1] as String;
|
|
||||||
final mnemonic = args[2] as String;
|
|
||||||
|
|
||||||
return WalletRestorationFromSeedVM(
|
|
||||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
|
||||||
type: type, language: language, seed: mnemonic);
|
|
||||||
});
|
|
||||||
|
|
||||||
getIt.registerFactoryParam<WalletRestorationFromKeysVM, List, void>((args, _) {
|
|
||||||
final type = args.first as WalletType;
|
|
||||||
final language = args[1] as String;
|
|
||||||
|
|
||||||
return WalletRestorationFromKeysVM(
|
|
||||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource,
|
|
||||||
type: type, language: language);
|
|
||||||
});
|
|
||||||
|
|
||||||
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
|
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
|
||||||
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
|
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
|
||||||
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
|
getIt.get<WalletCreationService>(param1: type), _walletInfoSource, type);
|
||||||
|
|
|
@ -22,6 +22,14 @@ class CWEthereum extends Ethereum {
|
||||||
}) =>
|
}) =>
|
||||||
EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
|
EthereumRestoreWalletFromSeedCredentials(name: name, password: password, mnemonic: mnemonic);
|
||||||
|
|
||||||
|
@override
|
||||||
|
WalletCredentials createEthereumRestoreWalletFromPrivateKey({
|
||||||
|
required String name,
|
||||||
|
required String privateKey,
|
||||||
|
required String password,
|
||||||
|
}) =>
|
||||||
|
EthereumRestoreWalletFromPrivateKey(name: name, password: password, privateKey: privateKey);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address;
|
String getAddress(WalletBase wallet) => (wallet as EthereumWallet).walletAddresses.address;
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,6 @@ import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
import 'package:cake_wallet/di.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
import 'package:cake_wallet/view_model/wallet_new_vm.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
|
|
||||||
import 'package:cake_wallet/exchange/trade.dart';
|
import 'package:cake_wallet/exchange/trade.dart';
|
||||||
import 'package:cw_core/transaction_info.dart';
|
import 'package:cw_core/transaction_info.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -80,7 +79,6 @@ import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_c
|
||||||
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
|
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/contact/contact_page.dart';
|
import 'package:cake_wallet/src/screens/contact/contact_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/restore/restore_wallet_from_seed_details.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
import 'package:cake_wallet/src/screens/exchange/exchange_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
|
import 'package:cake_wallet/src/screens/rescan/rescan_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/faq/faq_page.dart';
|
import 'package:cake_wallet/src/screens/faq/faq_page.dart';
|
||||||
|
@ -398,16 +396,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
builder: (_) =>
|
builder: (_) =>
|
||||||
getIt.get<BuyWebViewPage>(param1: args));
|
getIt.get<BuyWebViewPage>(param1: args));
|
||||||
|
|
||||||
case Routes.restoreWalletFromSeedDetails:
|
|
||||||
final args = settings.arguments as List;
|
|
||||||
final walletRestorationFromSeedVM =
|
|
||||||
getIt.get<WalletRestorationFromSeedVM>(param1: args);
|
|
||||||
|
|
||||||
return CupertinoPageRoute<void>(
|
|
||||||
fullscreenDialog: true,
|
|
||||||
builder: (_) => RestoreWalletFromSeedDetailsPage(
|
|
||||||
walletRestorationFromSeedVM: walletRestorationFromSeedVM));
|
|
||||||
|
|
||||||
case Routes.exchange:
|
case Routes.exchange:
|
||||||
return CupertinoPageRoute<void>(
|
return CupertinoPageRoute<void>(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
|
|
|
@ -30,7 +30,6 @@ class Routes {
|
||||||
static const tradeDetails = '/trade_details';
|
static const tradeDetails = '/trade_details';
|
||||||
static const exchangeFunds = '/exchange_funds';
|
static const exchangeFunds = '/exchange_funds';
|
||||||
static const exchangeTrade = '/exchange_trade';
|
static const exchangeTrade = '/exchange_trade';
|
||||||
static const restoreWalletFromSeedDetails = '/restore_from_seed_details';
|
|
||||||
static const exchange = '/exchange';
|
static const exchange = '/exchange';
|
||||||
static const settings = '/settings';
|
static const settings = '/settings';
|
||||||
static const desktop_settings_page = '/desktop_settings_page';
|
static const desktop_settings_page = '/desktop_settings_page';
|
||||||
|
|
|
@ -1,145 +0,0 @@
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
|
||||||
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
|
||||||
import 'package:cake_wallet/core/execution_state.dart';
|
|
||||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
|
||||||
import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
|
|
||||||
|
|
||||||
class RestoreWalletFromSeedDetailsPage extends BasePage {
|
|
||||||
RestoreWalletFromSeedDetailsPage(
|
|
||||||
{required this.walletRestorationFromSeedVM});
|
|
||||||
|
|
||||||
final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get title => S.current.restore_wallet_restore_description;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget body(BuildContext context) => RestoreFromSeedDetailsForm(
|
|
||||||
walletRestorationFromSeedVM: walletRestorationFromSeedVM);
|
|
||||||
}
|
|
||||||
|
|
||||||
class RestoreFromSeedDetailsForm extends StatefulWidget {
|
|
||||||
RestoreFromSeedDetailsForm({required this.walletRestorationFromSeedVM});
|
|
||||||
|
|
||||||
final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
|
|
||||||
|
|
||||||
@override
|
|
||||||
_RestoreFromSeedDetailsFormState createState() =>
|
|
||||||
_RestoreFromSeedDetailsFormState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _RestoreFromSeedDetailsFormState
|
|
||||||
extends State<RestoreFromSeedDetailsForm> {
|
|
||||||
final _formKey = GlobalKey<FormState>();
|
|
||||||
final _blockchainHeightKey = GlobalKey<BlockchainHeightState>();
|
|
||||||
final _nameController = TextEditingController();
|
|
||||||
ReactionDisposer? _stateReaction;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
_stateReaction = reaction((_) => widget.walletRestorationFromSeedVM.state,
|
|
||||||
(ExecutionState state) {
|
|
||||||
if (state is ExecutedSuccessfullyState) {
|
|
||||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state is FailureState) {
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
showPopUp<void>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertWithOneAction(
|
|
||||||
alertTitle: S.current.restore_title_from_seed,
|
|
||||||
alertContent: state.error,
|
|
||||||
buttonText: S.of(context).ok,
|
|
||||||
buttonAction: () => Navigator.of(context).pop());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
_nameController.addListener(
|
|
||||||
() => widget.walletRestorationFromSeedVM.name = _nameController.text);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_nameController.dispose();
|
|
||||||
_stateReaction?.reaction.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
padding: EdgeInsets.only(left: 24, right: 24),
|
|
||||||
child: ScrollableWithBottomSection(
|
|
||||||
contentPadding: EdgeInsets.only(bottom: 24.0),
|
|
||||||
content: Form(
|
|
||||||
key: _formKey,
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
Row(
|
|
||||||
children: <Widget>[
|
|
||||||
Flexible(
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.only(top: 20.0),
|
|
||||||
child: BaseTextFormField(
|
|
||||||
controller: _nameController,
|
|
||||||
hintText: S.of(context).restore_wallet_name,
|
|
||||||
validator: WalletNameValidator(),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
if (widget.walletRestorationFromSeedVM.hasRestorationHeight) ... [
|
|
||||||
BlockchainHeightWidget(
|
|
||||||
key: _blockchainHeightKey,
|
|
||||||
onHeightChange: (height) {
|
|
||||||
widget.walletRestorationFromSeedVM.height = height;
|
|
||||||
print(height);
|
|
||||||
}),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
|
||||||
child: Text(
|
|
||||||
S.of(context).restore_from_date_or_blockheight,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.normal,
|
|
||||||
color: Theme.of(context).hintColor
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
bottomSectionPadding: EdgeInsets.only(bottom: 24),
|
|
||||||
bottomSection: Observer(builder: (_) {
|
|
||||||
return LoadingPrimaryButton(
|
|
||||||
onPressed: () {
|
|
||||||
if (_formKey.currentState != null && _formKey.currentState!.validate()) {
|
|
||||||
widget.walletRestorationFromSeedVM.create();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isLoading:
|
|
||||||
widget.walletRestorationFromSeedVM.state is IsExecutingState,
|
|
||||||
text: S.of(context).restore_recover,
|
|
||||||
color: Theme.of(context).primaryColor,
|
|
||||||
textColor: Colors.white,
|
|
||||||
isDisabled: _nameController.text.isNotEmpty,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +1,29 @@
|
||||||
|
import 'package:cake_wallet/src/widgets/address_text_field.dart';
|
||||||
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
|
||||||
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
import 'package:cake_wallet/core/wallet_name_validator.dart';
|
||||||
import 'package:cake_wallet/entities/generate_name.dart';
|
import 'package:cake_wallet/entities/generate_name.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class WalletRestoreFromKeysFrom extends StatefulWidget {
|
class WalletRestoreFromKeysFrom extends StatefulWidget {
|
||||||
WalletRestoreFromKeysFrom({
|
WalletRestoreFromKeysFrom({
|
||||||
required this.walletRestoreViewModel,
|
required this.walletRestoreViewModel,
|
||||||
|
required this.displayPrivateKeyField,
|
||||||
|
required this.onHeightOrDateEntered,
|
||||||
Key? key,
|
Key? key,
|
||||||
this.onHeightOrDateEntered,})
|
}) : super(key: key);
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final Function(bool)? onHeightOrDateEntered;
|
final Function(bool) onHeightOrDateEntered;
|
||||||
final WalletRestoreViewModel walletRestoreViewModel;
|
final WalletRestoreViewModel walletRestoreViewModel;
|
||||||
|
final bool displayPrivateKeyField;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletRestoreFromKeysFromState createState() =>
|
WalletRestoreFromKeysFromState createState() => WalletRestoreFromKeysFromState();
|
||||||
WalletRestoreFromKeysFromState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
|
@ -35,6 +34,7 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
addressController = TextEditingController(),
|
addressController = TextEditingController(),
|
||||||
viewKeyController = TextEditingController(),
|
viewKeyController = TextEditingController(),
|
||||||
spendKeyController = TextEditingController(),
|
spendKeyController = TextEditingController(),
|
||||||
|
privateKeyController = TextEditingController(),
|
||||||
nameTextEditingController = TextEditingController();
|
nameTextEditingController = TextEditingController();
|
||||||
|
|
||||||
final GlobalKey<FormState> formKey;
|
final GlobalKey<FormState> formKey;
|
||||||
|
@ -44,6 +44,18 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
final TextEditingController viewKeyController;
|
final TextEditingController viewKeyController;
|
||||||
final TextEditingController spendKeyController;
|
final TextEditingController spendKeyController;
|
||||||
final TextEditingController nameTextEditingController;
|
final TextEditingController nameTextEditingController;
|
||||||
|
final TextEditingController privateKeyController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
privateKeyController.addListener(() {
|
||||||
|
if (privateKeyController.text.isNotEmpty) {
|
||||||
|
widget.onHeightOrDateEntered(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -51,16 +63,18 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
addressController.dispose();
|
addressController.dispose();
|
||||||
viewKeyController.dispose();
|
viewKeyController.dispose();
|
||||||
spendKeyController.dispose();
|
spendKeyController.dispose();
|
||||||
|
privateKeyController.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(left: 24, right: 24),
|
padding: EdgeInsets.only(left: 24, right: 24),
|
||||||
child: Form(
|
child: Form(
|
||||||
key: formKey,
|
key: formKey,
|
||||||
child: Column(children: <Widget>[
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
Stack(
|
Stack(
|
||||||
alignment: Alignment.centerRight,
|
alignment: Alignment.centerRight,
|
||||||
children: [
|
children: [
|
||||||
|
@ -75,9 +89,8 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
nameTextEditingController.text = rName;
|
nameTextEditingController.text = rName;
|
||||||
nameTextEditingController.selection =
|
nameTextEditingController.selection = TextSelection.fromPosition(
|
||||||
TextSelection.fromPosition(TextPosition(
|
TextPosition(offset: nameTextEditingController.text.length));
|
||||||
offset: nameTextEditingController.text.length));
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
icon: Container(
|
icon: Container(
|
||||||
|
@ -90,7 +103,8 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
height: 34,
|
height: 34,
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/images/refresh_icon.png',
|
'assets/images/refresh_icon.png',
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
|
color:
|
||||||
|
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -98,29 +112,65 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Container(height: 20),
|
Container(height: 20),
|
||||||
BaseTextFormField(
|
_restoreFromKeysFormFields(),
|
||||||
controller: addressController,
|
],
|
||||||
keyboardType: TextInputType.multiline,
|
),
|
||||||
maxLines: null,
|
),
|
||||||
hintText: S.of(context).restore_address),
|
);
|
||||||
Container(
|
}
|
||||||
padding: EdgeInsets.only(top: 20.0),
|
|
||||||
child: BaseTextFormField(
|
Widget _restoreFromKeysFormFields() {
|
||||||
controller: viewKeyController,
|
if (widget.displayPrivateKeyField) {
|
||||||
hintText: S.of(context).restore_view_key_private,
|
return AddressTextField(
|
||||||
maxLines: null)),
|
controller: privateKeyController,
|
||||||
Container(
|
placeholder: S.of(context).private_key,
|
||||||
padding: EdgeInsets.only(top: 20.0),
|
options: [AddressTextFieldOption.paste],
|
||||||
child: BaseTextFormField(
|
buttonColor: Theme.of(context).hintColor,
|
||||||
controller: spendKeyController,
|
onPushPasteButton: (_) {
|
||||||
hintText: S.of(context).restore_spend_key_private,
|
_pasteText();
|
||||||
maxLines: null)),
|
},
|
||||||
BlockchainHeightWidget(
|
);
|
||||||
key: blockchainHeightKey,
|
}
|
||||||
hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
|
|
||||||
onHeightChange: (_) => null,
|
return Column(
|
||||||
onHeightOrDateEntered: widget.onHeightOrDateEntered)
|
children: [
|
||||||
]),
|
BaseTextFormField(
|
||||||
));
|
controller: addressController,
|
||||||
|
keyboardType: TextInputType.multiline,
|
||||||
|
maxLines: null,
|
||||||
|
hintText: S.of(context).restore_address,
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(top: 20.0),
|
||||||
|
child: BaseTextFormField(
|
||||||
|
controller: viewKeyController,
|
||||||
|
hintText: S.of(context).restore_view_key_private,
|
||||||
|
maxLines: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(top: 20.0),
|
||||||
|
child: BaseTextFormField(
|
||||||
|
controller: spendKeyController,
|
||||||
|
hintText: S.of(context).restore_spend_key_private,
|
||||||
|
maxLines: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
BlockchainHeightWidget(
|
||||||
|
key: blockchainHeightKey,
|
||||||
|
hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
|
||||||
|
onHeightChange: (_) => null,
|
||||||
|
onHeightOrDateEntered: widget.onHeightOrDateEntered,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _pasteText() async {
|
||||||
|
final value = await Clipboard.getData('text/plain');
|
||||||
|
|
||||||
|
if (value?.text?.isNotEmpty ?? false) {
|
||||||
|
privateKeyController.text = value!.text!;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -19,10 +16,6 @@ import 'package:cake_wallet/src/screens/restore/wallet_restore_from_keys_form.da
|
||||||
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
import 'package:cake_wallet/src/screens/restore/wallet_restore_from_seed_form.dart';
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
import 'package:cake_wallet/core/validator.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
|
||||||
import 'package:cake_wallet/core/seed_validator.dart';
|
|
||||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
|
||||||
|
|
||||||
|
@ -76,6 +69,7 @@ class WalletRestorePage extends BasePage {
|
||||||
_pages.add(WalletRestoreFromKeysFrom(
|
_pages.add(WalletRestoreFromKeysFrom(
|
||||||
key: walletRestoreFromKeysFormKey,
|
key: walletRestoreFromKeysFormKey,
|
||||||
walletRestoreViewModel: walletRestoreViewModel,
|
walletRestoreViewModel: walletRestoreViewModel,
|
||||||
|
displayPrivateKeyField: walletRestoreViewModel.hasRestoreFromPrivateKey,
|
||||||
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
|
onHeightOrDateEntered: (value) => walletRestoreViewModel.isButtonEnabled = value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -193,8 +187,12 @@ class WalletRestorePage extends BasePage {
|
||||||
return LoadingPrimaryButton(
|
return LoadingPrimaryButton(
|
||||||
onPressed: _confirmForm,
|
onPressed: _confirmForm,
|
||||||
text: S.of(context).restore_recover,
|
text: S.of(context).restore_recover,
|
||||||
color: Theme.of(context).extension<WalletListTheme>()!.createNewWalletButtonBackgroundColor,
|
color: Theme.of(context)
|
||||||
textColor: Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor,
|
.extension<WalletListTheme>()!
|
||||||
|
.createNewWalletButtonBackgroundColor,
|
||||||
|
textColor: Theme.of(context)
|
||||||
|
.extension<WalletListTheme>()!
|
||||||
|
.restoreWalletButtonTextColor,
|
||||||
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
isLoading: walletRestoreViewModel.state is IsExecutingState,
|
||||||
isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
isDisabled: !walletRestoreViewModel.isButtonEnabled,
|
||||||
);
|
);
|
||||||
|
@ -246,11 +244,18 @@ class WalletRestorePage extends BasePage {
|
||||||
credentials['name'] =
|
credentials['name'] =
|
||||||
walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
|
walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
|
||||||
} else {
|
} else {
|
||||||
credentials['address'] = walletRestoreFromKeysFormKey.currentState!.addressController.text;
|
if (walletRestoreViewModel.hasRestoreFromPrivateKey) {
|
||||||
credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
|
credentials['private_key'] =
|
||||||
credentials['spendKey'] = walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
|
walletRestoreFromKeysFormKey.currentState!.privateKeyController.text;
|
||||||
credentials['height'] =
|
} else {
|
||||||
walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState!.height;
|
credentials['address'] = walletRestoreFromKeysFormKey.currentState!.addressController.text;
|
||||||
|
credentials['viewKey'] = walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
|
||||||
|
credentials['spendKey'] =
|
||||||
|
walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
|
||||||
|
credentials['height'] =
|
||||||
|
walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState!.height;
|
||||||
|
}
|
||||||
|
|
||||||
credentials['name'] =
|
credentials['name'] =
|
||||||
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
|
walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
|
import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
|
||||||
import 'package:cake_wallet/src/widgets/blockchain_height_widget.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:cake_wallet/palette.dart';
|
|
||||||
import 'package:cake_wallet/core/seed_validator.dart';
|
import 'package:cake_wallet/core/seed_validator.dart';
|
||||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
|
||||||
import 'package:cake_wallet/entities/mnemonic_item.dart';
|
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
|
|
||||||
class SeedWidget extends StatefulWidget {
|
class SeedWidget extends StatefulWidget {
|
||||||
|
|
|
@ -148,6 +148,7 @@ class ExceptionHandler {
|
||||||
"CERTIFICATE_VERIFY_FAILED",
|
"CERTIFICATE_VERIFY_FAILED",
|
||||||
"Handshake error in client",
|
"Handshake error in client",
|
||||||
"Error while launching http",
|
"Error while launching http",
|
||||||
|
"OS Error: Network is unreachable",
|
||||||
];
|
];
|
||||||
|
|
||||||
static Future<void> _addDeviceInfo(File file) async {
|
static Future<void> _addDeviceInfo(File file) async {
|
||||||
|
|
|
@ -107,7 +107,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
name = wallet.name;
|
name = wallet.name;
|
||||||
type = wallet.type;
|
type = wallet.type;
|
||||||
isOutdatedElectrumWallet =
|
isOutdatedElectrumWallet =
|
||||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
|
||||||
isShowFirstYatIntroduction = false;
|
isShowFirstYatIntroduction = false;
|
||||||
isShowSecondYatIntroduction = false;
|
isShowSecondYatIntroduction = false;
|
||||||
isShowThirdYatIntroduction = false;
|
isShowThirdYatIntroduction = false;
|
||||||
|
@ -327,7 +327,7 @@ abstract class DashboardViewModelBase with Store {
|
||||||
type = wallet.type;
|
type = wallet.type;
|
||||||
name = wallet.name;
|
name = wallet.name;
|
||||||
isOutdatedElectrumWallet =
|
isOutdatedElectrumWallet =
|
||||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
wallet.type == WalletType.bitcoin && wallet.seed!.split(' ').length < 24;
|
||||||
updateActions();
|
updateActions();
|
||||||
|
|
||||||
if (wallet.type == WalletType.monero) {
|
if (wallet.type == WalletType.monero) {
|
||||||
|
|
|
@ -66,6 +66,9 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
||||||
case WalletType.litecoin:
|
case WalletType.litecoin:
|
||||||
return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
|
return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
|
||||||
name: name, password: password, wif: wif);
|
name: name, password: password, wif: wif);
|
||||||
|
case WalletType.ethereum:
|
||||||
|
return ethereum!.createEthereumRestoreWalletFromPrivateKey(
|
||||||
|
name: name, password: password, privateKey: restoreWallet.privateKey!);
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected type: ${restoreWallet.type.toString()}');
|
throw Exception('Unexpected type: ${restoreWallet.type.toString()}');
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,8 @@ class RestoredWallet {
|
||||||
this.txAmount,
|
this.txAmount,
|
||||||
this.txDescription,
|
this.txDescription,
|
||||||
this.recipientName,
|
this.recipientName,
|
||||||
this.height});
|
this.height,
|
||||||
|
this.privateKey});
|
||||||
|
|
||||||
final WalletRestoreMode restoreMode;
|
final WalletRestoreMode restoreMode;
|
||||||
final WalletType type;
|
final WalletType type;
|
||||||
|
@ -26,6 +27,7 @@ class RestoredWallet {
|
||||||
final String? txDescription;
|
final String? txDescription;
|
||||||
final String? recipientName;
|
final String? recipientName;
|
||||||
final int? height;
|
final int? height;
|
||||||
|
final String? privateKey;
|
||||||
|
|
||||||
factory RestoredWallet.fromKey(Map<String, dynamic> json) {
|
factory RestoredWallet.fromKey(Map<String, dynamic> json) {
|
||||||
final height = json['height'] as String?;
|
final height = json['height'] as String?;
|
||||||
|
@ -36,6 +38,7 @@ class RestoredWallet {
|
||||||
spendKey: json['spend_key'] as String?,
|
spendKey: json['spend_key'] as String?,
|
||||||
viewKey: json['view_key'] as String?,
|
viewKey: json['view_key'] as String?,
|
||||||
height: height != null ? int.parse(height) : 0,
|
height: height != null ? int.parse(height) : 0,
|
||||||
|
privateKey: json['private_key'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,10 @@ class WalletRestoreFromQRCode {
|
||||||
getSeedPhraseFromUrl(queryParameters.toString(), credentials['type'] as WalletType);
|
getSeedPhraseFromUrl(queryParameters.toString(), credentials['type'] as WalletType);
|
||||||
if (seed != null) {
|
if (seed != null) {
|
||||||
credentials['seed'] = seed;
|
credentials['seed'] = seed;
|
||||||
|
} else {
|
||||||
|
credentials['private_key'] = queryParameters['private_key'];
|
||||||
}
|
}
|
||||||
|
|
||||||
credentials.addAll(queryParameters);
|
credentials.addAll(queryParameters);
|
||||||
credentials['mode'] = getWalletRestoreMode(credentials);
|
credentials['mode'] = getWalletRestoreMode(credentials);
|
||||||
|
|
||||||
|
@ -69,6 +72,8 @@ class WalletRestoreFromQRCode {
|
||||||
case 'litecoin':
|
case 'litecoin':
|
||||||
case 'litecoin-wallet':
|
case 'litecoin-wallet':
|
||||||
return WalletType.litecoin;
|
return WalletType.litecoin;
|
||||||
|
case 'ethereum-wallet':
|
||||||
|
return WalletType.ethereum;
|
||||||
default:
|
default:
|
||||||
throw Exception('Unexpected wallet type: ${scheme.toString()}');
|
throw Exception('Unexpected wallet type: ${scheme.toString()}');
|
||||||
}
|
}
|
||||||
|
@ -101,6 +106,7 @@ class WalletRestoreFromQRCode {
|
||||||
}
|
}
|
||||||
case WalletType.bitcoin:
|
case WalletType.bitcoin:
|
||||||
case WalletType.litecoin:
|
case WalletType.litecoin:
|
||||||
|
case WalletType.ethereum:
|
||||||
RegExp regex24 = RegExp(r'\b(\S+\b\s+){23}\S+\b');
|
RegExp regex24 = RegExp(r'\b(\S+\b\s+){23}\S+\b');
|
||||||
RegExp regex18 = RegExp(r'\b(\S+\b\s+){17}\S+\b');
|
RegExp regex18 = RegExp(r'\b(\S+\b\s+){17}\S+\b');
|
||||||
RegExp regex12 = RegExp(r'\b(\S+\b\s+){11}\S+\b');
|
RegExp regex12 = RegExp(r'\b(\S+\b\s+){11}\S+\b');
|
||||||
|
@ -152,6 +158,14 @@ class WalletRestoreFromQRCode {
|
||||||
: throw Exception('Unexpected restore mode: spend_key or view_key is invalid');
|
: throw Exception('Unexpected restore mode: spend_key or view_key is invalid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == WalletType.ethereum && credentials.containsKey('private_key')) {
|
||||||
|
final privateKey = credentials['private_key'] as String;
|
||||||
|
if (privateKey.isEmpty) {
|
||||||
|
throw Exception('Unexpected restore mode: private_key');
|
||||||
|
}
|
||||||
|
return WalletRestoreMode.keys;
|
||||||
|
}
|
||||||
|
|
||||||
throw Exception('Unexpected restore mode: restore params are invalid');
|
throw Exception('Unexpected restore mode: restore params are invalid');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,7 @@ abstract class WalletKeysViewModelBase with Store {
|
||||||
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
|
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
|
||||||
if (keys['privateViewKey'] != null)
|
if (keys['privateViewKey'] != null)
|
||||||
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
|
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
|
||||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
|
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,15 +85,23 @@ abstract class WalletKeysViewModelBase with Store {
|
||||||
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
|
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
|
||||||
if (keys['privateViewKey'] != null)
|
if (keys['privateViewKey'] != null)
|
||||||
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
|
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
|
||||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
|
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_appStore.wallet!.type == WalletType.bitcoin ||
|
if (_appStore.wallet!.type == WalletType.bitcoin ||
|
||||||
_appStore.wallet!.type == WalletType.litecoin ||
|
_appStore.wallet!.type == WalletType.litecoin) {
|
||||||
_appStore.wallet!.type == WalletType.ethereum) {
|
|
||||||
items.addAll([
|
items.addAll([
|
||||||
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed),
|
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_appStore.wallet!.type == WalletType.ethereum) {
|
||||||
|
items.addAll([
|
||||||
|
if (_appStore.wallet!.privateKey != null)
|
||||||
|
StandartListItem(title: S.current.private_key, value: _appStore.wallet!.privateKey!),
|
||||||
|
if (_appStore.wallet!.seed != null)
|
||||||
|
StandartListItem(title: S.current.wallet_seed, value: _appStore.wallet!.seed!),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +147,8 @@ abstract class WalletKeysViewModelBase with Store {
|
||||||
Future<Map<String, String>> get _queryParams async {
|
Future<Map<String, String>> get _queryParams async {
|
||||||
final restoreHeightResult = await restoreHeight;
|
final restoreHeightResult = await restoreHeight;
|
||||||
return {
|
return {
|
||||||
'seed': _appStore.wallet!.seed,
|
if (_appStore.wallet!.seed != null) 'seed': _appStore.wallet!.seed!,
|
||||||
|
if (_appStore.wallet!.privateKey != null) 'private_key': _appStore.wallet!.privateKey!,
|
||||||
if (restoreHeightResult != null) ...{'height': restoreHeightResult}
|
if (restoreHeightResult != null) ...{'height': restoreHeightResult}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
|
||||||
import 'package:cake_wallet/monero/monero.dart';
|
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
|
||||||
import 'package:cw_core/wallet_base.dart';
|
|
||||||
import 'package: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:cake_wallet/view_model/wallet_creation_vm.dart';
|
|
||||||
import 'package:cw_core/wallet_info.dart';
|
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
|
||||||
|
|
||||||
part 'wallet_restoration_from_keys_vm.g.dart';
|
|
||||||
|
|
||||||
class WalletRestorationFromKeysVM = WalletRestorationFromKeysVMBase
|
|
||||||
with _$WalletRestorationFromKeysVM;
|
|
||||||
|
|
||||||
abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
|
|
||||||
with Store {
|
|
||||||
WalletRestorationFromKeysVMBase(AppStore appStore,
|
|
||||||
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
|
|
||||||
{required WalletType type, required this.language})
|
|
||||||
: height = 0,
|
|
||||||
viewKey = '',
|
|
||||||
spendKey = '',
|
|
||||||
wif = '',
|
|
||||||
address = '',
|
|
||||||
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
|
|
||||||
|
|
||||||
@observable
|
|
||||||
int height;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String viewKey;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String spendKey;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String wif;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String address;
|
|
||||||
|
|
||||||
bool get hasRestorationHeight => type == WalletType.monero;
|
|
||||||
|
|
||||||
final String language;
|
|
||||||
|
|
||||||
@override
|
|
||||||
WalletCredentials getCredentials(dynamic options) {
|
|
||||||
final password = generateWalletPassword();
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case WalletType.monero:
|
|
||||||
return monero!.createMoneroRestoreWalletFromKeysCredentials(
|
|
||||||
name: name,
|
|
||||||
password: password,
|
|
||||||
language: language,
|
|
||||||
address: address,
|
|
||||||
viewKey: viewKey,
|
|
||||||
spendKey: spendKey,
|
|
||||||
height: height);
|
|
||||||
case WalletType.bitcoin:
|
|
||||||
return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
|
|
||||||
name: name, password: password, wif: wif);
|
|
||||||
default:
|
|
||||||
throw Exception('Unexpected type: ${type.toString()}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<WalletBase> process(WalletCredentials credentials) async =>
|
|
||||||
walletCreationService.restoreFromKeys(credentials);
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:hive/hive.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
|
||||||
import 'package:cake_wallet/monero/monero.dart';
|
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin.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:cake_wallet/view_model/wallet_creation_vm.dart';
|
|
||||||
import 'package:cw_core/wallet_info.dart';
|
|
||||||
|
|
||||||
part 'wallet_restoration_from_seed_vm.g.dart';
|
|
||||||
|
|
||||||
class WalletRestorationFromSeedVM = WalletRestorationFromSeedVMBase
|
|
||||||
with _$WalletRestorationFromSeedVM;
|
|
||||||
|
|
||||||
abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
|
|
||||||
with Store {
|
|
||||||
WalletRestorationFromSeedVMBase(AppStore appStore,
|
|
||||||
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
|
|
||||||
{required WalletType type, required this.language, this.seed = ''})
|
|
||||||
: height = 0,
|
|
||||||
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
|
|
||||||
|
|
||||||
@observable
|
|
||||||
String seed;
|
|
||||||
|
|
||||||
@observable
|
|
||||||
int height;
|
|
||||||
|
|
||||||
bool get hasRestorationHeight => type == WalletType.monero;
|
|
||||||
|
|
||||||
final String language;
|
|
||||||
|
|
||||||
@override
|
|
||||||
WalletCredentials getCredentials(dynamic options) {
|
|
||||||
final password = generateWalletPassword();
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case WalletType.monero:
|
|
||||||
return monero!.createMoneroRestoreWalletFromSeedCredentials(
|
|
||||||
name: name, height: height, mnemonic: seed, password: password);
|
|
||||||
case WalletType.bitcoin:
|
|
||||||
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
|
|
||||||
name: name, mnemonic: seed, password: password);
|
|
||||||
default:
|
|
||||||
throw Exception('Unexpected type: ${type.toString()}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<WalletBase> process(WalletCredentials credentials) async =>
|
|
||||||
walletCreationService.restoreFromSeed(credentials);
|
|
||||||
}
|
|
|
@ -1,7 +1,4 @@
|
||||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||||
import 'package:cake_wallet/core/mnemonic_length.dart';
|
|
||||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
@ -19,7 +16,6 @@ import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||||
|
|
||||||
part 'wallet_restore_view_model.g.dart';
|
part 'wallet_restore_view_model.g.dart';
|
||||||
|
|
||||||
|
|
||||||
class WalletRestoreViewModel = WalletRestoreViewModelBase
|
class WalletRestoreViewModel = WalletRestoreViewModelBase
|
||||||
with _$WalletRestoreViewModel;
|
with _$WalletRestoreViewModel;
|
||||||
|
|
||||||
|
@ -27,11 +23,13 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
|
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
|
||||||
Box<WalletInfo> walletInfoSource,
|
Box<WalletInfo> walletInfoSource,
|
||||||
{required WalletType type})
|
{required WalletType type})
|
||||||
: availableModes = (type == WalletType.monero || type == WalletType.haven)
|
: availableModes =
|
||||||
? WalletRestoreMode.values
|
(type == WalletType.monero || type == WalletType.haven || type == WalletType.ethereum)
|
||||||
: [WalletRestoreMode.seed],
|
? WalletRestoreMode.values
|
||||||
|
: [WalletRestoreMode.seed],
|
||||||
hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||||
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||||
|
hasRestoreFromPrivateKey = type == WalletType.ethereum,
|
||||||
isButtonEnabled = false,
|
isButtonEnabled = false,
|
||||||
mode = WalletRestoreMode.seed,
|
mode = WalletRestoreMode.seed,
|
||||||
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
|
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
|
||||||
|
@ -47,6 +45,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
final List<WalletRestoreMode> availableModes;
|
final List<WalletRestoreMode> availableModes;
|
||||||
final bool hasSeedLanguageSelector;
|
final bool hasSeedLanguageSelector;
|
||||||
final bool hasBlockchainHeightLanguageSelector;
|
final bool hasBlockchainHeightLanguageSelector;
|
||||||
|
final bool hasRestoreFromPrivateKey;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
WalletRestoreMode mode;
|
WalletRestoreMode mode;
|
||||||
|
@ -97,17 +96,17 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == WalletRestoreMode.keys) {
|
if (mode == WalletRestoreMode.keys) {
|
||||||
final viewKey = options['viewKey'] as String;
|
final viewKey = options['viewKey'] as String?;
|
||||||
final spendKey = options['spendKey'] as String;
|
final spendKey = options['spendKey'] as String?;
|
||||||
final address = options['address'] as String;
|
final address = options['address'] as String?;
|
||||||
|
|
||||||
if (type == WalletType.monero) {
|
if (type == WalletType.monero) {
|
||||||
return monero!.createMoneroRestoreWalletFromKeysCredentials(
|
return monero!.createMoneroRestoreWalletFromKeysCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
height: height,
|
height: height,
|
||||||
spendKey: spendKey,
|
spendKey: spendKey!,
|
||||||
viewKey: viewKey,
|
viewKey: viewKey!,
|
||||||
address: address,
|
address: address!,
|
||||||
password: password,
|
password: password,
|
||||||
language: 'English');
|
language: 'English');
|
||||||
}
|
}
|
||||||
|
@ -116,12 +115,20 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||||
return haven!.createHavenRestoreWalletFromKeysCredentials(
|
return haven!.createHavenRestoreWalletFromKeysCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
height: height,
|
height: height,
|
||||||
spendKey: spendKey,
|
spendKey: spendKey!,
|
||||||
viewKey: viewKey,
|
viewKey: viewKey!,
|
||||||
address: address,
|
address: address!,
|
||||||
password: password,
|
password: password,
|
||||||
language: 'English');
|
language: 'English');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == WalletType.ethereum) {
|
||||||
|
return ethereum!.createEthereumRestoreWalletFromPrivateKey(
|
||||||
|
name: name,
|
||||||
|
privateKey: options['private_key'] as String,
|
||||||
|
password: password,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception('Unexpected type: ${type.toString()}');
|
throw Exception('Unexpected type: ${type.toString()}');
|
||||||
|
|
|
@ -8,7 +8,7 @@ class WalletSeedViewModel = WalletSeedViewModelBase with _$WalletSeedViewModel;
|
||||||
abstract class WalletSeedViewModelBase with Store {
|
abstract class WalletSeedViewModelBase with Store {
|
||||||
WalletSeedViewModelBase(WalletBase wallet)
|
WalletSeedViewModelBase(WalletBase wallet)
|
||||||
: name = wallet.name,
|
: name = wallet.name,
|
||||||
seed = wallet.seed;
|
seed = wallet.seed!;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
String name;
|
String name;
|
||||||
|
|
|
@ -507,6 +507,7 @@ abstract class Ethereum {
|
||||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource);
|
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource);
|
||||||
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo});
|
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo});
|
||||||
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
|
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
|
||||||
|
WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
||||||
String getAddress(WalletBase wallet);
|
String getAddress(WalletBase wallet);
|
||||||
TransactionPriority getDefaultTransactionPriority();
|
TransactionPriority getDefaultTransactionPriority();
|
||||||
List<TransactionPriority> getTransactionPriorities();
|
List<TransactionPriority> getTransactionPriorities();
|
||||||
|
|
Loading…
Reference in a new issue