Fix: PSBT Scan via Camera was not closing the modal dialog when signing a multisig transaction (#7089)
What changed, and why it matters
This is a small user-interface bug fix. When a user scanned a QR code with their camera to provide a PSBT (a partially signed Bitcoin transaction), the on-screen modal dialog failed to close for multisig transactions because the JavaScript was clicking the wrong button. The patch makes the code click the correct button so the modal closes as expected. There is no security vulnerability here.
No security action needed. Treat as a normal UI bug fix.
Security signals we found
No strong security signals were identified.
Evidence from the diff
In WalletPSBTDecoded.cshtml, the camera-scan success callback previously called document.getElementById(“Decode”).click(). For multisig transactions with a pending transaction id, the visible submit button is id=”Collect” (command=collect), not id=”Decode” (command=decode), so the hardcoded click target did not exist or did not perform the expected action, leaving the scan modal open. The fix adds a shared CSS class camera-submit to both the Collect and Decode buttons and changes the JavaScript to click the first element with that class. This is a DOM targeting correction, not a security control change.
Changed components
BTCPayServer/Views/UIWallets/WalletPSBTDecoded.cshtmlInspect captured patch +3 / −3
diff --git a/BTCPayServer/Views/UIWallets/WalletPSBTDecoded.cshtml b/BTCPayServer/Views/UIWallets/WalletPSBTDecoded.cshtml
index bfb3d5b..edbb6bb 100644
--- a/BTCPayServer/Views/UIWallets/WalletPSBTDecoded.cshtml
+++ b/BTCPayServer/Views/UIWallets/WalletPSBTDecoded.cshtml
@@ -70,7 +70,7 @@
hex = data;
}
document.getElementById("ImportedPSBT").value = hex;
- document.getElementById("Decode").click();
+ document.getElementsByClassName("camera-submit")[0].click();
}, "scanModal");
});
</script>
@@ -215,11 +215,11 @@ else
<div class="d-flex flex-column flex-sm-row flex-wrap align-items-sm-center">
@if (this.Model.SigningContext.PendingTransactionId is not null)
{
- <button type="submit" name="command" value="collect" class="btn btn-primary mb-3 mb-sm-0 me-sm-2" id="Collect" text-translate="true">Collect signatures</button>
+ <button type="submit" name="command" value="collect" class="btn btn-primary mb-3 mb-sm-0 me-sm-2 camera-submit" id="Collect" text-translate="true">Collect signatures</button>
}
else
{
- <button type="submit" name="command" value="decode" class="btn btn-primary mb-3 mb-sm-0 me-sm-2" id="Decode" text-translate="true">Decode PSBT</button>
+ <button type="submit" name="command" value="decode" class="btn btn-primary mb-3 mb-sm-0 me-sm-2 camera-submit" id="Decode" text-translate="true">Decode PSBT</button>
}
<button type="button" id="scanqrcode" class="btn btn-primary only-for-js" data-bs-toggle="modal" data-bs-target="#scanModal" text-translate="true">Scan wallet QR with camera</button>
</div>
Why this scored 18/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.