Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f9e6081
feat: protocol additions for the firmware 7.x release
BitHighlander Jun 30, 2026
2ec999a
feat: LoadClearsignSigner (117) — runtime clearsign signer with alias…
BitHighlander Jul 2, 2026
33521a8
feat(clearsign): identity icon + persist fields on LoadClearsignSigner
BitHighlander Jul 7, 2026
9e46aeb
feat(hive): HiveSignMessage/HiveSignedMessage (1614/1615) — Keychain …
BitHighlander Jul 15, 2026
a793934
docs(hive): HiveSignMessage roles are posting/active/memo — owner' re…
BitHighlander Jul 15, 2026
f0b4549
feat(hive): HiveSignOperations/HiveSignedOperations (1616/1617) — par…
BitHighlander Jul 15, 2026
f7b4580
fix(clearsign): specify the icon RLE wire grammar — the packed-bitmap…
BitHighlander Jul 16, 2026
7182973
fix(clearsign): icon spec was unsafe — 0x80 literal undecodable, widt…
BitHighlander Jul 16, 2026
4eb7d5e
fix(clearsign): drop the obsolete packed-size rationale; correct the …
BitHighlander Jul 16, 2026
47e19d8
feat(solana): optional signed token-definition fields on SolanaTokenInfo
BitHighlander Jul 17, 2026
e31cddf
docs(clearsign): reserve persistence pending authenticated storage
BitHighlander Jul 25, 2026
6d0ae67
test(zcash): pin RC18 compact-signature contract
BitHighlander Jul 26, 2026
41c59ab
feat(solana): reusable instruction-schema fields on SolanaSignTx
BitHighlander Jul 27, 2026
844a9b9
feat(clearsign): attestor messages (1700-1703)
BitHighlander Jul 27, 2026
81c398d
docs(clearsign): attestor validates KKSOLSC1, not the abandoned KKSOLSW1
BitHighlander Jul 29, 2026
8856334
fix(clearsign): reserve additive schema wire fields
BitHighlander Jul 29, 2026
4cc8b71
fix(clearsign): reserve Solana transaction metadata tags
BitHighlander Jul 30, 2026
f2246ce
feat(zcash): add Ironwood signing metadata
BitHighlander Jul 30, 2026
2f766c2
Merge pull request #113 from keepkey/agent/zcash-ironwood-develop
BitHighlander Jul 30, 2026
cc858ef
feat(solana): add verified token recipient owner hints
BitHighlander Jul 31, 2026
5a8e270
Merge pull request #114 from BitHighlander/agent/x402-solana-metadata
BitHighlander Jul 31, 2026
dafb567
fix(ci): make protobuf JavaScript codegen portable
BitHighlander Jul 31, 2026
d8b94bd
Merge pull request #115 from keepkey/agent/fix-portable-protobuf-codegen
BitHighlander Jul 31, 2026
4b41d11
fix(build): generate bindings for git dependencies
BitHighlander Jul 31, 2026
b13391c
Merge pull request #116 from keepkey/agent/build-git-dependencies
BitHighlander Jul 31, 2026
be28549
feat(features): add supports_taproot capability bit
BitHighlander Aug 1, 2026
635571b
fix(ci): request reviews safely for fork PRs
BitHighlander Aug 2, 2026
d7ad3f2
Merge pull request #118 from BitHighlander/agent/copilot-review-fork-…
BitHighlander Aug 2, 2026
126e6a4
Merge remote-tracking branch 'upstream/up/release-protocol' into agen…
BitHighlander Aug 2, 2026
674777f
Merge pull request #117 from BitHighlander/agent/taproot-capability-s…
BitHighlander Aug 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Protocol CI

on:
push:
branches: [master, up/release-protocol]
pull_request:
branches: [master, up/release-protocol]

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Install protobuf compiler
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

- name: Use Node.js 20
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install JavaScript generator dependencies
run: npm ci

- name: Verify install generated JavaScript bindings
run: |
test -s lib/messages_pb.js
test -s lib/messages-solana_pb.js
test -s lib/messages-zcash_pb.js

- name: Compile protocol descriptors
run: |
protoc --proto_path=. --include_imports \
--descriptor_set_out=/tmp/keepkey-device-protocol.pb \
types.proto messages.proto messages-binance.proto \
messages-cosmos.proto messages-eos.proto messages-ethereum.proto \
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

- name: Check RC18 Zcash wire contract
run: python3 tools/check_zcash_contract.py
6 changes: 5 additions & 1 deletion .github/workflows/copilot-review.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
name: Request Copilot Review

on:
pull_request:
# This workflow never checks out or executes pull-request code. Using the
# base-repository context is therefore safe and is required for cross-fork
# PRs, whose pull_request GITHUB_TOKEN is always downgraded to read-only.
pull_request_target:
types: [opened, reopened, ready_for_review, synchronize]

jobs:
request-copilot-review:
if: github.event.pull_request.draft == false
runs-on: ubuntu-latest
permissions:
pull-requests: write
Expand Down
3 changes: 3 additions & 0 deletions messages-ethereum.options
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
EthereumTxMetadata.signed_payload max_size:1024
EthereumMetadataAck.display_summary max_size:32
LoadClearsignSigner.pubkey max_size:33
LoadClearsignSigner.alias max_size:32
LoadClearsignSigner.icon max_size:384
60 changes: 60 additions & 0 deletions messages-ethereum.proto
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,66 @@ message EthereumMetadataAck {
optional string display_summary = 2; // Brief result for host logging
}

/**
* Request: Load a clearsign signer public key + alias into a key slot.
* The device shows a mandatory confirmation (alias + key fingerprint) before
* accepting; there is no way to load a signer without user consent.
* A signer is RAM-only and is cleared on reboot. The persist field is retained
* for wire compatibility and future authenticated storage; firmware 7.15
* rejects persist=true. Every transaction whose metadata was verified by a loaded
* (non built-in) signer is preceded by a warning screen naming the alias
* during transaction confirmation.
* @next Success
* @next Failure
*/
message LoadClearsignSigner {
optional uint32 key_id = 1; // target key slot (0-3); must not hold a built-in key
optional bytes pubkey = 2; // 33-byte compressed secp256k1 public key
optional string alias = 3; // short display name shown on load confirm + per-tx warning
/*
* Optional identity logo, <= 384 bytes, run-length encoded — NOT a packed
* bitmap. (This is the format because draw_bitmap_mono_rle() is the decoder
* of record and every bundled image already uses it; it is NOT a size
* workaround — a packed 1bpp icon at the legal maximum geometry, 40x64,
* would be 320 bytes and would fit the cap.)
* Pixels are BYTE-VALUED intensity, one byte per pixel after decoding; the
* device renders each as (value * color / 100). Decoder of record:
* keepkey-firmware lib/board/draw.c: draw_bitmap_mono_rle().
*
* Grammar — the stream is a sequence of packets. Read n = (int8)data[i++]:
* n in [1, 127] RUN : one value byte follows; emit it n times. [n][v]
* n in [-127, -1] LITERAL : (-n) value bytes follow; emit each once. [n][v1]..[v-n]
* n == 0 : invalid.
* n == -128 (0x80) : INVALID. The decoder's run counter is int8_t,
* so it cannot represent -(-128) = 128; a 0x80
* packet is undecodable. Encoders MUST split a
* 128-byte literal into two packets. Firmware
* rejects 0x80 rather than rendering.
* The stream must decode EXACTLY, and the device validates this before the
* icon is shown or stored: no run may straddle the end of the image,
* exactly icon_width*icon_height pixels are emitted (row-major,
* left->right, top->bottom), and the ENTIRE input must be consumed —
* trailing packets after the final pixel are rejected. So a RUN emits at
* most 127 pixels and a LITERAL at most 127.
*
* Golden vector (2x2, w=2 h=2): bytes 03 FF FF 00
* 03 -> RUN of 3, value FF => pixels [FF, FF, FF]
* FF -> n = -1, LITERAL of 1 => next byte 00 => pixel [00]
* decoded = FF FF FF 00 (row0 = FF FF, row1 = FF 00)
*/
optional bytes icon = 4;
/*
* Icon pixel width, 1..40. The cap is the confirm screen's left icon column
* (LEFT_MARGIN_WITH_ICON = 40); title/body text begins at x=40 and the icon
* is drawn AFTER the text, so a wider icon would paint over the alias,
* fingerprint and the "NOT verified by KeepKey" warning on the trust screen.
* Icon + both dimensions omitted => text-only identity.
*/
optional uint32 icon_width = 5;
optional uint32 icon_height = 6; // icon pixel height (1..64; the icon column is 64px tall)
optional bool persist = 7; // reserved compatibility field; firmware rejects true (RAM-only)
}

////////////////////////////////////////
// Ethereum: Message signing messages //
////////////////////////////////////////
Expand Down
58 changes: 58 additions & 0 deletions messages-hive.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
HiveGetPublicKey.address_n max_count:8

HivePublicKey.public_key max_size:64
HivePublicKey.raw_public_key max_size:33

HiveGetPublicKeys.account_index int_size:IS_32

HivePublicKeys.owner_key max_size:64
HivePublicKeys.active_key max_size:64
HivePublicKeys.memo_key max_size:64
HivePublicKeys.posting_key max_size:64

HiveSignTx.address_n max_count:8
HiveSignTx.chain_id max_size:32
HiveSignTx.from max_size:16
HiveSignTx.to max_size:16
HiveSignTx.amount int_size:IS_64
HiveSignTx.asset_symbol max_size:10
HiveSignTx.memo max_size:2048

HiveSignedTx.signature max_size:65
HiveSignedTx.serialized_tx max_size:512

HiveSignAccountCreate.address_n max_count:8
HiveSignAccountCreate.chain_id max_size:32
HiveSignAccountCreate.creator max_size:16
HiveSignAccountCreate.new_account_name max_size:16
HiveSignAccountCreate.owner_key max_size:64
HiveSignAccountCreate.active_key max_size:64
HiveSignAccountCreate.posting_key max_size:64
HiveSignAccountCreate.memo_key max_size:64
HiveSignAccountCreate.fee_amount int_size:IS_64

HiveSignedAccountCreate.signature max_size:65
HiveSignedAccountCreate.serialized_tx max_size:512

HiveSignAccountUpdate.address_n max_count:8
HiveSignAccountUpdate.chain_id max_size:32
HiveSignAccountUpdate.account max_size:16
HiveSignAccountUpdate.new_owner_key max_size:64
HiveSignAccountUpdate.new_active_key max_size:64
HiveSignAccountUpdate.new_posting_key max_size:64
HiveSignAccountUpdate.new_memo_key max_size:64

HiveSignedAccountUpdate.signature max_size:65
HiveSignedAccountUpdate.serialized_tx max_size:512

HiveSignMessage.address_n max_count:8
HiveSignMessage.message max_size:1024

HiveSignedMessage.signature max_size:65
HiveSignedMessage.public_key max_size:33

HiveSignOperations.address_n max_count:8
HiveSignOperations.chain_id max_size:32
HiveSignOperations.serialized_tx max_size:2048

HiveSignedOperations.signature max_size:65
Loading
Loading