Skip to content

feat: add shared seedqr decoding - #155

Merged
pwltr merged 2 commits into
masterfrom
feat/seedqr-decoder
Sep 20, 2026
Merged

pwltr merged 2 commits into
masterfrom
feat/seedqr-decoder

Conversation

@pwltr

@pwltr pwltr commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Related to synonymdev/bitkit-android#1277.

Adds shared SeedQR decoding so the platform apps use one implementation for wallet restoration.

Description

  • Decode 12-word English Standard SeedQR payloads into validated BIP39 mnemonics.
  • Decode 16-byte Compact SeedQR entropy into BIP39 mnemonics.
  • Reuse the existing core BIP39 word-list, validation, and entropy conversion utilities.
  • Expose typed decoding functions and errors through UniFFI, including generated Swift bindings.
  • Keep camera capture and platform-specific barcode normalization in the applications.

The recently merged Jade integration does not overlap with this work: its air-gapped QR mode was explicitly out of scope, and neither the core Jade adapter nor jade-client-rs implements SeedQR decoding.

Preview

N/A — no UI changes.

QA Notes

Automated validation:

cargo fmt --check
cargo check
cargo clippy --all-targets
cargo test modules::seedqr
cargo test -- --skip modules::blocktank

The SeedQR suite passes 7 tests covering valid Standard and Compact payloads, null-byte entropy, invalid lengths, invalid characters, out-of-range indexes, and invalid BIP39 checksums.

A full cargo test run passed 535 tests and failed 11 existing Blocktank integration tests because requests to api.stag.blocktank.to were unavailable. The suite passes with the network-dependent Blocktank module skipped: 498 passed, 0 failed, 26 ignored.

@pwltr

pwltr commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Verified locally via synonymdev/bitkit-ios#760

@pwltr

pwltr commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator Author

Rationale and ecosystem compatibility

SeedQR is a de facto interoperability format originally documented by SeedSigner. It is not a BIP or a universally adopted wallet standard, but it is independently supported by several established signing and wallet projects:

  • COLDCARD supports Standard SeedQR import.
  • Krux supports Standard and Compact SeedQR.
  • Sparrow implements both formats.
  • SeedHammer implements both formats.
  • Blockstream Jade can export recovery seeds as SeedQR.

This makes the feature useful for wallet migration and interoperability with air-gapped signers, even though it should not be treated as evidence of broad mainstream-wallet adoption.

Keeping the decoder in bitkit-core provides one validated implementation for Android and iOS, prevents platform-specific interpretations of the format, and reuses core’s existing BIP39 word-list, checksum-validation, and entropy-conversion code. Camera capture and platform-specific barcode normalization remain application responsibilities.

The implementation is intentionally narrow:

  • 12-word English BIP39 restoration only.
  • Standard and Compact SeedQR decoding.
  • No QR generation or export.
  • No seed persistence, networking, or logging.
  • No dependency on the Jade integration or other hardware-wallet modules.

The complete iOS consumer path was also verified on a physical device: both Standard and Compact SeedQR payloads decoded through the locally built core XCFramework and populated the wallet restoration screen’s 12 seed-word fields.

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ✅ Approve


Review: diff 8 files.

Findings:
1 inline (non-blocking)

Audit:
Audited - no findings.

Coverage:
Unit tests: 88% - Seven added tests cover both successful decoders and every malformed-input branch except Standard payload length.


Reviewed by gpt-5.6-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest · audit (author or owner)

Comment thread src/modules/seedqr/tests.rs

@ovitrif ovitrif left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utAck

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: ✅ Approve


Reaudit: diff 1 file.

Findings:
N/A

Audit:
Already done in comment.

Coverage:
Unit tests: 100% - The added 47- and 49-digit cases cover both sides of the Standard SeedQR exact-length guard.


Reviewed by gpt-5.6-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest · audit (author or owner)

@pwltr
pwltr merged commit 59eb4cf into master Sep 20, 2026
4 checks passed
@pwltr
pwltr deleted the feat/seedqr-decoder branch September 20, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants