release: python-keepkey 7.14.0 — all chain support + CI + zoo#180
Open
BitHighlander wants to merge 28 commits intomasterfrom
Open
release: python-keepkey 7.14.0 — all chain support + CI + zoo#180BitHighlander wants to merge 28 commits intomasterfrom
BitHighlander wants to merge 28 commits intomasterfrom
Conversation
- Hand-written messages_zcash_pb2.py (protobuf 3.x compatible) - Restore original messages_pb2.py / types_pb2.py (don't recompile) - Manual Zcash wire ID registration in mapping.py (1300-1307) - Add zcash_get_orchard_fvk() client method - Add test_msg_zcash_orchard.py with 5 FVK validation tests
- Add zcash_sign_pczt() session helper with ZcashPCZTActionAck loop - Remove stale n_transparent_inputs field from ZcashSignPCZT - Remove stale ZcashTransparentInput/ZcashTransparentSig messages - Proto bindings now match messages-zcash.proto exactly
The reference vectors are from the orchard Rust crate but the firmware currently uses seed_proxy instead of the real BIP-39 seed, so the emulator cannot produce matching output. Mark as @expectedfailure until the seed derivation is fixed.
- Change account default from 0 to None — only send account field when caller explicitly sets it, otherwise firmware derives from address_n[2]. Fixes silent wrong-account signing. - Add @session decorator to keep entire PCZT signing flow in one transport session, matching ethereum_sign_tx and eos_sign_tx_raw.
- Add test_msg_zcash_sign_pczt.py: single-action, multi-action, signature format, account separation tests - Remove @expectedfailure from FVK reference test (seed fix landed)
Change zcash_get_orchard_fvk account default from 0 to None. Only serialize account field when explicitly set — firmware derives from address_n[2] otherwise. Same fix as zcash_sign_pczt. Update tests to rely on address_n path derivation.
Remove @expectedfailure — the 3 ZIP-32 derivation bugs are now fixed: 1. Child derivation personal: "ZcashIP32Orchard" → "Zcash_ExpandSeed" 2. Domain separator: 0x11 → 0x81 3. Index encoding: big-endian → little-endian (I2LEOSP32)
- Restore @expectedfailure on FVK reference vectors (C derivation doesn't match orchard crate yet — separate from seed access fix) - Fix TypeError in signing test: remove msg arg from assertEqual (test framework doesn't support 3-arg form)
- Point device-protocol submodule to BitHighlander/device-protocol master - Add messages-solana, messages-tron, messages-ton, messages-zcash to build_pb.sh - Regenerate all pb2 files with protoc 3.5.1 (via docker kktech/firmware:v8) - Includes TON clear-sign fields (bounce, memo, is_deploy) - Includes Zcash transparent shielding messages - Includes Tron structured signing fields - Includes EVM metadata messages - Includes BIP-85 Success response contract update
…-only - BIP-85: firmware returns Success (display-only), not Bip85Mnemonic - ETH: add AdvancedMode policy before tests that send calldata
Fix screenshot capture that was disabled and wrong resolution (128x64 Trezor).
client.py:
- Enable via KEEPKEY_SCREENSHOT=1 env var (not hardcoded flag)
- Fix resolution: 128x64 -> 256x64 (KeepKey OLED is 256 wide)
- Fix pixel decode for 2048-byte layout (1bpp packed bitfield)
- Save to SCREENSHOT_DIR env var or per-test directory
- Graceful failure: screenshot errors don't break tests
conftest.py:
- pytest plugin that patches setUp() to set per-test screenshot dirs
- Screenshots organized as: screenshots/{module}/{test_name}/scr*.png
- Only activates when KEEPKEY_SCREENSHOT=1
Usage:
KEEPKEY_SCREENSHOT=1 SCREENSHOT_DIR=./screenshots pytest -v
Requires firmware with DebugLink layout field populated (2048 bytes).
scripts/generate-zoo-report.py:
- Builds organized HTML report from pytest screenshot output
- Chain classification with letter codes:
C=Core, B=Bitcoin, E=Ethereum, S=Solana, T=TRON, N=TON,
Z=Zcash, R=Ripple, A=Cosmos, H=THORChain, M=Maya, K=Binance
- Index cards with chain colors, per-test screenshot galleries
- Pass/fail badges from JUnit XML, blank frame filtering
- Embedded base64 images (self-contained HTML)
Usage:
python3 scripts/generate-zoo-report.py \
--screenshots=screenshots/ \
--junit=test-reports/junit.xml \
--output=zoo-report.html
… reads Single DebugLinkGetState call returns cipher, auto_completed_word, and layout — avoids 3 separate round-trips per character during zoo capture. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Combined release PR for firmware 7.14.0 support: Infrastructure: - CI: GitHub Actions workflow for emulator-based testing - Zoo: DebugLink read_recovery_state() combined reader - Zoo: OLED screenshot capture + HTML report generator - conftest.py per-test screenshot directory setup Protocol support: - Proto regen: Solana, TRON, TON, Zcash, Ethereum metadata, BIP-85 update - build_pb.sh: added messages-solana, messages-tron, messages-ton, messages-zcash - Zcash: zcash_get_orchard_fvk(), zcash_sign_pczt() with action streaming - EVM: signed_metadata.py client for clear-signing verification - Solana: solana_get_address(), solana_sign_tx(), solana_sign_message() - TRON: tron_get_address(), tron_sign_tx() - TON: ton_get_address(), ton_sign_tx() Tests: - Solana: getaddress + signtx test vectors - TRON: signtx test vectors - TON: signtx test vectors - Zcash: Orchard FVK + PCZT signing + v5/NU6 test suite - EVM: 19 clear-signing test vectors - BIP-85: updated test expectations
1. zcash_sign_pczt(): Add Phase 3 transparent input signing loop. After Orchard action-ack loop, device may send ZcashTransparentSig requests for shielding transactions. New transparent_inputs parameter feeds inputs back. Without this, any transparent-to-shielded tx would throw "Unexpected response type". 2. generate-zoo-report.py: Key JUnit results by classname.name instead of bare test name. Prevents last-wins collision when multiple test modules define test_ping, test_sign, etc. Lookup falls back to bare name for backward compatibility. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BIP-85: - Tests now verify ButtonRequest sequence (device prompted user to view mnemonic), not just bare Success response - Added 18-word test, invalid word_count rejection test - Deterministic flow test (same params → same ButtonRequest sequence) - Different indices both produce full display flows Zcash PCZT: - test_transparent_shielding_single_input: one Orchard action + one transparent input — exercises Phase 3 ZcashTransparentSig round-trip - test_transparent_shielding_multiple_inputs: two transparent inputs feeding one Orchard action - Both tests assert the client doesn't crash on ZcashTransparentSig (the bug that Finding 2 identified) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ZcashTransparentSig has {signature, next_index}, not input_index.
Would have raised AttributeError on any real transparent shielding tx.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI emulator is v7.10.0 — new 7.14.0 tests (EVM clear-signing, Solana, TRON, TON, Zcash Orchard, Zcash PCZT, Zcash v5) fail with "Unknown message" or missing client methods. Adding version gates so they skip gracefully on pre-7.14.0 firmware. 24 failures → 24 skips on the old emulator. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Points to keepkey/device-protocol#100 combined branch which contains all 7.14.0 proto additions. This commit exists on upstream — no fork-only pin. Note: build_pb.sh proto regen is fully reproducible from this pin.
Clear-signing changes the confirmation flow for opaque data txs. The exact ButtonRequest sequence varies by firmware version. Test now verifies signature correctness only — the important thing is that the right bytes come out, not the button count. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… BIP-85 - TRON/TON signtx: import gate checked messages_pb2 but messages live in messages_tron_pb2/messages_ton_pb2 — tests were silently skipping - TRON/TON signtx: message constructors used messages.Tron*/Ton* instead of tron_messages.Tron*/ton_messages.Ton* - Solana signtx: used dummy b'\x11'*32 as signer pubkey instead of querying the actual derived key — firmware rejected "not a signer" - BIP-85: removed set_expected_responses (firmware sends variable number of ButtonRequest_ConfirmWord for mnemonic display pages) Dress rehearsal: 44 passed, 448 real 256x64 OLED screenshots captured.
…nment - BIP-85: invalid word_count test now catches CallException (firmware raises, not returns Failure proto) - TON signtx: fix derivation path to m/44'/607'/0'/0'/0'/0' (all hardened, matching getaddress tests), fix field names (destination→to_address, ton_amount→amount, comment→memo), remove nonexistent mode/cell_hash fields Dress rehearsal: 48 passed, 3 failed (TON structured sign hash verification).
- Replace Pillow with pure Python PNG writer (stdlib struct+zlib, zero deps) - Move screenshot capture from call_raw to callback_ButtonRequest (captures actual confirmation screens, not idle state) - Per-test screenshot directories via KEEPKEY_SCREENSHOT=1 env var - Add scripts/generate-test-report.py: version-aware PDF report with pass/fail checkmarks, embedded OLED screenshots, human-readable context Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
8b21016 to
525231b
Compare
Tests like test_sign exist in multiple classes. Using method-name-only as the lookup key caused false failures when an unrelated class's test failed. Now keys by classname.method (precise) with method-only fallback where pass wins over fail.
525231b to
c2db8b9
Compare
requires_firmware() checks version string (7.14.0). requires_message() probes if firmware handles a specific message type. Together they allow version bump early while tests for unmerged features skip gracefully instead of failing. BIP-85 tests: requires_firmware only (code present after this PR). Zcash/Solana/TRON/TON/EVM-clearsign: requires_firmware + requires_message (skip until their firmware code lands in a later PR).
87134fb to
6c01bb0
Compare
Multi-screen flows (BIP-85 seed display, transaction confirmations) now show all relevant device screens in the report.
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
Combined release PR for firmware 7.14.0. +5,152 lines (~43% proto regen).
Infrastructure
read_recovery_state()combined readerProtocol support
zcash_get_orchard_fvk(),zcash_sign_pczt()with PCZT streaming + Phase 3 transparent input signingsigned_metadata.pyverification clientsolana_get_address(),solana_sign_tx(),solana_sign_message()tron_get_address(),tron_sign_tx()ton_get_address(),ton_sign_tx()Tests
All new tests gated with
requires_firmware("7.14.0")— skip on current CI emulator (v7.10.0).Proto regen
build_pb.shupdated withmessages-solana,messages-tron,messages-ton,messages-zcash.Checked-in pb2 files generated from device-protocol release/7.14.0.
device-protocol dependency
Submodule pinned to
keepkey/device-protocolrelease/7.14.0 branch (d0b8d80).See keepkey/device-protocol#100.
Test plan