mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 12:09:43 +00:00
feat: Implement sweep all WIP [skip ci]
This commit is contained in:
parent
9f4e6f1a3a
commit
ef335efc5b
15 changed files with 294 additions and 271 deletions
|
@ -1,6 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||
|
@ -348,6 +349,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PendingTransaction> createTransactionForSweepAll(Object credentials) {
|
||||
// TODO: implement createTransactionForSweepAllElectrum
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
String toJSON() => json.encode({
|
||||
'mnemonic': mnemonic,
|
||||
'account_index': walletAddresses.currentReceiveAddressIndex.toString(),
|
||||
|
|
|
@ -56,6 +56,8 @@ abstract class WalletBase<
|
|||
|
||||
Future<PendingTransaction> createTransaction(Object credentials);
|
||||
|
||||
Future<PendingTransaction> createTransactionForSweepAll(Object credentials);
|
||||
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount);
|
||||
|
||||
// void fetchTransactionsAsync(
|
||||
|
|
|
@ -2,8 +2,6 @@ import 'package:cw_core/wallet_base.dart';
|
|||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
import 'node.dart';
|
||||
|
||||
abstract class WalletService<N extends WalletCredentials,
|
||||
RFS extends WalletCredentials,
|
||||
RFK extends WalletCredentials> {
|
||||
|
@ -15,8 +13,6 @@ abstract class WalletService<N extends WalletCredentials,
|
|||
|
||||
Future<WalletBase> restoreFromKeys(RFK credentials);
|
||||
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId);
|
||||
|
||||
Future<WalletBase> openWallet(String name, String password);
|
||||
|
||||
Future<bool> isWalletExit(String name);
|
||||
|
|
|
@ -222,6 +222,12 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
|
|||
return PendingHavenTransaction(pendingTransactionDescription, assetType);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PendingTransaction> createTransactionForSweepAll(Object credentials) {
|
||||
// TODO: implement createTransactionForSweepAllHaven
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
// FIXME: hardcoded value;
|
||||
|
|
|
@ -172,8 +172,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
final _credentials = credentials as MoneroTransactionCreationCredentials;
|
||||
final outputs = _credentials.outputs;
|
||||
final hasMultiDestination = outputs.length > 1;
|
||||
// final unlockedBalance = monero_wallet.getUnlockedBalance(
|
||||
// accountIndex: walletAddresses.accountList.accounts.first.id);
|
||||
|
||||
final unlockedBalance = monero_wallet.getUnlockedBalance(
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
|
||||
PendingTransactionDescription pendingTransactionDescription;
|
||||
|
||||
|
@ -192,10 +193,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
final int totalAmount = outputs.fold(
|
||||
0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0));
|
||||
|
||||
// if (unlockedBalance < totalAmount) {
|
||||
// throw MoneroTransactionCreationException(
|
||||
// 'You do not have enough XMR to send this amount.');
|
||||
// }
|
||||
if (unlockedBalance < totalAmount) {
|
||||
throw MoneroTransactionCreationException(
|
||||
'You do not have enough XMR to send this amount.');
|
||||
}
|
||||
|
||||
final moneroOutputs = outputs.map((output) {
|
||||
final outputAddress =
|
||||
|
@ -217,16 +218,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
output.isParsedAddress ? output.extractedAddress : output.address;
|
||||
final amount =
|
||||
output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
||||
// final formattedAmount =
|
||||
// output.sendAll ? null : output.formattedCryptoAmount;
|
||||
|
||||
// if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
|
||||
// (formattedAmount == null && unlockedBalance <= 0)) {
|
||||
// final formattedBalance = moneroAmountToString(amount: unlockedBalance);
|
||||
final formattedAmount =
|
||||
output.sendAll ? null : output.formattedCryptoAmount;
|
||||
|
||||
// throw MoneroTransactionCreationException(
|
||||
// 'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
||||
// }
|
||||
if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
|
||||
(formattedAmount == null && unlockedBalance <= 0)) {
|
||||
final formattedBalance = moneroAmountToString(amount: unlockedBalance);
|
||||
|
||||
throw MoneroTransactionCreationException(
|
||||
'You do not have enough unlocked balance. Unlocked: $formattedBalance. Transaction amount: ${output.cryptoAmount}.');
|
||||
}
|
||||
|
||||
pendingTransactionDescription =
|
||||
await transaction_history.createTransaction(
|
||||
|
@ -239,6 +241,34 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
return PendingMoneroTransaction(pendingTransactionDescription);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PendingTransaction> createTransactionForSweepAll(
|
||||
Object credentials) async {
|
||||
final _credentials = credentials as MoneroTransactionCreationCredentials;
|
||||
final outputs = _credentials.outputs;
|
||||
|
||||
PendingTransactionDescription pendingTransactionDescription;
|
||||
|
||||
if (!(syncStatus is SyncedSyncStatus)) {
|
||||
print('Wallet is not synced');
|
||||
throw MoneroTransactionCreationException('The wallet is not synced.');
|
||||
}
|
||||
|
||||
final output = outputs.first;
|
||||
final address =
|
||||
output.isParsedAddress ? output.extractedAddress : output.address;
|
||||
final amount =
|
||||
output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.');
|
||||
|
||||
pendingTransactionDescription = await transaction_history.createTransaction(
|
||||
address: address!,
|
||||
amount: amount,
|
||||
priorityRaw: _credentials.priority.serialize(),
|
||||
accountIndex: walletAddresses.account!.id);
|
||||
|
||||
return PendingMoneroTransaction(pendingTransactionDescription);
|
||||
}
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||
// FIXME: hardcoded value;
|
||||
|
@ -423,7 +453,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
|
|||
walletAddresses.accountList.update();
|
||||
syncStatus = SyncedSyncStatus();
|
||||
//! Introduce completer
|
||||
if (!syncCompleter.isCompleted) {
|
||||
syncCompleter.complete();
|
||||
}
|
||||
if (!_hasSyncAfterStartup) {
|
||||
_hasSyncAfterStartup = true;
|
||||
await save();
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import 'dart:io';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/monero_wallet_utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager;
|
||||
import 'package:cw_monero/api/wallet.dart' as monero_wallet;
|
||||
import 'package:cw_monero/api/exceptions/wallet_opening_exception.dart';
|
||||
import 'package:cw_monero/monero_wallet.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
|
@ -185,28 +183,6 @@ class MoneroWalletService extends WalletService<MoneroNewWalletCredentials,
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
try {
|
||||
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) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
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';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
@ -97,9 +95,4 @@ class WalletCreationService {
|
|||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> sweepAllFunds(Node node, String address, String paymentId) async {
|
||||
final result = await _service!.sweepAllFunds(node, address, paymentId);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
31
lib/di.dart
31
lib/di.dart
|
@ -301,7 +301,12 @@ Future setup({
|
|||
(WalletType type) => getIt.get<WalletService>(param1: type)));
|
||||
|
||||
getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) => WalletNewVM(
|
||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type),getIt.get<FiatConversionStore>(), _walletInfoSource,
|
||||
getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type),
|
||||
getIt.get<FiatConversionStore>(),
|
||||
transactionDescriptionBox,
|
||||
_walletInfoSource,
|
||||
|
||||
type: type));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestorationFromSeedVM, List, void>((args, _) {
|
||||
|
@ -310,7 +315,11 @@ Future setup({
|
|||
final mnemonic = args[2] as String;
|
||||
|
||||
return WalletRestorationFromSeedVM(
|
||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource , getIt.get<FiatConversionStore>(),
|
||||
getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type),
|
||||
_walletInfoSource,
|
||||
getIt.get<FiatConversionStore>(),
|
||||
transactionDescriptionBox,
|
||||
type: type, language: language, seed: mnemonic);
|
||||
});
|
||||
|
||||
|
@ -319,13 +328,21 @@ Future setup({
|
|||
final language = args[1] as String;
|
||||
|
||||
return WalletRestorationFromKeysVM(
|
||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type), _walletInfoSource, getIt.get<FiatConversionStore>(),
|
||||
getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type),
|
||||
_walletInfoSource,
|
||||
getIt.get<FiatConversionStore>(),
|
||||
transactionDescriptionBox,
|
||||
type: type, language: language);
|
||||
});
|
||||
|
||||
getIt.registerFactoryParam<WalletRestorationFromQRVM, WalletType, void>((WalletType type, _) {
|
||||
return WalletRestorationFromQRVM(getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type), getIt.get<FiatConversionStore>(), _walletInfoSource, type);
|
||||
getIt.get<WalletCreationService>(param1: type),
|
||||
getIt.get<FiatConversionStore>(),
|
||||
transactionDescriptionBox,
|
||||
_walletInfoSource,
|
||||
type);
|
||||
});
|
||||
|
||||
getIt.registerFactory<WalletAddressListViewModel>(() => WalletAddressListViewModel(
|
||||
|
@ -742,7 +759,11 @@ Future setup({
|
|||
|
||||
getIt.registerFactoryParam<WalletRestoreViewModel, WalletType, void>((type, _) =>
|
||||
WalletRestoreViewModel(
|
||||
getIt.get<AppStore>(), getIt.get<WalletCreationService>(param1: type),getIt.get<FiatConversionStore>(), _walletInfoSource,
|
||||
getIt.get<AppStore>(),
|
||||
getIt.get<WalletCreationService>(param1: type),
|
||||
getIt.get<FiatConversionStore>(),
|
||||
transactionDescriptionBox,
|
||||
_walletInfoSource,
|
||||
type: type));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestorePage, WalletType, void>(
|
||||
|
|
|
@ -65,19 +65,20 @@ class RestoreOptionsPage extends BasePage {
|
|||
}
|
||||
if (!isNewInstall || isPinSet) {
|
||||
try {
|
||||
//! This gives us the restored wallet
|
||||
final restoreWallet =
|
||||
await WalletRestoreFromQRCode.scanQRCodeForRestoring(context);
|
||||
|
||||
//! Next step will be to create a new wallet from this
|
||||
final restoreFromQRViewModel =
|
||||
getIt.get<WalletRestorationFromQRVM>(param1: restoreWallet.type);
|
||||
|
||||
await restoreFromQRViewModel.create(restoreWallet: restoreWallet);
|
||||
|
||||
if (restoreFromQRViewModel.state is FailureState) {
|
||||
final errorState = restoreFromQRViewModel.state as FailureState;
|
||||
_onWalletCreateFailure(context,
|
||||
'Create wallet state: ${errorState.error}');
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
_onWalletCreateFailure(context, e.toString());
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
|
@ -19,14 +20,20 @@ part 'restore_from_qr_vm.g.dart';
|
|||
class WalletRestorationFromQRVM = WalletRestorationFromQRVMBase with _$WalletRestorationFromQRVM;
|
||||
|
||||
abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store {
|
||||
WalletRestorationFromQRVMBase(AppStore appStore, WalletCreationService walletCreationService,FiatConversionStore fiatConversationStore,
|
||||
WalletRestorationFromQRVMBase(
|
||||
AppStore appStore,
|
||||
WalletCreationService walletCreationService,
|
||||
FiatConversionStore fiatConversationStore,
|
||||
Box<TransactionDescription> transactionDescriptionBox,
|
||||
Box<WalletInfo> walletInfoSource, WalletType type)
|
||||
: height = 0,
|
||||
viewKey = '',
|
||||
spendKey = '',
|
||||
wif = '',
|
||||
address = '',
|
||||
super(appStore, walletInfoSource, walletCreationService, fiatConversationStore, type: type, isRecovery: true);
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
fiatConversationStore, transactionDescriptionBox,
|
||||
type: type, isRecovery: true);
|
||||
|
||||
@observable
|
||||
int height;
|
||||
|
@ -78,6 +85,7 @@ abstract class WalletRestorationFromQRVMBase extends WalletCreationVM with Store
|
|||
height: restoreWallet.height ?? 0,
|
||||
mnemonic: restoreWallet.mnemonicSeed ?? '',
|
||||
password: password);
|
||||
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:async';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||
import 'package:cake_wallet/entities/load_current_wallet.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_mode.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
|
@ -31,10 +31,16 @@ part 'wallet_creation_vm.g.dart';
|
|||
class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
|
||||
|
||||
abstract class WalletCreationVMBase with Store {
|
||||
WalletCreationVMBase(this._appStore, this._walletInfoSource,
|
||||
this.walletCreationService, this._fiatConversationStore,
|
||||
{required this.type, required this.isRecovery})
|
||||
WalletCreationVMBase(
|
||||
this._appStore,
|
||||
this._walletInfoSource,
|
||||
this.walletCreationService,
|
||||
this._fiatConversationStore,
|
||||
this.transactionDescriptionBox,
|
||||
{required this.type,
|
||||
required this.isRecovery})
|
||||
: state = InitialExecutionState(),
|
||||
outputs = ObservableList(),
|
||||
name = '';
|
||||
|
||||
@observable
|
||||
|
@ -46,70 +52,117 @@ abstract class WalletCreationVMBase with Store {
|
|||
@observable
|
||||
PendingTransaction? pendingTransaction;
|
||||
|
||||
@observable
|
||||
ObservableList<Output> outputs;
|
||||
|
||||
WalletType type;
|
||||
final bool isRecovery;
|
||||
final WalletCreationService walletCreationService;
|
||||
final Box<WalletInfo> _walletInfoSource;
|
||||
final AppStore _appStore;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
final Box<TransactionDescription> transactionDescriptionBox;
|
||||
|
||||
bool nameExists(String name) => walletCreationService.exists(name);
|
||||
|
||||
bool typeExists(WalletType type) => walletCreationService.typeExists(type);
|
||||
|
||||
Future<void> create({dynamic options, RestoredWallet? restoreWallet}) async {
|
||||
final type = restoreWallet?.type ?? this.type;
|
||||
try {
|
||||
//! Create a restoredWallet from the scanned wallet parameters
|
||||
final restoredWallet = await createNewWalletWithoutSwitching(
|
||||
options: options, restoreWallet: restoreWallet);
|
||||
print(
|
||||
'Restored Wallet Address ' + restoredWallet.walletAddresses.address);
|
||||
|
||||
//TODO Get transactions details to verify 10 confirmations
|
||||
|
||||
// if (restoreWallet != null &&
|
||||
// restoreWallet.restoreMode == WalletRestoreMode.txids) {
|
||||
await _createFlowForSweepAll(options, restoreWallet);
|
||||
// }
|
||||
|
||||
//* Switch to the restoredWallet in order to activate the node connection
|
||||
await _walletInfoSource.add(restoredWallet.walletInfo);
|
||||
await connectToNode(restoredWallet);
|
||||
_appStore.changeCurrentWallet(restoredWallet);
|
||||
await loadCurrentWallet();
|
||||
await restoredWallet.startSync();
|
||||
print('Before syncing starts');
|
||||
await syncCompleter.future;
|
||||
print('After syncing ends');
|
||||
// await _createTransactionFlowNormally(options, restoreWallet);
|
||||
}
|
||||
|
||||
// * Create the newWallet that will receive the funds
|
||||
final newWallet = await createNewWalletWithoutSwitching(
|
||||
Future<void> _createTransactionFlowNormally(
|
||||
dynamic options,
|
||||
RestoredWallet? restoreWallet,
|
||||
) async {
|
||||
try {
|
||||
final restoredWallet = await _createNewWalletWithoutSwitching(
|
||||
options: options,
|
||||
restoreWallet: restoreWallet,
|
||||
regenerateName: true,
|
||||
);
|
||||
final newWalletAddress = newWallet.walletAddresses.address;
|
||||
print('New Wallet Address ' + newWalletAddress);
|
||||
|
||||
// * Sweep all funds from restoredWallet to newWallet
|
||||
await sweepAllFundsToNewWallet(
|
||||
restoredWallet,
|
||||
newWallet,
|
||||
type,
|
||||
newWalletAddress,
|
||||
restoreWallet?.txId ?? '',
|
||||
print(
|
||||
'Restored Wallet Address ' + restoredWallet.walletAddresses.address,
|
||||
);
|
||||
// } else {
|
||||
// await _walletInfoSource.add(restoredWallet.walletInfo);
|
||||
// _appStore.changeCurrentWallet(restoredWallet);
|
||||
|
||||
await _walletInfoSource.add(restoredWallet.walletInfo);
|
||||
|
||||
_appStore.changeCurrentWallet(restoredWallet);
|
||||
|
||||
_appStore.authenticationStore.allowed();
|
||||
|
||||
state = ExecutedSuccessfullyState();
|
||||
// }
|
||||
} catch (e) {
|
||||
print('Errorrrrr');
|
||||
print('Error occurred while creating a new wallet from Scan QR normally');
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> connectToNode(
|
||||
Future<void> _createFlowForSweepAll(
|
||||
dynamic options,
|
||||
RestoredWallet? restoreWallet,
|
||||
) async {
|
||||
final type = restoreWallet?.type ?? this.type;
|
||||
|
||||
try {
|
||||
final newWallet =
|
||||
await _createNewWalletWithoutSwitching(options: options);
|
||||
|
||||
final newWalletAddress = newWallet.walletAddresses.address;
|
||||
|
||||
print('New Wallet Address ' + newWalletAddress);
|
||||
|
||||
final restoredWallet = await _createNewWalletWithoutSwitching(
|
||||
options: options,
|
||||
restoreWallet: restoreWallet,
|
||||
regenerateName: true,
|
||||
);
|
||||
|
||||
print(
|
||||
'Restored Wallet Address ' + restoredWallet.walletAddresses.address,
|
||||
);
|
||||
|
||||
//* Switch to the restoredWallet in order to activate the node connection
|
||||
await _walletInfoSource.add(restoredWallet.walletInfo);
|
||||
|
||||
//* Connect to Node to get the ConnectedSyncStatus
|
||||
await _connectToNode(restoredWallet);
|
||||
|
||||
//* Switch to the restoredWallet for good measure
|
||||
_appStore.changeCurrentWallet(restoredWallet);
|
||||
|
||||
//* Load the wallet to simulate a real wallet interaction environment
|
||||
await loadCurrentWallet();
|
||||
|
||||
//*Synchronize
|
||||
await restoredWallet.startSync();
|
||||
|
||||
await syncCompleter.future;
|
||||
|
||||
// * Sweep all funds from restoredWallet to newWallet
|
||||
await _sweepAllFundsToNewWallet(
|
||||
restoredWallet,
|
||||
newWallet,
|
||||
type,
|
||||
restoreWallet?.txId ?? '',
|
||||
);
|
||||
|
||||
} catch (e) {
|
||||
print(
|
||||
'Error occurred while creating a new wallet from Scan QR using sweep all',
|
||||
);
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _connectToNode(
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo>
|
||||
wallet) async {
|
||||
|
@ -119,7 +172,7 @@ abstract class WalletCreationVMBase with Store {
|
|||
|
||||
Future<
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo>> createNewWalletWithoutSwitching(
|
||||
TransactionInfo>> _createNewWalletWithoutSwitching(
|
||||
{dynamic options,
|
||||
RestoredWallet? restoreWallet,
|
||||
bool regenerateName = false}) async {
|
||||
|
@ -142,7 +195,8 @@ abstract class WalletCreationVMBase with Store {
|
|||
id: WalletBase.idFor(name, type),
|
||||
name: name,
|
||||
type: type,
|
||||
isRecovery: isRecovery,
|
||||
//TODO(David): Ask Omar about this, was previous isRecovery
|
||||
isRecovery: restoreWallet != null ? true : false,
|
||||
restoreHeight: credentials.height ?? 0,
|
||||
date: DateTime.now(),
|
||||
path: path,
|
||||
|
@ -160,7 +214,7 @@ abstract class WalletCreationVMBase with Store {
|
|||
return wallet;
|
||||
}
|
||||
|
||||
Future<void> sweepAllFundsToNewWallet(
|
||||
Future<void> _sweepAllFundsToNewWallet(
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo>
|
||||
wallet,
|
||||
|
@ -168,29 +222,39 @@ abstract class WalletCreationVMBase with Store {
|
|||
TransactionInfo>
|
||||
newWallet,
|
||||
WalletType type,
|
||||
String newWalletAddress,
|
||||
String paymentId) async {
|
||||
String paymentId,
|
||||
) async {
|
||||
|
||||
final output = Output(wallet, _appStore.settingsStore,
|
||||
_fiatConversationStore, () => wallet.currency);
|
||||
output.address = newWalletAddress;
|
||||
_fiatConversationStore,
|
||||
() => wallet.currency,
|
||||
);
|
||||
outputs.add(output);
|
||||
output.address = newWallet.walletAddresses.address;
|
||||
output.sendAll = true;
|
||||
output.note = 'testing the sweep all function';
|
||||
|
||||
final credentials = _credentials(type, wallet.currency.title, output);
|
||||
print('About to enter create function');
|
||||
|
||||
try {
|
||||
await createTransaction(wallet, credentials);
|
||||
// final currentNode = _appStore.settingsStore.getCurrentNode(type);
|
||||
// final result = await walletCreationService.sweepAllFunds(currentNode, newWalletAddress, paymentId);
|
||||
//* Simulating a send all transaction
|
||||
await _createTransaction(wallet, credentials);
|
||||
|
||||
//* Switch back to new wallet
|
||||
_appStore.changeCurrentWallet(wallet);
|
||||
await _commitTransaction();
|
||||
|
||||
await _walletInfoSource.deleteAt(0);
|
||||
//* Add the new Wallet info to the walletInfoSource
|
||||
await _walletInfoSource.add(newWallet.walletInfo);
|
||||
|
||||
//* Switch to the new wallet
|
||||
_appStore.changeCurrentWallet(newWallet);
|
||||
|
||||
//* Load the wallet to simulate a real wallet interaction environment
|
||||
await loadCurrentWallet();
|
||||
|
||||
//* Approve authentication as successful
|
||||
_appStore.authenticationStore.allowed();
|
||||
|
||||
print('Successfully done inisde sweep all');
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
|
@ -244,8 +308,8 @@ abstract class WalletCreationVMBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> createTransaction(WalletBase wallet, Object credentials) async {
|
||||
|
||||
Future<void> _createTransaction(WalletBase wallet, Object credentials) async {
|
||||
try {
|
||||
print('in here');
|
||||
state = IsExecutingState();
|
||||
|
@ -257,6 +321,43 @@ abstract class WalletCreationVMBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> _commitTransaction() async {
|
||||
if (pendingTransaction == null) {
|
||||
throw Exception(
|
||||
"Pending transaction doesn't exist. It should not be happened.");
|
||||
}
|
||||
|
||||
String address = outputs.fold('', (acc, value) {
|
||||
return value.isParsedAddress
|
||||
? acc + value.address + '\n' + value.extractedAddress + '\n\n'
|
||||
: acc + value.address + '\n\n';
|
||||
});
|
||||
|
||||
address = address.trim();
|
||||
|
||||
String note = outputs.fold('', (acc, value) {
|
||||
return acc + value.note + '\n';
|
||||
});
|
||||
|
||||
note = note.trim();
|
||||
|
||||
try {
|
||||
await pendingTransaction!.commit();
|
||||
|
||||
if (pendingTransaction!.id.isNotEmpty) {
|
||||
_appStore.settingsStore.shouldSaveRecipientAddress
|
||||
? await transactionDescriptionBox.add(TransactionDescription(
|
||||
id: pendingTransaction!.id,
|
||||
recipientAddress: address,
|
||||
transactionNote: note))
|
||||
: await transactionDescriptionBox.add(TransactionDescription(
|
||||
id: pendingTransaction!.id, transactionNote: note));
|
||||
}
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
WalletCredentials getCredentials(dynamic options) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
|
@ -287,149 +388,3 @@ abstract class WalletCreationVMBase with Store {
|
|||
WalletCredentials credentials, RestoredWallet restoreWallet) =>
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
// class SweepAllService {
|
||||
// final AppStore _appStore;
|
||||
// final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
// TransactionInfo> restoredWallet;
|
||||
// final WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
// TransactionInfo> newWallet;
|
||||
// final FiatConversionStore _fiatConversationStore;
|
||||
// final Box<WalletInfo> _walletInfoSource;
|
||||
// final String? txId;
|
||||
|
||||
// SweepAllService(
|
||||
// this._appStore,
|
||||
// this.restoredWallet,
|
||||
// this._fiatConversationStore,
|
||||
// this._walletInfoSource,
|
||||
// this.newWallet,
|
||||
// this.txId,
|
||||
// );
|
||||
|
||||
// Future<void> create() async {
|
||||
// try {
|
||||
// //* Connect to the Node first
|
||||
// await connectToNode(restoredWallet);
|
||||
|
||||
// //* Switch wallet to that of the restoredWallet
|
||||
// _appStore.changeCurrentWallet(restoredWallet);
|
||||
|
||||
// //* Load the restore wallet to imitate actual loading
|
||||
// await loadCurrentWallet();
|
||||
|
||||
// //* Start the sync
|
||||
// await restoredWallet.startSync();
|
||||
// print('Before syncing starts');
|
||||
// await syncCompleter.future;
|
||||
// print('After syncing ends');
|
||||
|
||||
// // * Sweep all funds from restoredWallet to newWallet
|
||||
// await sweepAllFundsToNewWallet(
|
||||
// restoredWallet,
|
||||
// restoredWallet.type,
|
||||
// newWallet.walletAddresses.address,
|
||||
// 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();
|
||||
// } catch (e) {
|
||||
// print('Errorrrrr');
|
||||
// }
|
||||
// }
|
||||
|
||||
// Future<void> connectToNode(
|
||||
// WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
// TransactionInfo>
|
||||
// wallet) async {
|
||||
// final node = _appStore.settingsStore.getCurrentNode(wallet.type);
|
||||
// await wallet.connectToNode(node: node);
|
||||
// }
|
||||
|
||||
// Future<void> sweepAllFundsToNewWallet(
|
||||
// WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
// TransactionInfo>
|
||||
// wallet,
|
||||
// WalletType type,
|
||||
// String newWalletAddress,
|
||||
// String paymentId) async {
|
||||
// final output = Output(wallet, _appStore.settingsStore,
|
||||
// _fiatConversationStore, () => wallet.currency);
|
||||
// output.address = newWalletAddress;
|
||||
// output.sendAll = true;
|
||||
// output.note = 'testing the sweep all function';
|
||||
// final credentials = _credentials(type, wallet.currency.title, output);
|
||||
// print('About to enter create function');
|
||||
// try {
|
||||
// await createTransaction(wallet, credentials);
|
||||
// // final currentNode = _appStore.settingsStore.getCurrentNode(type);
|
||||
// // final result = await walletCreationService.sweepAllFunds(currentNode, newWalletAddress, paymentId);
|
||||
// } catch (e) {
|
||||
// log(e.toString());
|
||||
// }
|
||||
// }
|
||||
|
||||
// @action
|
||||
// Future<void> createTransaction(WalletBase wallet, Object credentials) async {
|
||||
// try {
|
||||
// print('about to enter wallet create transaction function');
|
||||
// final pendingTransaction = await wallet.createTransaction(credentials);
|
||||
// print(pendingTransaction);
|
||||
// } catch (e) {
|
||||
// log(e.toString());
|
||||
// }
|
||||
// }
|
||||
|
||||
// Object _credentials(
|
||||
// WalletType type, String cryptoCurrencyTitle, Output output) {
|
||||
// switch (type) {
|
||||
// case WalletType.bitcoin:
|
||||
// final priority = _appStore.settingsStore.priority[type];
|
||||
|
||||
// if (priority == null) {
|
||||
// throw Exception('Priority is null for wallet type: ${type}');
|
||||
// }
|
||||
|
||||
// return bitcoin!
|
||||
// .createBitcoinTransactionCredentials([output], priority: priority);
|
||||
// case WalletType.litecoin:
|
||||
// final priority = _appStore.settingsStore.priority[type];
|
||||
|
||||
// if (priority == null) {
|
||||
// throw Exception('Priority is null for wallet type: ${type}');
|
||||
// }
|
||||
|
||||
// return bitcoin!
|
||||
// .createBitcoinTransactionCredentials([output], priority: priority);
|
||||
// case WalletType.monero:
|
||||
// final priority = _appStore.settingsStore.priority[type];
|
||||
|
||||
// if (priority == null) {
|
||||
// throw Exception('Priority is null for wallet type: ${type}');
|
||||
// }
|
||||
|
||||
// return monero!.createMoneroTransactionCreationCredentials(
|
||||
// outputs: [output], priority: priority);
|
||||
// case WalletType.haven:
|
||||
// final priority = _appStore.settingsStore.priority[type];
|
||||
|
||||
// if (priority == null) {
|
||||
// throw Exception('Priority is null for wallet type: ${type}');
|
||||
// }
|
||||
|
||||
// return haven!.createHavenTransactionCreationCredentials(
|
||||
// outputs: [output],
|
||||
// priority: priority,
|
||||
// assetType: cryptoCurrencyTitle);
|
||||
// default:
|
||||
// throw Exception('Unexpected wallet type: ${type}');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
|
@ -18,11 +19,17 @@ part 'wallet_new_vm.g.dart';
|
|||
class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
|
||||
|
||||
abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
WalletNewVMBase(AppStore appStore, WalletCreationService walletCreationService,FiatConversionStore fiatConversationStore,
|
||||
WalletNewVMBase(
|
||||
AppStore appStore,
|
||||
WalletCreationService walletCreationService,
|
||||
FiatConversionStore fiatConversationStore,
|
||||
Box<TransactionDescription> transactionDescriptionBox,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
{required WalletType type})
|
||||
: selectedMnemonicLanguage = '',
|
||||
super(appStore, walletInfoSource, walletCreationService,fiatConversationStore, type: type, isRecovery: false);
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
fiatConversationStore, transactionDescriptionBox,
|
||||
type: type, isRecovery: false);
|
||||
|
||||
@observable
|
||||
String selectedMnemonicLanguage;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -22,14 +23,19 @@ class WalletRestorationFromKeysVM = WalletRestorationFromKeysVMBase
|
|||
abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
|
||||
with Store {
|
||||
WalletRestorationFromKeysVMBase(AppStore appStore,
|
||||
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,FiatConversionStore fiatConversationStore,
|
||||
WalletCreationService walletCreationService,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
FiatConversionStore fiatConversationStore,
|
||||
Box<TransactionDescription> transactionDescriptionBox,
|
||||
{required WalletType type, required this.language})
|
||||
: height = 0,
|
||||
viewKey = '',
|
||||
spendKey = '',
|
||||
wif = '',
|
||||
address = '',
|
||||
super(appStore, walletInfoSource, walletCreationService, fiatConversationStore, type: type, isRecovery: true);
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
fiatConversationStore, transactionDescriptionBox,
|
||||
type: type, isRecovery: true);
|
||||
|
||||
@observable
|
||||
int height;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -22,10 +23,15 @@ class WalletRestorationFromSeedVM = WalletRestorationFromSeedVMBase
|
|||
abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
|
||||
with Store {
|
||||
WalletRestorationFromSeedVMBase(AppStore appStore,
|
||||
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,FiatConversionStore fiatConversationStore,
|
||||
WalletCreationService walletCreationService,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
FiatConversionStore fiatConversationStore,
|
||||
Box<TransactionDescription> transactionDescriptionBox,
|
||||
{required WalletType type, required this.language, this.seed = ''})
|
||||
: height = 0,
|
||||
super(appStore, walletInfoSource, walletCreationService ,fiatConversationStore, type: type, isRecovery: true);
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
fiatConversationStore, transactionDescriptionBox,
|
||||
type: type, isRecovery: true);
|
||||
|
||||
@observable
|
||||
String seed;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/core/mnemonic_length.dart';
|
||||
import 'package:cake_wallet/entities/transaction_description.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/view_model/restore/restore_wallet.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
@ -24,7 +25,11 @@ class WalletRestoreViewModel = WalletRestoreViewModelBase
|
|||
with _$WalletRestoreViewModel;
|
||||
|
||||
abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,FiatConversionStore fiatConversationStore,
|
||||
WalletRestoreViewModelBase(
|
||||
AppStore appStore,
|
||||
WalletCreationService walletCreationService,
|
||||
FiatConversionStore fiatConversationStore,
|
||||
Box<TransactionDescription> transactionDescriptionBox,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
{required WalletType type})
|
||||
: availableModes = (type == WalletType.monero || type == WalletType.haven)
|
||||
|
@ -34,7 +39,9 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
isButtonEnabled = false,
|
||||
mode = WalletRestoreMode.seed,
|
||||
super(appStore, walletInfoSource, walletCreationService, fiatConversationStore, type: type, isRecovery: true) {
|
||||
super(appStore, walletInfoSource, walletCreationService,
|
||||
fiatConversationStore, transactionDescriptionBox,
|
||||
type: type, isRecovery: true) {
|
||||
isButtonEnabled =
|
||||
!hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
|
||||
walletCreationService.changeWalletType(type: type);
|
||||
|
|
Loading…
Reference in a new issue