fix(tx): track async operations to completion (send/shield/auto-shield)

z_sendmany returns an opid immediately; the tx is built/signed/broadcast
asynchronously afterward. The send path showed "Transaction sent successfully!"
and cleared the form on opid receipt, so a later async failure contradicted it.
Shield/merge stored the opid only in a dialog-local static (never polled), and
auto-shield ran a blocking z_shieldcoinbase on the UI thread and discarded its
opid — async failures of all three were silently lost.

- Add App::trackOperation(opid) so shield/merge/auto-shield register with the
  shared opid poller (failures surface, balances refresh on completion).
- Defer the full-node send's success/failure to the poller via per-opid callbacks
  (parseOperationStatusPoll now exposes failureByOpid); the "Sending..." spinner
  covers the finalizing window, and the form is kept until terminal status.
- Dispatch auto-shield through the worker thread and use the configured fee.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:16:48 -05:00
parent 20b22410e9
commit 1bc7f5c8cd
6 changed files with 113 additions and 28 deletions

View File

@@ -1095,6 +1095,7 @@ NetworkRefreshService::OperationStatusPollResult NetworkRefreshService::parseOpe
} catch (...) {}
}
parsed.failureMessages.push_back(msg);
parsed.failureByOpid[opid] = msg;
}
}

View File

@@ -198,6 +198,7 @@ public:
std::vector<std::string> successTxids;
std::unordered_map<std::string, std::string> successTxidsByOpid;
std::vector<std::string> failureMessages;
std::unordered_map<std::string, std::string> failureByOpid; // opid -> error message
bool anySuccess = false;
};