Skip to content

feat: EVM clear-signing support (firmware 7.14+)#32

Merged
BitHighlander merged 2 commits intomasterfrom
feature/evm-clearsign
Mar 21, 2026
Merged

feat: EVM clear-signing support (firmware 7.14+)#32
BitHighlander merged 2 commits intomasterfrom
feature/evm-clearsign

Conversation

@BitHighlander
Copy link
Collaborator

Summary

  • Add EthereumTxMetadata (message type 115) and EthereumMetadataAck (message type 116) protobuf shim classes
  • Send signed metadata blob to device BEFORE EthereumSignTx when txMetadata is provided
  • Device OLED displays decoded contract call info instead of raw hex
  • Graceful fallback to blind signing on older firmware

Protocol Flow

1. Host → EthereumTxMetadata(signed_payload, key_id)
2. Device → EthereumMetadataAck(classification: 0=OPAQUE | 1=VERIFIED | 2=MALFORMED)
3. Host → EthereumSignTx (normal flow)
4. Device OLED shows decoded info if classification=VERIFIED

Changes

  • hdwallet-core/src/ethereum.ts: Added optional txMetadata field to ETHSignTx type
  • hdwallet-keepkey/src/ethereum.ts: Hand-rolled jspb.Message classes for msg 115/116, registered in type registry, integrated into ethSignTx() flow

Test plan

  • Uniswap V2 swap with Pioneer metadata blob — device shows decoded method
  • ERC-20 transfer without metadata — backward-compatible blind signing
  • Old firmware without msg 115 — graceful fallback, no crash
  • Simple ETH transfer (no calldata) — unchanged behavior

@vercel
Copy link

vercel bot commented Mar 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hdwallet-sandbox Ready Ready Preview, Comment Mar 21, 2026 4:49am

Request Review

Add support for firmware 7.14+ EVM clear-signing protocol:
- EthereumTxMetadata (msg 115): sends signed metadata blob BEFORE EthereumSignTx
- EthereumMetadataAck (msg 116): receives verification result from device
- Device OLED displays decoded contract call info instead of raw hex when
  a verified metadata blob is provided

Protocol flow:
  1. Host → EthereumTxMetadata(signed_payload, key_id)
  2. Device → EthereumMetadataAck(classification: OPAQUE|VERIFIED|MALFORMED)
  3. Host → EthereumSignTx (normal flow continues)
  4. Device OLED shows decoded contract info if classification=VERIFIED

Protobuf shims implement deserializeBinaryFromReader (required by
transport.ts:395 for inbound message decoding) — not just deserializeBinary.
Graceful fallback on older firmware that doesn't support msg type 115.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9 tests covering:
- Message registration in type registry (115, 116)
- EthereumTxMetadata serialize/deserialize round-trip via deserializeBinaryFromReader
  (the exact codepath transport.ts uses for inbound messages)
- EthereumMetadataAck deserialization for all 3 classifications (OPAQUE/VERIFIED/MALFORMED)
- Empty payload handling
- toObject() shape validation

These tests would have caught the missing deserializeBinaryFromReader bug
that caused the metadata path to silently fall back to blind signing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@BitHighlander BitHighlander merged commit 9b7b98a into master Mar 21, 2026
4 checks passed
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.

1 participant