Skip to content

feat(protocol): 7.15 release additions — hive signing (1614-1617), clearsign identity icons, thorchain denom, ripple memo, zcash - #112

Open
BitHighlander wants to merge 69 commits into
masterfrom
up/release-protocol
Open

feat(protocol): 7.15 release additions — hive signing (1614-1617), clearsign identity icons, thorchain denom, ripple memo, zcash#112
BitHighlander wants to merge 69 commits into
masterfrom
up/release-protocol

Conversation

@BitHighlander

@BitHighlander BitHighlander commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Upstream branch → upstream master. keepkey:up/release-protocol is the single protocol PR for the firmware 7.15 / RC18 release line. It replaces the mis-structured #111 and remains blocked on human review.

Additions

All changes are additive; existing field numbers and wire behavior remain compatible.

  • Hive signing: HiveSignMessage / HiveSignedMessage (1614/1615) and HiveSignOperations / HiveSignedOperations (1616/1617). 1610-1613 remain reserved for NEAR.
  • Clearsign identity icons on LoadClearsignSigner: bounded RLE icon data, icon_width, icon_height, and the legacy-compatible persist field.
  • Earlier 7.x additions accumulated on this release branch: thorchain any-denom, Ripple memo, and Zcash messages.

RC18 Zcash wire contract

The regular/full RC18 firmware includes Orchard privacy. Only bitcoin-only compiles non-Bitcoin features out.

  • all Orchard actions are streamed to and validated by the device
  • is_spend is required by firmware 7.15
  • dummy shield/change actions use is_spend=false and receive no RedPallas signature
  • real spends use is_spend=true
  • ZcashSignedPCZT.signatures is compact: exactly one 64-byte signature per real spend, in ascending action order
  • an all-dummy shield transaction therefore returns zero Orchard signatures

These semantics are documented on the protocol fields and pinned by a machine-readable contract check.

Validation

Review and merge gates

  • singular master-targeting protocol branch
  • hosted descriptor and RC18 contract validation
  • human approval and merge of this PR
  • Python #197 repinned to the resulting canonical master commit, reviewed, and merged
  • firmware #320 repinned to both canonical dependency merge commits and rerun

No merge, tag, or release is requested before human review.

BitHighlander and others added 30 commits March 23, 2026 15:26
- PCZT streaming protocol: ZcashSignPCZT, ZcashPCZTAction, ZcashPCZTActionAck
- Orchard FVK: ZcashGetOrchardFVK, ZcashOrchardFVK
- Transparent shielding: ZcashTransparentInput, ZcashTransparentSig
- Wire IDs 1300-1307
- nanopb options for all fields

Multi-phase protocol: session init → action streaming → transparent signing.
Supports on-device Orchard digest verification via sub-digest fields.
New messages for displaying a Zcash unified address on the device screen
with FVK verification. The host provides the UA string and FVK components;
the device independently derives FVK from seed and verifies the match
before displaying the address with a QR code.

- ZcashDisplayAddress (wire_in 1308): address + ak/nk/rivk for verification
- ZcashAddress (wire_out 1309): confirmed address after user approval
- nanopb options: address max_size:128, key fields max_size:32
feat(zcash): add ZcashDisplayAddress protocol (IDs 1308/1309)
The device only verifies the Orchard FVK — it cannot verify
transparent or Sapling receivers that may also be bundled in
a Unified Address. Updated proto comments to explicitly state
the guarantee: "This UA contains an Orchard receiver from this
account" rather than implying full address ownership.

Also clarified that account or address_n is required (no silent
fallback to account 0).
docs(zcash): clarify ZcashDisplayAddress verification scope
…TIP-712)

Adds proto definitions for TRON message-signing parity:
- TronSignMessage / TronMessageSignature (1404/1405) — TIP-191 personal_sign
- TronVerifyMessage (1406) — host-asserted signature verification
- TronSignTypedHash / TronTypedDataSignature (1407/1408) — TIP-712 hash mode

Mirrors the Ethereum personal_sign + EIP-712 hash-mode shape. Firmware
implementation will reuse the secp256k1 + keccak256 primitives already
present for Ethereum, swapping the message prefix to '\x19TRON Signed Message:\n'
for TIP-191 and using '\x19\x01' for TIP-712.

Reserves IDs 1404-1408 contiguous to existing TRON range (1400-1403).
Adds TonSignMessage / TonMessageSignature (1504/1505) — basic Ed25519
arbitrary-bytes signing, mirroring SolanaSignMessage's shape.

This primitive lacks domain separation by design (raw Ed25519 over message
bytes). Firmware should gate it behind the AdvancedMode policy — same
fence used for SolanaSignMessage in fsm_msg_solana.h — until a TON
Connect ton_proof envelope is added as a separate proto.

Reserves IDs 1504-1505 contiguous to existing TON range (1500-1503).
Adds SolanaSignOffchainMessage / SolanaOffchainMessageSignature (756/757)
implementing the Solana off-chain message spec:

  '\xff' || 'solana offchain' || version || format || length || message

The '\xff' lead byte is invalid as a Solana transaction prefix, providing
the domain separation that plain SolanaSignMessage (754/755) lacks. With
this primitive, firmware can drop the AdvancedMode policy gate currently
required for SolanaSignMessage (fsm_msg_solana.h:461-472) for ASCII/UTF8
off-chain messages, since the envelope makes transaction-shaped attacks
impossible.

message_format values per spec:
  0 = Restricted ASCII (max 1212 bytes) — display-renderable
  1 = UTF-8 limited (max 1212 bytes) — display-renderable with care
  2 = UTF-8 extended (max 65515) — blind-sign only

Reserves IDs 756-757 contiguous to existing Solana range (750-755).
Bumped message max_size to 1212 to match the spec ceiling for formats 0/1.
…sages

ZIP-32 §6.1 seed fingerprint:

  SeedFingerprint := BLAKE2b-256("Zcash_HD_Seed_FP", seed)

A 32-byte stable identity of the device's seed. Adds optional bytes
seed_fingerprint fields across the existing zcash messages so hosts
and devices can bind FVKs, addresses, and signing sessions to a
specific seed identity.

Four new fields, all optional, fully backward compatible:

  ZcashOrchardFVK.seed_fingerprint              (4)
    Returned alongside (ak, nk, rivk). Lets a host pin an FVK to
    this device's seed.

  ZcashAddress.seed_fingerprint                 (2)
    Returned alongside the confirmed UA after on-device verification.
    Lets a host record "this address is on this device's seed."

  ZcashSignPCZT.expected_seed_fingerprint       (31)
    Sent by host. If present, device checks against its own
    fingerprint and rejects with Failure on mismatch before signing.
    Mirrors Keystone3's PCZT zip32_derivation seed_fingerprint check
    at the session level (one tx = one seed, no per-action duplication
    needed for our flow).

  ZcashDisplayAddress.expected_seed_fingerprint (7)
    Sent by host. Same rejection semantics as above before displaying.

Matching nanopb max_size:32 entries added to messages-zcash.options.

No existing fields modified. Devices and hosts that don't populate
the new fields continue to work unchanged.
feat(zcash): add seed_fingerprint binding to FVK / address / sign messages
Brings in upstream's 7.14.0 release + features/7.15 commits:
  d0b8d80 feat: 7.14.0 protocol — BIP-85, EVM metadata, Solana, TRON, TON, Zcash
  18bb4a7 Merge pull request #100 from keepkey/release/7.14.0
  bbcfcb0 feat: add ZcashDisplayAddress protocol messages (IDs 1308-1309)
  bf8646b Merge pull request #101 from keepkey/features/7.15

Note: ZcashDisplayAddress was developed in parallel on both sides.
Conflict resolution prefers upstream's version (max_size:256 for the
unified-address fields, more correct than fork's :128 since UAs can be
long when shielded receivers are present).

# Conflicts:
#	messages-zcash.options
#	messages-zcash.proto
#	messages.proto
#	package.json
Brings in TRON/TON/Solana message-signing proto definitions:
  0e3dc97 feat(tron): TIP-191 SignMessage, VerifyMessage, TIP-712 SignTypedHash
  20e646a feat(ton): Ed25519 SignMessage primitive
  c0ef415 feat(solana): SignOffchainMessage with domain-separated envelope

After this merge, fork master is the single source of truth that
firmware branches pin to during fork-only testing. A clean upstream
PR can be assembled later by cherry-picking these 3 commits onto a
fresh branch off keepkey/master.
Field comments documented the formula as

  BLAKE2b-256("Zcash_HD_Seed_FP", seed)

but ZIP-32 §6.1 (and the actual conforming implementations in the
upstream zip32 Rust crate, keystone3-firmware, and our own firmware)
prepend a 1-byte length:

  BLAKE2b-256("Zcash_HD_Seed_FP", I2LEBSP_8(len(seed)) || seed)

A host implementer following the proto comments would compute the
wrong fingerprint and have the device reject every signing/display
request with "seed fingerprint mismatch."

Comment-only change. No wire-format impact.
…formula-doc

fix(zcash): correct seed_fingerprint formula in proto comments
Remove fields 3-6 (address, ak, nk, rivk) from ZcashDisplayAddress.
Field numbers are reserved to prevent reuse. The on-device UA
derivation (Sinsemilla + SWU hash-to-curve) shipped — FVK-match
attestation against a host-built UA is strictly weaker than
device-derived display and is no longer supported.

What stays: address_n / account / expected_seed_fingerprint.
What ZcashAddress returns: address (now device-derived) + seed_fingerprint.
Add optional string memo field (field 7) to RippleSignTx protobuf message.
This enables THORChain swap routing memos and other arbitrary memo data
to be included in XRP transactions signed by the device.
feat(ripple): add memo field to RippleSignTx for 7.14.2
Merges upstream 7.14.1 (Tron TIP-191/712, TON SignMessage, Solana
SignOffchainMessage) with fork's Zcash UA/seed_fingerprint/display
address additions. Conflict resolution: kept upstream's format-2
removal from SolanaSignOffchainMessage docs.
Adds messages-hive.proto with HiveGetPublicKey, HivePublicKey,
HiveSignTx, and HiveSignedTx. Assigns message type IDs 1600-1603
in messages.proto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* release: device-protocol 7.14.1

* feat(tron): add SignMessage (TIP-191), VerifyMessage, SignTypedHash (TIP-712)

Adds proto definitions for TRON message-signing parity:
- TronSignMessage / TronMessageSignature (1404/1405) — TIP-191 personal_sign
- TronVerifyMessage (1406) — host-asserted signature verification
- TronSignTypedHash / TronTypedDataSignature (1407/1408) — TIP-712 hash mode

Mirrors the Ethereum personal_sign + EIP-712 hash-mode shape. Firmware
implementation will reuse the secp256k1 + keccak256 primitives already
present for Ethereum, swapping the message prefix to '\x19TRON Signed Message:\n'
for TIP-191 and using '\x19\x01' for TIP-712.

Reserves IDs 1404-1408 contiguous to existing TRON range (1400-1403).

* feat(ton): add SignMessage Ed25519 message-signing primitive

Adds TonSignMessage / TonMessageSignature (1504/1505) — basic Ed25519
arbitrary-bytes signing, mirroring SolanaSignMessage's shape.

This primitive lacks domain separation by design (raw Ed25519 over message
bytes). Firmware should gate it behind the AdvancedMode policy — same
fence used for SolanaSignMessage in fsm_msg_solana.h — until a TON
Connect ton_proof envelope is added as a separate proto.

Reserves IDs 1504-1505 contiguous to existing TON range (1500-1503).

* feat(solana): add SignOffchainMessage with domain-separated envelope

Adds SolanaSignOffchainMessage / SolanaOffchainMessageSignature (756/757)
implementing the Solana off-chain message spec:

  '\xff' || 'solana offchain' || version || format || length || message

The '\xff' lead byte is invalid as a Solana transaction prefix, providing
the domain separation that plain SolanaSignMessage (754/755) lacks. With
this primitive, firmware can drop the AdvancedMode policy gate currently
required for SolanaSignMessage (fsm_msg_solana.h:461-472) for ASCII/UTF8
off-chain messages, since the envelope makes transaction-shaped attacks
impossible.

message_format values per spec:
  0 = Restricted ASCII (max 1212 bytes) — display-renderable
  1 = UTF-8 limited (max 1212 bytes) — display-renderable with care
  2 = UTF-8 extended (max 65515) — blind-sign only

Reserves IDs 756-757 contiguous to existing Solana range (750-755).
Bumped message max_size to 1212 to match the spec ceiling for formats 0/1.

* feat(zcash): drop host-supplied UA from ZcashDisplayAddress

Remove fields 3-6 (address, ak, nk, rivk) from ZcashDisplayAddress.
Field numbers are reserved to prevent reuse. The on-device UA
derivation (Sinsemilla + SWU hash-to-curve) shipped — FVK-match
attestation against a host-built UA is strictly weaker than
device-derived display and is no longer supported.

What stays: address_n / account / expected_seed_fingerprint.
What ZcashAddress returns: address (now device-derived) + seed_fingerprint.

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* docs: update SolanaSignOffchainMessage to reflect 1212 byte limit and drop format 2

Agent-Logs-Url: https://github.com/keepkey/device-protocol/sessions/880cd954-b4b2-4f87-af05-8d715e1e0dc4

Co-authored-by: pastaghost <62026038+pastaghost@users.noreply.github.com>

* feat(hive): add Hive blockchain message definitions

Adds messages-hive.proto with HiveGetPublicKey, HivePublicKey,
HiveSignTx, and HiveSignedTx. Assigns message type IDs 1600-1603
in messages.proto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(hive): add messages-hive.proto to build, drop broken build:json step

build:json used pbjs v0.0.5 which cannot parse proto3 reserved fields (present
in zcash, cosmos, ethereum, etc). proto.json is unused by the vault — only
messages_pb.js is imported. Build now runs build:js + build:postprocess only.

* feat(hive): add HiveGetPublicKeys, HiveSignAccountCreate, HiveSignAccountUpdate + SLIP-0048 paths

---------

Co-authored-by: pastaghost <62026038+pastaghost@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves conflict between:
- feature/hive branch (2b25cf7): 10 Hive message types
- alpha branch (c1dea44): Zcash clear-signing + THORChain denom field

Kept all 10 Hive message types; added alpha's Zcash/THORChain proto additions.
NearGetAddress, NearAddress, NearSignTx, NearSignedTx.
Ed25519 derivation m/44'/397'/0'. Implicit account = lowercase hex of
the 32-byte Ed25519 pubkey.

Numbered 1610-1613 to avoid colliding with Hive (1600-1609), which
landed on alpha after the original NEAR spike.
feat(near): NEAR Protocol proto definitions (MessageType 1610-1613)
…oadcast (#35)

account_create is authorized on-chain by the creator (sponsor) account's active
authority, not by the new account. The device's owner-key signature here is a
proof-of-control attestation; the sponsor recovers the owner pubkey to verify
control, then rebuilds and signs the real account_create with the creator's
active key server-side. Comment-only — no wire or generated-code change.

Addresses review P1 on the (closed) feature/hive PR.
Adds the device-protocol messages required by the upcoming firmware release:

- thorchain: ThorchainMsgSend.denom (field 11) — non-RUNE assets (TCY, RUJI, IBC)
- ripple:    RippleSignTx.memo (field 7) — XRP->THORChain swap routing
- hive:      full Hive support — HiveGetPublicKey(s), HiveSignTx,
             HiveSignAccountCreate/Update (MessageType 1600-1609)
- zcash:     clear-signing + Orchard shielded protocol (transparent in/out/ack,
             PCZT, FVK, display-address)

All additions are new optional fields / new message types — additive and
backward-compatible. lib/ bindings are gitignored build artifacts; package.json
build:js/json updated to include messages-hive.proto.
BitHighlander and others added 13 commits July 31, 2026 14:41
feat(solana): add verified token recipient owner hints
fix(ci): make protobuf JavaScript codegen portable
fix(build): generate bindings for git dependencies
Lets a host ask the device whether it can derive and spend P2TR, instead of
inferring it from a firmware version.  Version inference breaks the moment
the feature is retargeted to a different release, and it forces every client
to carry a version table.

Field 27: 19 and 20 are gaps with no reserved markers, so they are not safe
to reuse against historical wire data.

Additive and optional -- older hosts ignore it, older firmware simply does
not set it.
…safety

fix(ci): request reviews safely for fork PRs
…taging

feat(features): advertise Taproot signing support
ResetDevice.dice_entropy=10 asks the device to collect dice rolls with
the single button and mix them into the internal entropy before it is
displayed or committed. DebugLinkDecision.input=2 lets debug builds
inject synthetic roll input (kept short so the decoded struct fits the
firmware tiny-message buffer). DebugLinkState.dice_digest=15 exposes
SHA-256 of the collected ASCII roll string so tests can prove the
device received exactly the injected rolls. ButtonRequest_DiceRoll=39
announces the entry screen to the host.
feat(reset): dice-entropy fields for on-device roll collection
BitHighlander and others added 9 commits August 4, 2026 22:38
Picks up f2c3c00 (ci: auto-request Copilot review), the only commit the
fork lacked. The fork's 28 protocol commits -- zcash Orchard + clear-sign,
hive, near, tron/ton/solana message signing, ripple memo, thorchain denom --
are unaffected; this adds one workflow file and nothing else.
yarn install --frozen-lockfile fails on this branch with:
  @mapbox/node-pre-gyp@2.0.3: The engine "node" is incompatible with this
  module. Expected version ">=18". Got "17.2.0"

The unpinned legacy circleci/node image resolves to node 17.2.0. master
passes only because its older lockfile predates that transitive
requirement; any lockfile refresh trips it. Pin a maintained image.
The Ironwood enum was inserted above the file-level java_package /
java_outer_classname options, leaving them after a top-level definition.
protobufjs's parser rejects that outright:

  Error: illegal token 'option' (messages-zcash.proto, line 16)

so 'npm run build' (build:json -> lib/proto.json) fails on this branch.
protoc accepts either order, so the generated descriptors are unchanged;
every other proto in the repo already declares options directly after
syntax. Verified: pbjs now emits proto.json cleanly.
alpha pinned device-protocol at cf308fd, 32 commits ahead of fork master and
29 behind. Per the branch SOP alpha must pin fork MASTERS, not loose commits --
a pin that exists only on a feature branch is the tech debt, because nothing
downstream can resolve it without knowing which branch it came from.

Merged rather than picked, since both lines had real work:

  messages.proto        NEAR 1610-1613 (master) + Hive 1614-1617 and Clearsign
                        attestor 1700-1703 (alpha). No ID collision -- alpha's
                        side already carried the comment reserving 1610-1613 for
                        NEAR, so this merge was anticipated.
  messages-zcash        alpha's shielded_pool and ironwood_digest (NU6.3 / v6)
  messages-hive         alpha's SignMessage/SignedMessage options; master's
                        account_create attestation docs kept
  package.json          alpha's scripts as the base: they actually run build:json,
                        and use grpc_tools_node_protoc explicitly rather than bare
                        protoc. Master contributed messages-near.proto, which alpha
                        lacked. All three of near/zcash/hive now appear in both
                        build:js and build:json.

Verified no duplicate field numbers within any message, and no duplicate
MessageType IDs.
A Solana v0 transaction may source instruction accounts from an Address Lookup
Table. Those accounts are NOT in the bytes being signed, so the device cannot
derive them and refuses to guess: the transaction is forced to
SOL_TX_REVIEW_OPAQUE, which fsm_msg_solana.h refuses outright unless the user
has enabled AdvancedMode, and which is then an explicit BLIND SIGN. The
instruction's meaning is never shown.

So this does not rescue a blank screen -- nothing is signed silently. It
upgrades a BLIND SIGN into a provider-attested CLEAR SIGN, which is the whole
point of the tier.

KKSOLSC1 schemas cannot close this: they are instruction-scoped and reusable,
carry no transaction hash, and work by decoding values out of the bytes the
device is signing. With a lookup table those bytes do not contain the accounts.

So a provider attests the resolved account list for THIS transaction:

  preimage = "KeepKeySolanaTxAccounts/1" || message_hash(32)
             || count(le32) || account[i](32) ...

Bound to the exact message hash, so it cannot be replayed onto another
transaction. Domain-tagged, so a signature made for any other purpose -- an EVM
metadata blob, a token definition -- cannot be replayed as one.

Annotation, not authority: accounts render as PROVIDER-ATTESTED next to the
provider alias, and the unverified-transaction review still runs.

Uses tags 5-7 of the reservation that named this descriptor. Tag 8 stays
reserved for one-request opaque-signing consent.
feat(solana): KKSOLSW1 transaction-bound account attestation on tags 5-7
Five messages (1704-1708) that let the device drive an EIP-712 walk instead of
being handed the document.

The device asks for one type definition, or one leaf VALUE, at a time, and
hashes each value in the same pass that displays it. The host owns the
document; the device holds only the digest stack for the containers currently
open. A 10,000-element array costs the same RAM as a 2-element one, and there
is no document-size limit to raise later.

This replaces Ethereum712TypesValues, which shipped the whole thing as two
2048-byte JSON blobs and was withdrawn in 7.14.2 because its parser could not
guarantee the value on screen was the value being hashed. Here that is
structural rather than reviewed: a value is displayed and absorbed from the
same buffer in the same call, and each member_path is requested exactly once.

That last clause is not incidental. Trezor shipped this same protocol with a
hole until 2.12.0 -- nothing bound repeated answers for one path to each other,
so a host could answer the domain name one way for the summary screen and
another for the hashing pass. Requesting each path once closes it by
construction rather than by caching around it.

ONE deliberate divergence from Trezor and OneKey: arrays.

Both describe an array as a field whose entry_type is another EthereumFieldType
-- a self-referential message. Trezor can, because core is Python. OneKey does
it on nanopb by compiling that one field as a POINTER (PB_ENABLE_MALLOC) and
then flattening the pointer chain into a fixed pool to sever the recursion.

KeepKey's nanopb is static-allocation only, and a heap inside a signing device
is not a liability worth taking on for one field. So array nesting is FLATTENED
onto the wire the way Ledger describes it: data_type is always the LEAF type,
and array_levels carries the dimensions in written order, 0 for dynamic:

    uint256        -> UINT,   size=32,               array_levels=[]
    address[]      -> ADDRESS,                       array_levels=[0]
    Person[3]      -> STRUCT, struct_name="Person",  array_levels=[3]
    int16[2][][4]  -> INT,    size=2,                array_levels=[2,0,4]

Nothing EIP-712 permits is lost and the encoding is bounded, flat and
statically sized. Enum values still match Trezor's so a shared host keeps its
mapping; ARRAY is reserved and never sent.

Values arrive as raw big-endian bytes of the declared width, not JSON. That
deletes the whole decimal-parsing step from the device -- and with it the
64-bit integer ceiling that made the old path refuse an unlimited approval,
which is the most common permit there is.

Validated with protoc 3.5.1 in kktech/firmware:v8.
…aming

feat(eip712): device-driven field streaming for structured typed data
up/release-protocol carried two build fixes that exist only on this
upstream branch -- the cimg/node:20.11 CI pin and moving the zcash file
options into the preamble so pbjs can parse them -- while 34 commits of
7.15 protocol work sat on the fork's master. develop cannot pin the fork
commit, because a PR into upstream carries its submodule pins and a
reviewer cannot resolve one that exists only on a fork.

Merged rather than rebased so nothing is force-pushed over an open PR,
and so both histories stay readable.

Verified after the merge, because a clean auto-merge keeps hunks from
both sides and that is exactly how one side quietly loses:
  - cimg/node:20.11 still pinned in .circleci/config.yml
  - the zcash file options are still in the preamble
  - EthereumSignTypedData / EthereumTypedDataStructAck /
    EthereumTypedDataValueAck all present in messages-ethereum.proto
BitHighlander added a commit to keepkey/keepkey-firmware that referenced this pull request Aug 22, 2026
keepkey/python-keepkey#216 -- the 7.14.2 disclosure tests -- is merged, so
upstream master is 598097e1 and carries them. This PR pinned 87ff2499,
that PR's branch head, which was the right pin while it was open and is
the wrong one now: a merged PR's branch can be deleted, and a pin at a
branch head rather than at master is exactly what a reviewer cannot
resolve later.

598097e1 is 1 ahead of 87ff2499 and 0 behind -- the merge commit, nothing
else. Every submodule pin on this branch was re-verified to FETCH from its
real URL, not merely to be well-formed.

deps/device-protocol stays at f2c3c005, which IS upstream master: the
7.14.2 line needs no protocol change. The 7.15 protocol additions are
keepkey/device-protocol#112 and land with that release.
@BitHighlander

Copy link
Copy Markdown
Collaborator Author

Review guide

Scope: the 7.15 protocol additions. This is a dependency merge — nothing here ships to a device by itself; it makes submodule pins resolvable for the firmware releases that follow.

The change is wire-additive

The only deletion in messages.proto is a rename at the same wire number:

- MessageType_ZcashTransparentSig     = 1307 [(wire_out) = true];
+ MessageType_ZcashTransparentSigned  = 1307 [(wire_out) = true];

Identical wire value, so nothing on the wire breaks. The other deletions are in messages-zcash.proto (+111/−33), restructuring messages for a chain that does not ship in the 7.14.x line.

Where the volume actually is

+3,071/−112 across 22 files sounds large; only ~750 lines are real .proto/.options. The rest:

lines
generated lib/messages-ripple_pb.js + .d.ts 1,604
package-lock.json + yarn.lock 501
.proto / .optionsthe actual review surface ~750

Worth checking

  • new message numbers do not collide: hive 1614-1617, near, and the solana/ethereum additions
  • supports_taproot in messages.proto — this one is load-bearing for the upcoming 7.14.3 bitcoin-only release, which cannot report the capability without it
  • messages-zcash.proto restructuring, if you want to be thorough — but it cannot affect 7.14.x

Why it matters now

Two firmware releases are waiting on this pin becoming resolvable on master:

  • 7.14.3 bitcoin-only + taproot — currently has to carry a dress-rehearsal pin at this PR's head to get supports_taproot
  • 7.15 — same, via keepkey/keepkey-firmware staging

Both ci/circleci: build and validate are green.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds firmware 7.15 protocol surfaces across Hive, Zcash, clearsigning, and several chains, plus validation and binding-generation updates.

Changes:

  • Adds Hive, NEAR, Zcash, Ethereum/Solana clearsigning, Ripple, and THORChain protocol fields.
  • Updates JavaScript protobuf generation and dependencies.
  • Adds protocol CI and Zcash contract validation.

Reviewed changes

Copilot reviewed 19 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
yarn.lock Updates generator dependencies.
types.proto Adds dice-roll button type.
tools/check_zcash_contract.py Validates the RC18 Zcash contract.
package.json Updates protobuf builds and inputs.
package-lock.json Locks updated npm dependencies.
messages.proto Registers messages and common fields.
messages-zcash.proto Defines revised Zcash signing flows.
messages-zcash.options Bounds Zcash fields.
messages-thorchain.proto Adds send denomination.
messages-solana.proto Adds clearsigning attestations.
messages-solana.options Bounds new Solana fields.
messages-ripple.proto Adds transaction memo.
messages-near.proto Defines NEAR protocol messages.
messages-hive.proto Defines Hive protocol messages.
messages-hive.options Bounds Hive fields.
messages-ethereum.proto Adds clearsign and EIP-712 messages.
messages-ethereum.options Bounds new Ethereum fields.
lib/messages-ripple_pb.js Adds generated Ripple bindings.
lib/messages-ripple_pb.d.ts Adds Ripple TypeScript declarations.
.github/workflows/copilot-review.yml Supports cross-fork review requests.
.github/workflows/ci.yml Adds protocol validation CI.
.circleci/config.yml Updates the Node.js image.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/ci.yml
messages-hive.proto messages-mayachain.proto messages-nano.proto \
messages-osmosis.proto messages-ripple.proto messages-solana.proto \
messages-tendermint.proto messages-thorchain.proto messages-ton.proto \
messages-tron.proto messages-zcash.proto
Comment thread messages-solana.options
Comment on lines +7 to 12
SolanaSignTx.schema_payload max_size:256
SolanaSignTx.schema_signature max_size:64
SolanaSignTx.token_recipient_owner max_count:4
SolanaSignTx.token_recipient_owner max_size:32
SolanaTokenInfo.mint max_size:32
SolanaTokenInfo.symbol max_size:13
Comment thread messages-zcash.proto
Comment on lines +229 to +232
* Fields 3–6 (host-supplied address, ak, nk, rivk) were removed when the
* device gained on-device UA derivation: FVK-match attestation against a
* host-built UA is strictly weaker than device-derived display and was
* dropped. Field numbers are reserved to prevent reuse.
Comment thread messages.proto
Comment on lines +268 to +272
// NEAR
MessageType_NearGetAddress = 1610 [ (wire_in) = true ];
MessageType_NearAddress = 1611 [ (wire_out) = true ];
MessageType_NearSignTx = 1612 [ (wire_in) = true ];
MessageType_NearSignedTx = 1613 [ (wire_out) = true ];
Comment thread messages-hive.proto
Comment on lines +102 to +105
* Request: Sign a Hive account_create operation (op type 9).
* All four role public keys become the account authorities at genesis.
* No software keys are generated. KeepKey is sole root of trust from block 1.
* Signing key: owner key at m/48'/13'/0'/account_index'/0'
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.

2 participants