show a transaction tab confirmation indicator correctly when its tab opens at six confirmations or a reorg takes it back below
What changed, and why it matters
This commit fixes a UI display bug in Sparrow Wallet's transaction confirmation indicator. Previously, if a transaction tab opened when a transaction already had six or more confirmations, the little progress/tick icon would not draw correctly. It also now handles the rare case of a blockchain reorganization (reorg) reducing confirmations back below six, restoring the progress circle instead of leaving a tick. There is no indication this affects funds, private keys, or transaction signing.
No security action required; this is a cosmetic UI fix. Users may update at their convenience if they want the confirmation icon to display correctly.
Security signals we found
UI state inconsistency fixed for confirmation indicator
Reorg handling added for confirmation count decreasing below threshold
No cryptographic, networking, or wallet-seed logic modified
Evidence from the diff
The patch updates ConfirmationProgressIndicator to initialize its arc and tick lines to the ‘confirmed’ end-state when confirmations are already >= BLOCKS_TO_CONFIRM (6), and to reset to the progress-circle state if a reorg drops confirmations below that threshold. It also stops any running confirmation animation before starting a new one. HeadersController is changed to use blockTransaction.getConfirmations(currentHeight) rather than an inline calculation, likely for consistency. The drongo submodule is bumped to a newer commit. The changes are purely presentational UI logic.
Changed components
Sparrow Wallet desktop UIConfirmationProgressIndicator.javaHeadersController.javadrongo submoduleInspect captured patch +33 / −2
### drongo
@@ -1 +1 @@
-Subproject commit c0333df629682472925279de60b6c172ab3290ac
+Subproject commit eb3cf3e577265165875b70de60d5333f827e279e
### src/main/java/com/sparrowwallet/sparrow/control/ConfirmationProgressIndicator.java
@@ -18,6 +18,7 @@ public class ConfirmationProgressIndicator extends StackPane {
private final Arc arc;
private final Line downTickLine;
private final Line upTickLine;
+ private SequentialTransition confirmationSequence;
public ConfirmationProgressIndicator(int confirmations) {
Circle circle = new Circle(7, 7, 7);
@@ -37,6 +38,18 @@ public ConfirmationProgressIndicator(int confirmations) {
upTickLine.setOpacity(0);
upTickLine.getStyleClass().add("confirmation-progress-tick");
+ if(confirmations >= BlockTransactionHash.BLOCKS_TO_CONFIRM) {
+ //A transaction already confirmed when shown is drawn as the tick the confirming animation ends with
+ arc.setRadiusX(0);
+ arc.setRadiusY(0);
+ downTickLine.setEndX(6);
+ downTickLine.setEndY(10);
+ downTickLine.setOpacity(1);
+ upTickLine.setEndX(10);
+ upTickLine.setEndY(4);
+ upTickLine.setOpacity(1);
+ }
+
confirmationGroup = new Group(circle, arc, downTickLine, upTickLine);
getStyleClass().add("confirmation-progress");
@@ -46,7 +59,25 @@ public ConfirmationProgressIndicator(int confirmations) {
confirmationsProperty().set(confirmations);
confirmationsProperty().addListener((observable, oldValue, newValue) -> {
if(!oldValue.equals(newValue)) {
+ if(confirmationSequence != null) {
+ confirmationSequence.stop();
+ }
+
+ if(newValue.intValue() < BlockTransactionHash.BLOCKS_TO_CONFIRM) {
+ //A reorg can return a confirmed transaction below the threshold, so restore the progress circle in place of the tick
+ arc.setRadiusX(7);
+ arc.setRadiusY(7);
+ downTickLine.setOpacity(0);
+ downTickLine.setEndX(4);
+ downTickLine.setEndY(8);
+ upTickLine.setOpacity(0);
+ upTickLine.setEndX(6);
+ upTickLine.setEndY(10);
+ confirmationGroup.setOpacity(1.0);
+ }
+
SequentialTransition sequence = new SequentialTransition();
+ confirmationSequence = sequence;
Timeline arcLengthTimeline = new Timeline();
KeyValue arcLengthValue = new KeyValue(arc.lengthProperty(), getDegrees(newValue.intValue()));
### src/main/java/com/sparrowwallet/sparrow/transaction/HeadersController.java
@@ -886,7 +886,7 @@ private void updateBlockchainForm(BlockTransaction reportedTransaction, Integer
} else if(currentHeight == null) {
blockStatus.setText(blockTransaction.getHeight() > 0 ? "Confirmed" : "Unconfirmed");
} else {
- int confirmations = blockTransaction.getHeight() > 0 ? currentHeight - blockTransaction.getHeight() + 1 : 0;
+ int confirmations = blockTransaction.getConfirmations(currentHeight);
if(confirmations == 0) {
blockStatus.setText("Unconfirmed");
} else if(confirmations == 1) {Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.