SFT-3834: Refine Message Signing via MicroSD#636
Conversation
format for sparrow parsing
|
Coverage gap: SignTextFileFlow is a parallel entry point that's NOT touched There are two menu entries that produce signed text files via microSD:
SignTextFileFlow.do_sign (sign_text_file_flow.py:83) goes straight from validate_file to signing with no message preview, no address confirmation. So if the goal is "user must always see the message and address before signing", this PR closes only one of the two doors. A user reaching for "Sign Text File" still sees nothing. Either:
This is the most important issue with the PR. Worth raising before merge. |
|
Also, Address is derived twice In show_message: with stash.SensitiveValues() as sv: Then sign_health_check runs sign_text_file_task, which derives the address again and writes self.address = address (overwriting). In practice both derive from the same subpath + addr_type, so they match — but:
Cleaner pattern: derive the address in the task (or in a non-sensitive way from xpub), pass it to show_message for confirmation, then sign. As-is, it's not a correctness bug, but it weakens the "WYSIWYG signing" guarantee that's the entire point of the verify step. |
There's an issue: the preview is skipped for health checks, so the address derivation during signing may be the first derivation. I made some changes to be absolutely sure there's no mismatch. "The task now always derives the address from the subpath. When expected_address is provided (message-signing path), it checks that the derived address matches what the user confirmed — if not, it short-circuits with an error before signing. Health checks pass None so the check is skipped entirely. The error message includes both addresses to make a mismatch diagnosable, though in practice this should never trigger if the flow is correct — it's a defensive assertion rather than expected user-facing error handling." |
Jacksper13
left a comment
There was a problem hiding this comment.
Canceling the new preview produces a bogus error instead of a clean cancel.
The bug: in health_check_common_flow.py:show_message (PR-introduced code), cancel sets self.set_result(False). But the caller in health_check_microsd_flow.py:common_flow (line
~68) only treats None as failure:
self.signed_message = await HealthCheckCommonFlow(self.lines, normal_signing=self.normal_signing).run()
if self.signed_message is None: # <-- False is not None, so check fails
self.set_result(False)
return
self.goto(self.write_signed_file) # <-- proceeds with signed_message = False
Then write_signed_file constructs SaveToMicroSDFlow(data=False, ...), and SaveToMicroSDFlow.check_inputs (save_to_microsd_flow.py:50) hits (not self.data and not self.write_fn)
→ True, displaying "Either data or a write function is required to save a file." to the user.
So a user who backs out of the message preview sees a confusing error instead of returning to the menu. This is a user-visible regression introduced by this PR.
Mirrors the WYSIWYG-signing assertion that microSD signing already has (added in #636). Keeps self.address raw (used as expected_address) and uses a local display_address for stylization in the preview. Co-Authored-By: Claude Opus 4.7 <[email protected]>
Restores the file-size cap that the deleted SignTextFileFlow used to provide before its consolidation in #636. Gated on normal_signing so health-check files (with their own implicit length constraints) are unaffected. Co-Authored-By: Claude Opus 4.7 <[email protected]>
format for sparrow parsing