mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-24 20:49:28 +00:00
Finished setup and initiated initial testing WIP [skip ci]
This commit is contained in:
parent
8c609f09a1
commit
b7d9bf8746
14 changed files with 215 additions and 176 deletions
|
@ -80,7 +80,7 @@ class BitcoinWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> sweepAllFunds(Node node, String address, String paymentId) {
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) {
|
||||
// TODO: implement sweepAllFunds
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ class LitecoinWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> sweepAllFunds(Node node, String address, String paymentId) {
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) {
|
||||
// TODO: implement sweepAllFunds
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ abstract class WalletService<N extends WalletCredentials,
|
|||
|
||||
Future<WalletBase> restoreFromKeys(RFK credentials);
|
||||
|
||||
Future<void> sweepAllFunds(Node node, String address, String paymentId);
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId);
|
||||
|
||||
Future<WalletBase> openWallet(String name, String password);
|
||||
|
||||
|
|
|
@ -48,8 +48,8 @@ void createWalletSync(
|
|||
final passwordPointer = password.toNativeUtf8();
|
||||
final languagePointer = language.toNativeUtf8();
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isWalletCreated = createWalletNative(pathPointer, passwordPointer,
|
||||
languagePointer, nettype, errorMessagePointer) !=
|
||||
final isWalletCreated = createWalletNative(
|
||||
pathPointer, passwordPointer, languagePointer, nettype, errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
calloc.free(pathPointer);
|
||||
|
@ -57,8 +57,7 @@ void createWalletSync(
|
|||
calloc.free(languagePointer);
|
||||
|
||||
if (!isWalletCreated) {
|
||||
throw WalletCreationException(
|
||||
message: convertUTF8ToString(pointer: errorMessagePointer));
|
||||
throw WalletCreationException(message: convertUTF8ToString(pointer: errorMessagePointer));
|
||||
}
|
||||
|
||||
// setupNodeSync(address: "node.moneroworld.com:18089");
|
||||
|
@ -84,12 +83,7 @@ void restoreWalletFromSeedSync(
|
|||
final seedPointer = seed.toNativeUtf8();
|
||||
final errorMessagePointer = ''.toNativeUtf8();
|
||||
final isWalletRestored = restoreWalletFromSeedNative(
|
||||
pathPointer,
|
||||
passwordPointer,
|
||||
seedPointer,
|
||||
nettype,
|
||||
restoreHeight,
|
||||
errorMessagePointer) !=
|
||||
pathPointer, passwordPointer, seedPointer, nettype, restoreHeight, errorMessagePointer) !=
|
||||
0;
|
||||
|
||||
calloc.free(pathPointer);
|
||||
|
@ -151,8 +145,7 @@ void loadWallet({required String path, required String password, int nettype = 0
|
|||
calloc.free(passwordPointer);
|
||||
|
||||
if (!loaded) {
|
||||
throw WalletOpeningException(
|
||||
message: convertUTF8ToString(pointer: errorStringNative()));
|
||||
throw WalletOpeningException(message: convertUTF8ToString(pointer: errorStringNative()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,20 +194,15 @@ bool _isWalletExist(String path) => isWalletExistSync(path: path);
|
|||
void openWallet({required String path, required String password, int nettype = 0}) async =>
|
||||
loadWallet(path: path, password: password, nettype: nettype);
|
||||
|
||||
Future<void> openWalletAsync(Map<String, String> args) async =>
|
||||
compute(_openWallet, args);
|
||||
Future<void> openWalletAsync(Map<String, String> args) async => compute(_openWallet, args);
|
||||
|
||||
Future<void> createWallet(
|
||||
{required String path,
|
||||
required String password,
|
||||
required String language,
|
||||
int nettype = 0}) async =>
|
||||
compute(_createWallet, {
|
||||
'path': path,
|
||||
'password': password,
|
||||
'language': language,
|
||||
'nettype': nettype
|
||||
});
|
||||
compute(_createWallet,
|
||||
{'path': path, 'password': password, 'language': language, 'nettype': nettype});
|
||||
|
||||
Future<void> restoreFromSeed(
|
||||
{required String path,
|
||||
|
@ -250,7 +238,7 @@ Future<void> restoreFromKeys(
|
|||
'restoreHeight': restoreHeight
|
||||
});
|
||||
|
||||
Future<bool> sweepFundsToNewWallet({
|
||||
Future<Map<String, dynamic>> sweepFundsToNewWallet({
|
||||
required Node node,
|
||||
required String address,
|
||||
required String paymentId,
|
||||
|
@ -311,9 +299,10 @@ Future<bool> sweepFundsToNewWallet({
|
|||
client.close();
|
||||
|
||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
return !(resBody['result']['offline'] as bool);
|
||||
} catch (_) {
|
||||
return false;
|
||||
return resBody;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -231,13 +231,14 @@ class HavenWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
try {
|
||||
await haven_wallet_manager.sweepFundsToNewWallet(
|
||||
final result = await haven_wallet_manager.sweepFundsToNewWallet(
|
||||
node: node,
|
||||
address: address,
|
||||
paymentId: paymentId,
|
||||
);
|
||||
return result;
|
||||
} catch (e) {
|
||||
// TODO: Implement Exception for wallet list service.
|
||||
print('MoneroWalletsManager Error: $e');
|
||||
|
|
|
@ -232,7 +232,7 @@ Future<void> restoreFromKeys(
|
|||
'restoreHeight': restoreHeight
|
||||
});
|
||||
|
||||
Future<bool> sweepFundsToNewWallet({
|
||||
Future<Map<String, dynamic>> sweepFundsToNewWallet({
|
||||
required Node node,
|
||||
required String address,
|
||||
required String paymentId,
|
||||
|
@ -253,24 +253,24 @@ Future<bool> sweepFundsToNewWallet({
|
|||
final rpcUri = node.isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
|
||||
final realm = 'monero-rpc';
|
||||
final body = {
|
||||
'method': 'sweep_all',
|
||||
'params': {
|
||||
'address': address,
|
||||
'account_index': accountIndex,
|
||||
'subaddr_indices': subaddressIndices,
|
||||
'priority': priority,
|
||||
'ring_size': ringSize,
|
||||
'outputs': outputs,
|
||||
'unlock_time': unlockTime,
|
||||
'payment_id': paymentId,
|
||||
'get_tx_keys': getTxKeys,
|
||||
'below_amount': belowAmount,
|
||||
'do_not_relay': doNotRelay,
|
||||
'get_tx_hex': getTxHex,
|
||||
'get_tx_metadata': getTxMetadata,
|
||||
"method": "sweep_all",
|
||||
"jsonrpc": "2.0",
|
||||
"id": "0",
|
||||
"params": {
|
||||
"address": address,
|
||||
"account_index": accountIndex,
|
||||
"subaddr_indices": subaddressIndices,
|
||||
"priority": priority,
|
||||
"ring_size": ringSize,
|
||||
"outputs": outputs,
|
||||
"unlock_time": unlockTime,
|
||||
"payment_id": paymentId,
|
||||
"get_tx_keys": getTxKeys,
|
||||
"below_amount": belowAmount,
|
||||
"do_not_relay": doNotRelay,
|
||||
"get_tx_hex": getTxHex,
|
||||
"get_tx_metadata": getTxMetadata,
|
||||
},
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0'
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -291,11 +291,12 @@ Future<bool> sweepFundsToNewWallet({
|
|||
);
|
||||
|
||||
client.close();
|
||||
|
||||
final resBody = json.decode(response.body) as Map<String, dynamic>;
|
||||
return !(resBody['result']['offline'] as bool);
|
||||
} catch (_) {
|
||||
return false;
|
||||
|
||||
return resBody;
|
||||
} catch (e) {
|
||||
print(e);
|
||||
throw Exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,14 +50,12 @@ class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
|
|||
final String spendKey;
|
||||
}
|
||||
|
||||
class MoneroWalletService extends WalletService<
|
||||
MoneroNewWalletCredentials,
|
||||
MoneroRestoreWalletFromSeedCredentials,
|
||||
MoneroRestoreWalletFromKeysCredentials> {
|
||||
class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
|
||||
MoneroRestoreWalletFromSeedCredentials, MoneroRestoreWalletFromKeysCredentials> {
|
||||
MoneroWalletService(this.walletInfoSource);
|
||||
|
||||
final Box<WalletInfo> walletInfoSource;
|
||||
|
||||
|
||||
static bool walletFilesExist(String path) =>
|
||||
!File(path).existsSync() && !File('$path.keys').existsSync();
|
||||
|
||||
|
@ -69,9 +67,7 @@ class MoneroWalletService extends WalletService<
|
|||
try {
|
||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await monero_wallet_manager.createWallet(
|
||||
path: path,
|
||||
password: credentials.password!,
|
||||
language: credentials.language);
|
||||
path: path, password: credentials.password!, language: credentials.language);
|
||||
final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
|
||||
await wallet.init();
|
||||
|
||||
|
@ -104,10 +100,9 @@ class MoneroWalletService extends WalletService<
|
|||
await repairOldAndroidWallet(name);
|
||||
}
|
||||
|
||||
await monero_wallet_manager
|
||||
.openWalletAsync({'path': path, 'password': password});
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()));
|
||||
await monero_wallet_manager.openWalletAsync({'path': path, 'password': password});
|
||||
final walletInfo = walletInfoSource.values
|
||||
.firstWhere((info) => info.id == WalletBase.idFor(name, getType()));
|
||||
final wallet = MoneroWallet(walletInfo: walletInfo);
|
||||
final isValid = wallet.walletAddresses.validate();
|
||||
|
||||
|
@ -124,12 +119,10 @@ class MoneroWalletService extends WalletService<
|
|||
// TODO: Implement Exception for wallet list service.
|
||||
|
||||
if ((e.toString().contains('bad_alloc') ||
|
||||
(e is WalletOpeningException &&
|
||||
(e.message == 'std::bad_alloc' ||
|
||||
e.message.contains('bad_alloc')))) ||
|
||||
(e is WalletOpeningException &&
|
||||
(e.message == 'std::bad_alloc' || e.message.contains('bad_alloc')))) ||
|
||||
(e.toString().contains('does not correspond') ||
|
||||
(e is WalletOpeningException &&
|
||||
e.message.contains('does not correspond')))) {
|
||||
(e is WalletOpeningException && e.message.contains('does not correspond')))) {
|
||||
await restoreOrResetWalletFiles(name);
|
||||
return openWallet(name, password);
|
||||
}
|
||||
|
@ -150,8 +143,7 @@ class MoneroWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<MoneroWallet> restoreFromKeys(
|
||||
MoneroRestoreWalletFromKeysCredentials credentials) async {
|
||||
Future<MoneroWallet> restoreFromKeys(MoneroRestoreWalletFromKeysCredentials credentials) async {
|
||||
try {
|
||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await monero_wallet_manager.restoreFromKeys(
|
||||
|
@ -174,8 +166,7 @@ class MoneroWalletService extends WalletService<
|
|||
}
|
||||
|
||||
@override
|
||||
Future<MoneroWallet> restoreFromSeed(
|
||||
MoneroRestoreWalletFromSeedCredentials credentials) async {
|
||||
Future<MoneroWallet> restoreFromSeed(MoneroRestoreWalletFromSeedCredentials credentials) async {
|
||||
try {
|
||||
final path = await pathForWallet(name: credentials.name, type: getType());
|
||||
await monero_wallet_manager.restoreFromSeed(
|
||||
|
@ -193,36 +184,43 @@ class MoneroWalletService extends WalletService<
|
|||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
try {
|
||||
await monero_wallet_manager.sweepFundsToNewWallet(
|
||||
final response = await monero_wallet_manager.sweepFundsToNewWallet(
|
||||
node: node,
|
||||
address: address,
|
||||
paymentId: paymentId,
|
||||
);
|
||||
|
||||
|
||||
if (response['error'] != null) {
|
||||
throw Exception('${response['error']['message']}');
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
} catch (e) {
|
||||
// TODO: Implement Exception for wallet list service.
|
||||
print('MoneroWalletsManager Error: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> repairOldAndroidWallet(String name) async {
|
||||
try {
|
||||
if (!Platform.isAndroid) {
|
||||
return;
|
||||
}
|
||||
|
||||
final oldAndroidWalletDirPath =
|
||||
await outdatedAndroidPathForWalletDir(name: name);
|
||||
final oldAndroidWalletDirPath = await outdatedAndroidPathForWalletDir(name: name);
|
||||
final dir = Directory(oldAndroidWalletDirPath);
|
||||
|
||||
if (!dir.existsSync()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final newWalletDirPath =
|
||||
await pathForWalletDir(name: name, type: getType());
|
||||
final newWalletDirPath = await pathForWalletDir(name: name, type: getType());
|
||||
|
||||
dir.listSync().forEach((f) {
|
||||
final file = File(f.path);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -39,15 +40,11 @@ class WalletCreationService {
|
|||
|
||||
bool exists(String name) {
|
||||
final walletName = name.toLowerCase();
|
||||
return walletInfoSource
|
||||
.values
|
||||
.any((walletInfo) => walletInfo.name.toLowerCase() == walletName);
|
||||
return walletInfoSource.values.any((walletInfo) => walletInfo.name.toLowerCase() == walletName);
|
||||
}
|
||||
|
||||
bool typeExists(WalletType type) {
|
||||
return walletInfoSource
|
||||
.values
|
||||
.any((walletInfo) => walletInfo.type == type);
|
||||
return walletInfoSource.values.any((walletInfo) => walletInfo.type == type);
|
||||
}
|
||||
|
||||
void checkIfExists(String name) {
|
||||
|
@ -60,15 +57,12 @@ class WalletCreationService {
|
|||
checkIfExists(credentials.name);
|
||||
final password = generateWalletPassword();
|
||||
credentials.password = password;
|
||||
await keyService.saveWalletPassword(
|
||||
password: password, walletName: credentials.name);
|
||||
final wallet = await _service!.create(credentials);
|
||||
await keyService.saveWalletPassword(password: password, walletName: credentials.name);
|
||||
final wallet = await _service!.create(credentials);
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
await sharedPreferences
|
||||
.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
|
||||
_isNewMoneroWalletPasswordUpdated);
|
||||
await sharedPreferences.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name), _isNewMoneroWalletPasswordUpdated);
|
||||
}
|
||||
|
||||
return wallet;
|
||||
|
@ -78,15 +72,12 @@ class WalletCreationService {
|
|||
checkIfExists(credentials.name);
|
||||
final password = generateWalletPassword();
|
||||
credentials.password = password;
|
||||
await keyService.saveWalletPassword(
|
||||
password: password, walletName: credentials.name);
|
||||
await keyService.saveWalletPassword(password: password, walletName: credentials.name);
|
||||
final wallet = await _service!.restoreFromKeys(credentials);
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
await sharedPreferences
|
||||
.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
|
||||
_isNewMoneroWalletPasswordUpdated);
|
||||
await sharedPreferences.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name), _isNewMoneroWalletPasswordUpdated);
|
||||
}
|
||||
|
||||
return wallet;
|
||||
|
@ -96,17 +87,19 @@ class WalletCreationService {
|
|||
checkIfExists(credentials.name);
|
||||
final password = generateWalletPassword();
|
||||
credentials.password = password;
|
||||
await keyService.saveWalletPassword(
|
||||
password: password, walletName: credentials.name);
|
||||
await keyService.saveWalletPassword(password: password, walletName: credentials.name);
|
||||
final wallet = await _service!.restoreFromSeed(credentials);
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
await sharedPreferences
|
||||
.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
|
||||
_isNewMoneroWalletPasswordUpdated);
|
||||
await sharedPreferences.setBool(
|
||||
PreferencesKey.moneroWalletUpdateV1Key(wallet.name), _isNewMoneroWalletPasswordUpdated);
|
||||
}
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
final result = await _service!.sweepAllFunds(node, address, paymentId);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ class RestoreOptionsPage extends BasePage {
|
|||
@override
|
||||
String get title => S.current.restore_restore_wallet;
|
||||
|
||||
|
||||
final bool isNewInstall;
|
||||
final imageSeedKeys = Image.asset('assets/images/restore_wallet_image.png');
|
||||
final imageBackup = Image.asset('assets/images/backup.png');
|
||||
|
@ -38,8 +37,7 @@ class RestoreOptionsPage extends BasePage {
|
|||
child: Column(
|
||||
children: <Widget>[
|
||||
RestoreButton(
|
||||
onPressed: () => Navigator.pushNamed(
|
||||
context, Routes.restoreWalletFromSeedKeys,
|
||||
onPressed: () => Navigator.pushNamed(context, Routes.restoreWalletFromSeedKeys,
|
||||
arguments: isNewInstall),
|
||||
image: imageSeedKeys,
|
||||
title: S.of(context).restore_title_from_seed_keys,
|
||||
|
@ -74,10 +72,11 @@ class RestoreOptionsPage extends BasePage {
|
|||
//! Next step will be to create a new wallet from this
|
||||
final restoreFromQRViewModel =
|
||||
getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
|
||||
await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
|
||||
await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
|
||||
if (restoreFromQRViewModel.state is FailureState) {
|
||||
final errorState = restoreFromQRViewModel.state as FailureState;
|
||||
_onWalletCreateFailure(context,
|
||||
'Create wallet state: ${restoreFromQRViewModel.state.runtimeType.toString()}');
|
||||
'Create wallet state: ${errorState.error}');
|
||||
}
|
||||
} catch (e) {
|
||||
_onWalletCreateFailure(context, e.toString());
|
||||
|
|
|
@ -25,8 +25,7 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
|||
spendKey = '',
|
||||
wif = '',
|
||||
address = '',
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
type: type, isRecovery: true);
|
||||
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
|
||||
|
||||
@observable
|
||||
int height;
|
||||
|
@ -46,7 +45,8 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
|||
bool get hasRestorationHeight => type == WalletType.monero;
|
||||
|
||||
@override
|
||||
WalletCredentials getCredentialsFromRestoredWallet(dynamic options, RestoredWallet restoreWallet) {
|
||||
WalletCredentials getCredentialsFromRestoredWallet(
|
||||
dynamic options, RestoredWallet restoreWallet) {
|
||||
final password = generateWalletPassword();
|
||||
|
||||
switch (restoreWallet.restoreMode) {
|
||||
|
@ -69,6 +69,7 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
|||
throw Exception('Unexpected type: ${restoreWallet.type.toString()}');
|
||||
}
|
||||
case WalletRestoreMode.seed:
|
||||
case WalletRestoreMode.txids:
|
||||
switch (restoreWallet.type) {
|
||||
case WalletType.monero:
|
||||
return monero!.createMoneroRestoreWalletFromSeedCredentials(
|
||||
|
@ -83,30 +84,20 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
|||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
case WalletRestoreMode.txids:
|
||||
switch (restoreWallet.type) {
|
||||
case WalletType.monero:
|
||||
return monero!
|
||||
.createMoneroNewWalletCredentials(name: name, language: options as String);
|
||||
case WalletType.bitcoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${restoreWallet.type.toString()}');
|
||||
}
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WalletBase> processFromRestoredWallet(WalletCredentials credentials, RestoredWallet restoreWallet) async {
|
||||
Future<WalletBase> processFromRestoredWallet(
|
||||
WalletCredentials credentials, RestoredWallet restoreWallet) async {
|
||||
try {
|
||||
switch (restoreWallet.restoreMode) {
|
||||
case WalletRestoreMode.keys:
|
||||
return walletCreationService.restoreFromKeys(credentials);
|
||||
case WalletRestoreMode.seed:
|
||||
case WalletRestoreMode.txids:
|
||||
return walletCreationService.restoreFromSeed(credentials);
|
||||
default:
|
||||
throw Exception('Unexpected restore mode: ${restoreWallet.restoreMode.toString()}');
|
||||
|
|
|
@ -53,12 +53,17 @@ class RestoredWallet {
|
|||
}
|
||||
|
||||
factory RestoredWallet.fromTxIds(Map<String, dynamic> json) {
|
||||
final mnemonic_seed = json['mnemonic_seed'] as String?;
|
||||
final seed = json['seed'] as String?;
|
||||
return RestoredWallet(
|
||||
restoreMode: json['mode'] as WalletRestoreMode,
|
||||
type: json['type'] as WalletType,
|
||||
address: json['address'] as String?,
|
||||
txId: json['tx_payment_id'] as String,
|
||||
txAmount: json['tx_amount'] as String,
|
||||
txId: json['txid'] as String,
|
||||
txAmount: json['tx_amount'] as String?,
|
||||
mnemonicSeed: mnemonic_seed ?? seed,
|
||||
spendKey: json['spend_key'] as String?,
|
||||
viewKey: json['view_key'] as String?,
|
||||
txDescription: json['tx_description'] as String?,
|
||||
recipientName: json['recipient_name'] as String?,
|
||||
);
|
||||
|
|
|
@ -125,11 +125,11 @@ class WalletRestoreFromQRCode {
|
|||
|
||||
static WalletRestoreMode getWalletRestoreMode(Map<String, dynamic> credentials) {
|
||||
final type = credentials['type'] as WalletType;
|
||||
if (credentials.containsKey('tx_payment_id')) {
|
||||
final txIdValue = credentials['tx_payment_id'] as String? ?? '';
|
||||
if (credentials.containsKey('txid')) {
|
||||
final txIdValue = credentials['txid'] as String? ?? '';
|
||||
return txIdValue.isNotEmpty
|
||||
? WalletRestoreMode.txids
|
||||
: throw Exception('Unexpected restore mode: tx_payment_id is invalid');
|
||||
: throw Exception('Unexpected restore mode: txid is invalid');
|
||||
}
|
||||
|
||||
if (credentials.containsKey('seed')) {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
|
@ -10,6 +13,9 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/entities/generate_name.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'wallet_creation_vm.g.dart';
|
||||
|
||||
|
@ -33,64 +39,122 @@ abstract class WalletCreationVMBase with Store {
|
|||
final Box<WalletInfo> _walletInfoSource;
|
||||
final AppStore _appStore;
|
||||
|
||||
bool nameExists(String name)
|
||||
=> walletCreationService.exists(name);
|
||||
bool nameExists(String name) => walletCreationService.exists(name);
|
||||
|
||||
bool typeExists(WalletType type)
|
||||
=> walletCreationService.typeExists(type);
|
||||
bool typeExists(WalletType type) => walletCreationService.typeExists(type);
|
||||
|
||||
Future<void> create({dynamic options, RestoredWallet? restoreWallet}) async {
|
||||
final type = restoreWallet?.type ?? this.type;
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
if (name.isEmpty) {
|
||||
name = await generateName();
|
||||
}
|
||||
//! Create a restoredWallet from the scanned wallet parameters
|
||||
final restoredWallet =
|
||||
await createNewWalletWithoutSwitching(options: options, restoreWallet: restoreWallet);
|
||||
print('Restored Wallet Address ' + restoredWallet.walletAddresses.address);
|
||||
|
||||
walletCreationService.checkIfExists(name);
|
||||
final dirPath = await pathForWalletDir(name: name, type: type);
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final credentials = restoreWallet != null
|
||||
? getCredentialsFromRestoredWallet(options, restoreWallet)
|
||||
: getCredentials(options);
|
||||
final walletInfo = WalletInfo.external(
|
||||
id: WalletBase.idFor(name, type),
|
||||
name: name,
|
||||
type: type,
|
||||
isRecovery: isRecovery,
|
||||
restoreHeight: credentials.height ?? 0,
|
||||
date: DateTime.now(),
|
||||
path: path,
|
||||
dirPath: dirPath,
|
||||
address: '',
|
||||
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven);
|
||||
credentials.walletInfo = walletInfo;
|
||||
//TODO Get transactions details to verify 10 confirmations
|
||||
|
||||
//! Restored
|
||||
final wallet = restoreWallet != null
|
||||
? await processFromRestoredWallet(credentials, restoreWallet)
|
||||
: await process(credentials);
|
||||
walletInfo.address = wallet.walletAddresses.address;
|
||||
await _walletInfoSource.add(walletInfo);
|
||||
//---- Code to create new
|
||||
//! Create the newWallet that will received the funds
|
||||
final newWallet = await createNewWalletWithoutSwitching(
|
||||
options: options,
|
||||
regenerateName: true,
|
||||
);
|
||||
final newWalletAddress = newWallet.walletAddresses.address;
|
||||
print('New Wallet Address ' + newWalletAddress);
|
||||
|
||||
//! Before we switch
|
||||
_appStore.changeCurrentWallet(wallet);
|
||||
//! Switch to the restoredWallet in order to activate the node connection
|
||||
_appStore.changeCurrentWallet(restoredWallet);
|
||||
|
||||
//! Sweep all funds from restoredWallet to newWallet
|
||||
await sweepAllFundsToNewWallet(type, newWalletAddress, restoreWallet?.txId ?? '');
|
||||
|
||||
//! Switch back to new wallet
|
||||
_appStore.changeCurrentWallet(newWallet);
|
||||
|
||||
//! Add the new Wallet info to the walletInfoSource
|
||||
await _walletInfoSource.add(newWallet.walletInfo);
|
||||
|
||||
//! Approve authentication as successful
|
||||
_appStore.authenticationStore.allowed();
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
WalletCredentials getCredentials(dynamic options) =>
|
||||
|
||||
Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
|
||||
createNewWalletWithoutSwitching(
|
||||
{dynamic options, RestoredWallet? restoreWallet, bool regenerateName = false}) async {
|
||||
state = IsExecutingState();
|
||||
if (name.isEmpty) {
|
||||
name = await generateName();
|
||||
}
|
||||
|
||||
if (regenerateName) {
|
||||
name = await generateName();
|
||||
}
|
||||
|
||||
walletCreationService.checkIfExists(name);
|
||||
final dirPath = await pathForWalletDir(name: name, type: type);
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final credentials = restoreWallet != null
|
||||
? getCredentialsFromRestoredWallet(options, restoreWallet)
|
||||
: getCredentials(options);
|
||||
final walletInfo = WalletInfo.external(
|
||||
id: WalletBase.idFor(name, type),
|
||||
name: name,
|
||||
type: type,
|
||||
isRecovery: isRecovery,
|
||||
restoreHeight: credentials.height ?? 0,
|
||||
date: DateTime.now(),
|
||||
path: path,
|
||||
dirPath: dirPath,
|
||||
address: '',
|
||||
showIntroCakePayCard:
|
||||
(!walletCreationService.typeExists(type)) && type != WalletType.haven);
|
||||
credentials.walletInfo = walletInfo;
|
||||
|
||||
final wallet = restoreWallet != null
|
||||
? await processFromRestoredWallet(credentials, restoreWallet)
|
||||
: await process(credentials);
|
||||
walletInfo.address = wallet.walletAddresses.address;
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sweepAllFundsToNewWallet(
|
||||
WalletType type, String address, String paymentId) async {
|
||||
final currentNode = _appStore.settingsStore.getCurrentNode(type);
|
||||
final result = await walletCreationService.sweepAllFunds(currentNode, address, paymentId);
|
||||
return result;
|
||||
}
|
||||
|
||||
WalletCredentials getCredentials(dynamic options) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return monero!
|
||||
.createMoneroNewWalletCredentials(name: name, language: options as String? ?? '');
|
||||
case WalletType.bitcoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.haven:
|
||||
return haven!
|
||||
.createHavenNewWalletCredentials(name: name, language: options as String? ?? '');
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
Future<WalletBase> process(WalletCredentials credentials) {
|
||||
walletCreationService.changeWalletType(type: type);
|
||||
return walletCreationService.create(credentials);
|
||||
}
|
||||
|
||||
WalletCredentials getCredentialsFromRestoredWallet(
|
||||
dynamic options, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
Future<WalletBase> process(WalletCredentials credentials) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
WalletCredentials getCredentialsFromRestoredWallet(dynamic options, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
|
||||
Future<WalletBase> processFromRestoredWallet(WalletCredentials credentials, RestoredWallet restoreWallet) =>
|
||||
Future<WalletBase> processFromRestoredWallet(
|
||||
WalletCredentials credentials, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
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/wallet_creation_service.dart';
|
||||
|
@ -10,6 +7,7 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
|
@ -43,7 +41,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
|||
return haven!.createHavenNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');;
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue