diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index c2899db9b..ed0f306c2 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -48,8 +48,8 @@ const MIN_RESTORE_HEIGHT = 1000; class MoneroWallet = MoneroWalletBase with _$MoneroWallet; -abstract class MoneroWalletBase extends WalletBase with Store { +abstract class MoneroWalletBase + extends WalletBase with Store { MoneroWalletBase( {required WalletInfo walletInfo, required Box unspentCoinsInfo, @@ -71,16 +71,13 @@ abstract class MoneroWalletBase extends WalletBase walletAddresses.account, (Account? account) { + _onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) { if (account == null) return; - balance = ObservableMap.of({ + balance = ObservableMap.of({ currency: MoneroBalance( fullBalance: monero_wallet.getFullBalance(accountIndex: account.id), - unlockedBalance: - monero_wallet.getUnlockedBalance(accountIndex: account.id)) + unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id)) }); _updateSubAddress(isEnabledAutoGenerateSubaddress, account: account); _askForUpdateTransactionHistory(); @@ -135,7 +132,8 @@ abstract class MoneroWalletBase extends WalletBase - transactionHistory.transactions.values.firstOrNull?.height ?? monero.Wallet_getRefreshFromBlockHeight(wptr!); + transactionHistory.transactions.values.firstOrNull?.height ?? + monero.Wallet_getRefreshFromBlockHeight(wptr!); monero_wallet.SyncListener? _listener; ReactionDisposer? _onAccountChangeReaction; @@ -148,13 +146,11 @@ abstract class MoneroWalletBase extends WalletBase init() async { await walletAddresses.init(); - balance = ObservableMap.of({ + balance = ObservableMap.of({ currency: MoneroBalance( - fullBalance: monero_wallet.getFullBalance( - accountIndex: walletAddresses.account!.id), - unlockedBalance: monero_wallet.getUnlockedBalance( - accountIndex: walletAddresses.account!.id)) + fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id), + unlockedBalance: + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id)) }); _setListeners(); await updateTransactions(); @@ -163,15 +159,14 @@ abstract class MoneroWalletBase extends WalletBase await save()); + _autoSaveTimer = + Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save()); // update transaction details after restore - walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id??0); + walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id ?? 0); } @override @@ -274,9 +269,9 @@ abstract class MoneroWalletBase extends WalletBase[]; final outputs = _credentials.outputs; final hasMultiDestination = outputs.length > 1; - final unlockedBalance = monero_wallet.getUnlockedBalance( - accountIndex: walletAddresses.account!.id); + final unlockedBalance = + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); PendingTransactionDescription pendingTransactionDescription; @@ -305,44 +300,35 @@ abstract class MoneroWalletBase extends WalletBase item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) { - throw MoneroTransactionCreationException( - 'You do not have enough XMR to send this amount.'); + if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) { + throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.'); } - final int totalAmount = outputs.fold( - 0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)); + 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.'); + throw MoneroTransactionCreationException('You do not have enough XMR to send this amount.'); } - if (inputs.isEmpty) MoneroTransactionCreationException( - 'No inputs selected'); + if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected'); final moneroOutputs = outputs.map((output) { - final outputAddress = - output.isParsedAddress ? output.extractedAddress : output.address; + final outputAddress = output.isParsedAddress ? output.extractedAddress : output.address; return MoneroOutput( - address: outputAddress!, - amount: output.cryptoAmount!.replaceAll(',', '.')); + address: outputAddress!, amount: output.cryptoAmount!.replaceAll(',', '.')); }).toList(); - pendingTransactionDescription = - await transaction_history.createTransactionMultDest( - outputs: moneroOutputs, - priorityRaw: _credentials.priority.serialize(), - accountIndex: walletAddresses.account!.id, - preferredInputs: inputs); + pendingTransactionDescription = await transaction_history.createTransactionMultDest( + outputs: moneroOutputs, + priorityRaw: _credentials.priority.serialize(), + accountIndex: walletAddresses.account!.id, + preferredInputs: inputs); } else { final output = outputs.first; - final address = - output.isParsedAddress ? output.extractedAddress : output.address; - final amount = - output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.'); + final address = output.isParsedAddress ? output.extractedAddress : output.address; + final amount = output.sendAll ? null : output.cryptoAmount!.replaceAll(',', '.'); // if ((formattedAmount != null && unlockedBalance < formattedAmount) || // (formattedAmount == null && unlockedBalance <= 0)) { @@ -352,15 +338,13 @@ abstract class MoneroWalletBase extends WalletBase changePassword(String password) async => - monero_wallet.setPasswordSync(password); + Future changePassword(String password) async => monero_wallet.setPasswordSync(password); Future getNodeHeight() async => monero_wallet.getNodeHeight(); @@ -517,7 +496,8 @@ abstract class MoneroWalletBase extends WalletBase _refreshUnspentCoinsInfo() async { try { final List keys = []; - final currentWalletUnspentCoins = unspentCoinsInfo.values.where( - (element) => - element.walletId.contains(id) && - element.accountIndex == walletAddresses.account!.id); + final currentWalletUnspentCoins = unspentCoinsInfo.values.where((element) => + element.walletId.contains(id) && element.accountIndex == walletAddresses.account!.id); if (currentWalletUnspentCoins.isNotEmpty) { currentWalletUnspentCoins.forEach((element) { - final existUnspentCoins = unspentCoins - .where((coin) => element.keyImage!.contains(coin.keyImage!)); + final existUnspentCoins = + unspentCoins.where((coin) => element.keyImage!.contains(coin.keyImage!)); if (existUnspentCoins.isEmpty) { keys.add(element.key); @@ -615,15 +593,13 @@ abstract class MoneroWalletBase extends WalletBase - monero_wallet.getAddress( - accountIndex: accountIndex, addressIndex: addressIndex); + monero_wallet.getAddress(accountIndex: accountIndex, addressIndex: addressIndex); @override Future> fetchTransactions() async { transaction_history.refreshTransactions(); return (await _getAllTransactionsOfAccount(walletAddresses.account?.id)) - .fold>( - {}, + .fold>({}, (Map acc, MoneroTransactionInfo tx) { acc[tx.id] = tx; return acc; @@ -652,15 +628,12 @@ abstract class MoneroWalletBase extends WalletBase> _getAllTransactionsOfAccount(int? accountIndex) async => - (await transaction_history - .getAllTransactions()) + (await transaction_history.getAllTransactions()) .map( (row) => MoneroTransactionInfo( row.hash, row.blockheight, - row.isSpend - ? TransactionDirection.outgoing - : TransactionDirection.incoming, + row.isSpend ? TransactionDirection.outgoing : TransactionDirection.incoming, row.timeStamp, row.isPending, row.amount, @@ -709,8 +682,7 @@ abstract class MoneroWalletBase extends WalletBase _askForUpdateTransactionHistory() async => - await updateTransactions(); + Future _askForUpdateTransactionHistory() async => await updateTransactions(); - int _getUnlockedBalance() => monero_wallet.getUnlockedBalance( - accountIndex: walletAddresses.account!.id); + int _getUnlockedBalance() => + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); int _getFrozenBalance() { var frozenBalance = 0; @@ -829,8 +797,7 @@ abstract class MoneroWalletBase extends WalletBase