feat: add native seedqr wallet restore - #760
Conversation
|
jvsena42
left a comment
There was a problem hiding this comment.
No HIGH or MEDIUM findings. Two LOWs inline, both checked by a second pass.
Scope note: besides SeedQR, this PR replaces CodeScanner with an in-house AVFoundation/Vision scanner that every QR flow uses (Send, main, Electrum, add contact, probing tool). That is the larger part of the change, and the first inline comment is about it.
Checked and clean:
- Standard decode. bitkit-core requires 48 digits, indices < 2048 and
validate_mnemonic. Framed Compact parsing fails closed on ECI, multi-segment and 16-bit counts. - Key material. The payload is never logged and never pasted. The scanner view holds no mnemonic and has
screenshotPreventMask(true). Back from the scanner leaves the form untouched. - Other scanners. Non-restore scanners only forward
payload.string. Binary-only payloads get the unsupported-QR toast, and payment QR handling is unchanged. - Dependencies. CodeScanner is removed, and bitkit-core goes 0.5.14 → 0.5.18 (revision matches the tag). The core delta adds the SeedQR and Jade modules and tightens
finalize_psbtsighash checks. No derivation changes. - Threading. Frame state lives on
videoQueue, and the device and torch onsessionQueue.
Non-blocking: is there a Figma frame for the new SeedQR scanner screen? Link it and I'll diff the implementation against it on the next pass.
There was a problem hiding this comment.
Delta since 0953483c (f7104855): no findings. Both LOWs are fixed.
- Scan guard.
ScannerManageris@MainActor, and theisHandlingScancheck and set happen before the first await, so two scans cannot both pass..sendinsideprocessScancallsprocessSendScan, so it cannot deadlock on its own guard. SeedQR still bypasses the manager, so an invalid SeedQR does not latch the camera. - Decoder. Compact now requires the framed header. The null-byte fixture (
0x41+ 17 ×0x00+0xEC) parses as mode 4, count 16, 16 zero bytes, and the raw 16-byte entropy is rejected bytestRejectsRawCompactEntropy.
|
QA reviewed on f710485. Since the review on 0953483, one commit. A scan is handled one at a time, and Compact decoding no longer accepts a raw 16-byte blob. Ran on iPhone 17: a 12-word Standard SeedQR and the matching Compact SeedQR filled Twin synonymdev/bitkit-android#1319: same import. System Back keeps the form. Compact needed a closer hold. Its invalid and 24-word toast is the generic QR error. That note is on the Android review. No findings. Checked and clean
QA LGTM |
|
Squashed commits |
f710485 to
1c1c83c
Compare
Description
This PR adds native SeedQR wallet restoration on iOS.
bitkit-corev0.5.18; iOS retains only camera capture and Vision-specific payload normalization.SeedQR originated in SeedSigner, but it is not limited to one product: Specter DIY independently supports both Standard and Compact SeedQR. SeedQR is not itself a BIP; it is a compact transport encoding of BIP39 word indexes or entropy. Supporting it therefore improves interoperability with existing air-gapped backup tooling without introducing a new wallet or seed derivation scheme.
Linked Issues/Tasks
Design
N/A — no design available.
Screenshot / Video
N/A — no recovery seed material was captured.
QA Notes
Manual Tests
regression:Send → scan a payment QR: the existing payment flow opens normally.regression:Restore Wallet → enter twelve words manually: manual recovery remains unchanged.The simulator has no camera input. Photo-library handling is not treated as a simulator compatibility requirement; physical-device camera tests are the authoritative checks for this feature.
Automated Checks
SeedQRCodeDecoderTests.swiftcovers Standard SeedQR, raw Compact entropy, the binary bitstream returned by Vision on a physical iPhone, null-byte entropy, invalid checksums, out-of-range indexes, and unsupported payload lengths.bitkit-corev0.5.18Swift package.bitkit-corev0.5.18at merge commitb53fa54a16f04940943072bb6e08dc2650302f93.