warn on loading transactions with non-zero outputs of unknown script type
What changed, and why it matters
This commit adds a warning when a user tries to load a Bitcoin transaction that sends money to an unusual or unrecognised address/script type. Previously, Sparrow would silently open such transactions and not show those outputs in its visual transaction diagram, which could mislead a user into signing or broadcasting a transaction without realising where some funds were going. Now the user is warned and asked whether to proceed.
Users should upgrade to the version containing this commit to benefit from the warning. When loading unfamiliar transactions, review all outputs in the transaction tree before signing or broadcasting, especially when the new warning appears.
Security signals we found
UI spoofing / information hiding risk mitigated
Transaction output visibility gap addressed
User consent added before handling non-standard scripts
No cryptographic or consensus-layer change
Evidence from the diff
The change in AppController.java inserts a check before opening a transaction. If the transaction is not already confirmed/inspected (blockTransaction == null), it scans outputs for any with value > 0 whose script cannot be resolved to an address (getToAddress() == null). If any exist, it shows a warning dialog listing the count and total amount, explaining that these outputs won’t appear in the transaction diagram, and only proceeds if the user clicks YES. This is a UI/UX hardening change, not a cryptographic fix.
Changed components
src/main/java/com/sparrowwallet/sparrow/AppController.javaTransaction loading/opening flowUnknown/non-standard script output handlingInspect captured patch +26 / −0
diff --git a/src/main/java/com/sparrowwallet/sparrow/AppController.java b/src/main/java/com/sparrowwallet/sparrow/AppController.java
index 2288e60..5c8d4b6 100644
--- a/src/main/java/com/sparrowwallet/sparrow/AppController.java
+++ b/src/main/java/com/sparrowwallet/sparrow/AppController.java
@@ -2060,6 +2060,15 @@ public class AppController implements Initializable {
}
}
+ //Skip the warning for already-confirmed transactions loaded for inspection
+ if(blockTransaction == null) {
+ List<TransactionOutput> unknownScriptOutputs = transaction.getOutputs().stream()
+ .filter(o -> o.getValue() > 0 && o.getScript().getToAddress() == null).toList();
+ if(!unknownScriptOutputs.isEmpty() && !confirmUnknownScriptOutputs(unknownScriptOutputs)) {
+ return;
+ }
+ }
+
try {
String tabName = name;
@@ -2164,6 +2173,23 @@ public class AppController implements Initializable {
return result.isPresent() && result.get() == ButtonType.YES;
}
+ private boolean confirmUnknownScriptOutputs(List<TransactionOutput> unknownScriptOutputs) {
+ long totalAmount = unknownScriptOutputs.stream().mapToLong(TransactionOutput::getValue).sum();
+ UnitFormat format = Config.get().getUnitFormat() == null ? UnitFormat.DOT : Config.get().getUnitFormat();
+ BitcoinUnit unit = Config.get().getBitcoinUnit();
+ if(unit == null || unit.equals(BitcoinUnit.AUTO)) {
+ unit = totalAmount >= BitcoinUnit.getAutoThreshold() ? BitcoinUnit.BTC : BitcoinUnit.SATOSHIS;
+ }
+ String amount = unit.equals(BitcoinUnit.BTC) ? format.formatBtcValue(totalAmount) + " BTC" : format.formatSatsValue(totalAmount) + " sats";
+ String outputDesc = unknownScriptOutputs.size() == 1 ? "an output" : unknownScriptOutputs.size() + " outputs";
+ Optional<ButtonType> result = AppServices.showWarningDialog("Unknown Script Type",
+ "This transaction contains " + outputDesc + " of a non-standard or unrecognised script type, totalling " + amount + ".\n\n" +
+ "Sparrow cannot resolve these outputs to addresses, so they will not appear in the transaction diagram. " +
+ "Review the individual output(s) in the transaction tree carefully before signing or broadcasting.\n\n" +
+ "Open the transaction?", ButtonType.YES, ButtonType.NO);
+ return result.isPresent() && result.get() == ButtonType.YES;
+ }
+
private String getTabName(Tab tab) {
return ((Label)tab.getGraphic()).getText();
}
Why this scored 40/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.