Add touch-friendly SeedQR transcription viewer - #369
Open
schnuartz-ai wants to merge 1 commit into
Open
Conversation
Selecting Standard SeedQR (digits) or Compact SeedQR (binary) from the mnemonic export menu now opens a dedicated overview screen: the complete QR code, split into labeled sections (matching SeedSigner's SeedQR transcription workflow), with a coordinate axis (row letters / column numbers) around it. Tapping a section opens it hugely enlarged, with crisp square modules, visible grid lines, and Left/Right/Up/Down navigation to neighboring sections -- making it practical to copy a SeedQR onto paper or a metal backup plate by hand. - src/seedqr.py: pure matrix/geometry helpers (no lvgl dependency), so section geometry, touch-to-section mapping, and navigation logic are unit-testable without a display or firmware build. - src/gui/screens/seedqr.py: the two new screens (SeedQROverviewScreen, SeedQRZoomScreen) and the overview<->zoom navigation loop. - src/keystore/ram.py: routes Standard/Compact SeedQR selections to the new viewer; Plaintext QR export is unchanged except it's now marked sensitive so it stops being logged in the simulator. - src/gui/components/qrcode.py, gui/common.py, gui/screens/qralert.py: add a `sensitive` flag and remove an unconditional print() that leaked QR contents (including on real hardware, not just the simulator). - test/tests_native/test_seedqr.py: encoding, section geometry, touch mapping, navigation, and security-regression tests (41 total) for the pure logic module. The corresponding fix to the f469-disco submodule's qrcode usermod (a pre-existing bug where compact/binary QR payloads could read past their buffer into uninitialized stack memory) is proposed separately at diybitcoinhardware/f469-disco#43, since this repo has no write access to that submodule's upstream. Once that merges, the f469-disco submodule pointer here should be bumped in a follow-up commit.
✅ Deploy Preview for specter-diy-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements a guided, zone-based SeedQR transcription viewer, adapted from
SeedSigner's SeedQR transcription workflow to Specter DIY's 480x800
touchscreen (see SeedSigner's
docs/seed_qr/README.mdfor the reference UX).Selecting SeedQR (digits) or Compact SeedQR (binary) from the
mnemonic export menu now opens a dedicated overview screen: the complete
QR code, split into labeled sections, with a coordinate axis (row letters
/ column numbers) around it and a "Tap a section to enlarge" hint. Tapping
a section opens it hugely enlarged, with crisp square modules, visible
grid lines, and Left/Right/Up/Down navigation to neighboring sections —
making it practical to copy a SeedQR onto paper or a metal backup plate by
hand. Returning to the overview preserves the section you were last
looking at. Plaintext QR export is unchanged.
(I'll attach a few simulator screenshots to this description separately.)
Design
src/seedqr.py: pure matrix/geometry helpers (matrix generation +validation, section geometry, touch-to-section mapping, navigation) with
no lvgl dependency, so this logic is unit-testable on a desktop
Python interpreter without a display or firmware build.
src/gui/screens/seedqr.py:SeedQROverviewScreen+SeedQRZoomScreen,and the
show_seedqr()overview<->zoom navigation loop. Both screensrender the same canonical module matrix (generated once via
seedqr.generate_matrix()), so the overview and every zoomed sectioncan never disagree about module data.
src/keystore/ram.py: routes the Standard/Compact SeedQR menu choicesto
show_seedqr(); the Plaintext QR path is unchanged except it nowpasses
sensitive=True.sections (3x3 grid); every larger SeedQR size groups into 5x5-module
sections. A non-square-divisible size (e.g. 29x29) has a smaller
trailing row/column, which is rendered at its true, smaller size (not
padded out with filler modules).
Security
This handles wallet recovery material, so:
module matrix are never printed, logged, or persisted.
gui/components/qrcode.pyI found a pre-existingunconditional
print(text)that logged the full QR payload even onreal hardware, not just the simulator. Removed it, and added a
sensitiveflag (threaded throughadd_qrcode/QRAlert) so simulatordebug logging can be suppressed per-QR; it's now set for every
mnemonic-related QR, including the pre-existing Plaintext export path.
DELETE.Companion fix (separate repo)
While building the matrix-generation helper I found a pre-existing bug in
the
f469-discosubmodule'sqrcodeusermod:_qrcode_encode()decidedtext-vs-binary mode by scanning for an embedded
0x00byte, so abytespayload with no zero byte (common for Compact SeedQR's raw entropy) fell
through to
qrcodegen_encodeText(), which expects a NUL-terminated stringand could read past the intended data into uninitialized stack memory.
Fixed at diybitcoinhardware/f469-disco#43 (using the actual Python object
type instead of content-sniffing). I don't have write access to that
repo's upstream, so it's a separate PR; the
f469-discosubmodule pointerin this PR is unchanged (still upstream's commit) — once #43 merges,
the submodule pointer here should be bumped in a follow-up commit.
Test plan
python3 run_native_tests.py— 41/41 tests pass (encoding, sectiongeometry, touch mapping, navigation, and print/log security
regressions for the pure
seedqrmodule).python3 -m compileall src test— clean.make unix(real firmware build, including this submodule fix) —builds successfully; confirmed the compiled
qrcode.encode_to_string()produces the correct matrix size for all 4 SeedQR combinations
(12/24-word x Standard/Compact), including entropy with no embedded
zero byte.
overview, tapping into first/middle/last/partial sections, all four
nav directions, back-to-overview section
This PR implements the SeedQR transcription mode requested in #212, including the sectioned overview and enlarged grid-based navigation for copying the QR to paper or metal.
Fixes #212