CW-873 automatically export outputs (#1885)

* automatically export outputs * remove print statements * update configure script * Update logic behind import/export keyimages/outputs * discussed changes * replace store with just waiting for the wallet to update it's state

cyan committed Jan 4, 2025 at 05:28 UTC da9c30980581c470e6f06ac4616a51ed9e7ae82b
5 files changed +35 -2
cw_monero/lib/api/wallet.dart
+4 -2
@@ -126,8 +126,10 @@ Future<bool> setupNodeSync(
126
127 if (status != 0) {
128 final error = monero.Wallet_errorString(wptr!);
129 - printV("error: $error");
130 - throw SetupWalletException(message: error);
129 + if (error != "no tx keys found for this txid") {
130 + printV("error: $error");
131 + throw SetupWalletException(message: error);
132 + }
133 }
134
135 if (kDebugMode) {
cw_monero/lib/monero_wallet.dart
+8
@@ -265,6 +265,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
265 return str;
266 }
267
268 + bool needExportOutputs(int amount) {
269 + // viewOnlyBalance - balance that we can spend
270 + // TODO(mrcyjanek): remove hasUnknownKeyImages when we cleanup coin control
271 + return (monero.Wallet_viewOnlyBalance(wptr!,
272 + accountIndex: walletAddresses.account!.id) < amount) ||
273 + monero.Wallet_hasUnknownKeyImages(wptr!);
274 + }
275 +
276 @override
277 Future<PendingTransaction> createTransaction(Object credentials) async {
278 final _credentials = credentials as MoneroTransactionCreationCredentials;
lib/monero/cw_monero.dart
+6
@@ -391,6 +391,12 @@ class CWMonero extends Monero {
391 return moneroWallet.exportOutputsUR(all);
392 }
393
394 + @override
395 + bool needExportOutputs(Object wallet, int amount) {
396 + final moneroWallet = wallet as MoneroWallet;
397 + return moneroWallet.needExportOutputs(amount);
398 + }
399 +
400 @override
401 void monerocCheck() {
402 checkIfMoneroCIsFine();
lib/src/screens/send/send_page.dart
+15
@@ -4,6 +4,7 @@ import 'package:cake_wallet/entities/contact_record.dart';
4 import 'package:cake_wallet/core/execution_state.dart';
5 import 'package:cake_wallet/entities/fiat_currency.dart';
6 import 'package:cake_wallet/entities/template.dart';
7 +import 'package:cake_wallet/monero/monero.dart';
8 import 'package:cake_wallet/reactions/wallet_connect.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10 import 'package:cake_wallet/routes.dart';
@@ -412,6 +413,20 @@ class SendPage extends BasePage {
413 }
414 }
415
416 + if (sendViewModel.wallet.type == WalletType.monero) {
417 + int amount = 0;
418 + for (var item in sendViewModel.outputs) {
419 + amount += item.formattedCryptoAmount;
420 + }
421 + if (monero!.needExportOutputs(sendViewModel.wallet, amount)) {
422 + await Navigator.of(context).pushNamed(Routes.urqrAnimatedPage, arguments: 'export-outputs');
423 + await Future.delayed(Duration(seconds: 1)); // wait for monero to refresh the state
424 + }
425 + if (monero!.needExportOutputs(sendViewModel.wallet, amount)) {
426 + return;
427 + }
428 + }
429 +
430 final check = sendViewModel.shouldDisplayTotp();
431 authService.authenticateAction(
432 context,
tool/configure.dart
+2
@@ -387,6 +387,8 @@ abstract class Monero {
387
388 String exportOutputsUR(Object wallet, bool all);
389
390 + bool needExportOutputs(Object wallet, int amount);
391 +
392 bool importKeyImagesUR(Object wallet, String ur);
393
394 WalletCredentials createMoneroRestoreWalletFromKeysCredentials({