device_trezor: update protobuf definitions
What changed, and why it matters
This commit updates Monero's Trezor hardware wallet integration to match newer Trezor firmware protobuf definitions. It adds support for new device features (brightness, language packs, authenticity proofs, debug tools, etc.), renames some message types, and moves protobuf extension options into a separate file. There is no direct evidence in the commit that this fixes a security vulnerability; it appears to be a compatibility update to keep Monero working with current Trezor firmware.
Treat as a routine compatibility/maintenance update. Review the generated C++ code and any corresponding Trezor protocol implementation changes in related commits to confirm no behavioral security regressions were introduced by the new message definitions or direction changes.
Security signals we found
Large protobuf schema synchronization with upstream Trezor firmware
Monero transaction message directions corrected (wire_in vs wire_out)
Removal/reservation of deprecated passphrase-state message IDs
Addition of device-authentication and firmware-reboot message types
No C/C++ logic changes or bounds-checking patches present in diff
Evidence from the diff
The commit refreshes the vendored Trezor protobuf definitions from trezor-common commit bc28c316 to 06735a467. Key changes: adds options.proto and wires it into CMake; imports options.proto in place of inline descriptor extensions in messages.proto; adds/renames many MessageType enum values (e.g., Monero directions corrected from wire_out to wire_in, PaymentRequest, AuthenticateDevice, ChangeLanguage, THP, Solana, Tron, Nostr, etc.); adds new management/debug messages and fields; deprecates or removes old passphrase-state messages. The Monero-specific messages gain a chunkify display option and make some previously optional fields required. No runtime code logic changes are visible in the diff—only generated proto definitions and build lists.
Changed components
src/device_trezor/trezor/protob/*.protosrc/device_trezor/CMakeLists.txtcmake/CheckTrezor.cmakesrc/device_trezor/trezor/fetch_protob.shInspect captured patch +959 / −364
diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake
index b436e2d..effeac8 100644
--- a/cmake/CheckTrezor.cmake
+++ b/cmake/CheckTrezor.cmake
@@ -123,6 +123,7 @@ endif()
if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
# .proto files to compile
set(_proto_files "messages.proto"
+ "options.proto"
"messages-common.proto"
"messages-management.proto"
"messages-monero.proto")
diff --git a/src/device_trezor/CMakeLists.txt b/src/device_trezor/CMakeLists.txt
index 8da075a..80e932f 100644
--- a/src/device_trezor/CMakeLists.txt
+++ b/src/device_trezor/CMakeLists.txt
@@ -28,6 +28,7 @@
set(TREZOR_PROTOB_H
trezor/messages/messages.pb.h
+ trezor/messages/options.pb.h
trezor/messages/messages-common.pb.h
trezor/messages/messages-management.pb.h
trezor/messages/messages-monero.pb.h
@@ -35,6 +36,7 @@ set(TREZOR_PROTOB_H
set(TREZOR_PROTOB_CPP
trezor/messages/messages.pb.cc
+ trezor/messages/options.pb.cc
trezor/messages/messages-common.pb.cc
trezor/messages/messages-management.pb.cc
trezor/messages/messages-monero.pb.cc
diff --git a/src/device_trezor/trezor/fetch_protob.sh b/src/device_trezor/trezor/fetch_protob.sh
index 2ca138f..3b6c95e 100755
--- a/src/device_trezor/trezor/fetch_protob.sh
+++ b/src/device_trezor/trezor/fetch_protob.sh
@@ -9,13 +9,13 @@ fi
cd trezor-common
git fetch
-git reset --hard bc28c316d05bf1e9ebfe3d7df1ab25831d98d168
+git reset --hard 06735a46718edf383e453febf8a870fb71ae1789
cd ..
rm -rf protob
mkdir protob
-proto_files="messages.proto messages-common.proto messages-monero.proto messages-management.proto messages-debug.proto"
+proto_files="messages.proto messages-common.proto messages-monero.proto messages-management.proto messages-debug.proto options.proto"
for file in ${proto_files}
do
diff --git a/src/device_trezor/trezor/protob/messages-common.proto b/src/device_trezor/trezor/protob/messages-common.proto
index e7a0ac7..1e15784 100644
--- a/src/device_trezor/trezor/protob/messages-common.proto
+++ b/src/device_trezor/trezor/protob/messages-common.proto
@@ -1,20 +1,21 @@
syntax = "proto2";
package hw.trezor.messages.common;
+import "options.proto";
+
// Sugar for easier handling in Java
-option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageCommon";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+// Include in BTC-only firmware
option (include_in_bitcoin_only) = true;
-import "messages.proto";
-
/**
* Response: Success of the previous request
* @end
*/
message Success {
- optional string message = 1 [default=""]; // human readable description of action or request-specific payload
+ optional string message = 1 [default = ""]; // human readable description of action or request-specific payload
}
/**
@@ -39,6 +40,11 @@ message Failure {
Failure_PinMismatch = 12;
Failure_WipeCodeMismatch = 13;
Failure_InvalidSession = 14;
+ Failure_Busy = 15;
+ Failure_ThpUnallocatedSession = 16;
+ Failure_InvalidProtocol = 17;
+ reserved 18;
+ Failure_InProgress = 19;
Failure_FirmwareError = 99;
}
}
@@ -49,11 +55,18 @@ message Failure {
* @next ButtonAck
*/
message ButtonRequest {
- optional ButtonRequestType code = 1; // enum identifier of the screen
+ optional ButtonRequestType code = 1; // enum identifier of the screen (deprecated)
optional uint32 pages = 2; // if the screen is paginated, number of pages
+
+ // this existed briefly:
+ // https://github.com/trezor/trezor-firmware/commit/1012ee8497b241e8ca559e386d936fa549bc0357
+ reserved 3;
+
+ optional string name = 4; // name of the screen
+
/**
- * Type of button request
- */
+ * Type of button request
+ */
enum ButtonRequestType {
ButtonRequest_Other = 1;
ButtonRequest_FeeOverThreshold = 2;
@@ -68,7 +81,7 @@ message ButtonRequest {
ButtonRequest_PublicKey = 11;
ButtonRequest_MnemonicWordCount = 12;
ButtonRequest_MnemonicInput = 13;
- _Deprecated_ButtonRequest_PassphraseType = 14 [deprecated=true];
+ _Deprecated_ButtonRequest_PassphraseType = 14 [deprecated = true];
ButtonRequest_UnknownDerivationPath = 15;
ButtonRequest_RecoveryHomepage = 16;
ButtonRequest_Success = 17;
@@ -82,8 +95,7 @@ message ButtonRequest {
* Request: Computer agrees to wait for HW button press
* @auxend
*/
-message ButtonAck {
-}
+message ButtonAck {}
/**
* Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme
@@ -93,8 +105,8 @@ message ButtonAck {
message PinMatrixRequest {
optional PinMatrixRequestType type = 1;
/**
- * Type of PIN request
- */
+ * Type of PIN request
+ */
enum PinMatrixRequestType {
PinMatrixRequestType_Current = 1;
PinMatrixRequestType_NewFirst = 2;
@@ -109,7 +121,7 @@ message PinMatrixRequest {
* @auxend
*/
message PinMatrixAck {
- required string pin = 1; // matrix encoded PIN entered by user
+ required string pin = 1; // matrix encoded PIN entered by user
}
/**
@@ -118,7 +130,7 @@ message PinMatrixAck {
* @next PassphraseAck
*/
message PassphraseRequest {
- optional bool _on_device = 1 [deprecated=true]; // <2.3.0
+ reserved 1; // bool on_device, deprecated in 2.3.0
}
/**
@@ -127,27 +139,8 @@ message PassphraseRequest {
*/
message PassphraseAck {
optional string passphrase = 1;
- optional bytes _state = 2 [deprecated=true]; // <2.3.0
- optional bool on_device = 3; // user wants to enter passphrase on the device
-}
-
-/**
- * Response: Device awaits passphrase state
- * Deprecated in 2.3.0
- * @next Deprecated_PassphraseStateAck
- */
-message Deprecated_PassphraseStateRequest {
- option deprecated = true;
- optional bytes state = 1; // actual device state
-}
-
-/**
- * Request: Send passphrase state back
- * Deprecated in 2.3.0
- * @auxend
- */
-message Deprecated_PassphraseStateAck {
- option deprecated = true;
+ reserved 2; // bytes state, deprecated in 2.3.0
+ optional bool on_device = 3; // user wants to enter passphrase on the device
}
/**
@@ -163,3 +156,50 @@ message HDNodeType {
optional bytes private_key = 5;
required bytes public_key = 6;
}
+
+/**
+ * Structure representing a SLIP-0024 payment request.
+ * @embed
+ */
+message PaymentRequest {
+ optional bytes nonce = 1; // the nonce used in the signature computation
+ required string recipient_name = 2; // merchant's name
+ repeated PaymentRequestMemo memos = 3; // any memos that were signed as part of the request
+ reserved 4; // this existed briefly. obsoleted by this change:
+ // https://github.com/satoshilabs/slips/commit/08d36aa61722275a21617ac6a713e31ec23fdec4
+ optional bytes amount = 6; // the sum of the external output amounts requested, encoded in little endian on either
+ // 8 or 32 bytes required for non-CoinJoin transactions; do not set this for fiat
+ // amounts (BUY crypto with fiat)
+ required bytes signature = 5; // the trusted party's signature of the paymentRequestDigest
+
+ message PaymentRequestMemo {
+ optional TextMemo text_memo = 1;
+ optional RefundMemo refund_memo = 2;
+ optional CoinPurchaseMemo coin_purchase_memo = 3;
+ optional TextDetailsMemo text_details_memo = 4;
+ }
+
+ message TextMemo {
+ required string text = 1; // plain-text note explaining the purpose of the payment request
+ }
+
+ message TextDetailsMemo {
+ required string title = 1; // plain-text heading
+ required string text = 2; // plain-text note containing additional details about the payment
+ }
+
+ message RefundMemo {
+ required string address = 1; // the address where the payment should be refunded if necessary
+ repeated uint32 address_n = 2; // BIP-32 path to derive the key from the master node
+ required bytes mac = 3; // the MAC returned by GetAddress
+ }
+
+ message CoinPurchaseMemo {
+ required uint32 coin_type = 1; // the SLIP-0044 coin type of the address
+ required string amount = 2; // the amount the address will receive as a human-readable
+ // string including units, e.g. "0.025 BTC"
+ required string address = 3; // the address where the coin purchase will be delivered
+ repeated uint32 address_n = 4; // BIP-32 path to derive the key from the master node
+ required bytes mac = 5; // the MAC returned by GetAddress
+ }
+}
diff --git a/src/device_trezor/trezor/protob/messages-debug.proto b/src/device_trezor/trezor/protob/messages-debug.proto
index efe347b..f9ec44d 100644
--- a/src/device_trezor/trezor/protob/messages-debug.proto
+++ b/src/device_trezor/trezor/protob/messages-debug.proto
@@ -1,28 +1,29 @@
syntax = "proto2";
package hw.trezor.messages.debug;
+import "messages-common.proto";
+import "messages-management.proto";
+import "options.proto";
+
// Sugar for easier handling in Java
-option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageDebug";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+// Include in BTC-only firmware
option (include_in_bitcoin_only) = true;
-import "messages.proto";
-import "messages-common.proto";
-import "messages-management.proto";
-
/**
* Request: "Press" the button on the device
* @start
* @next DebugLinkLayout
*/
message DebugLinkDecision {
- optional DebugButton button = 1; // button press
+ optional DebugButton button = 1; // button press
optional DebugSwipeDirection swipe = 2; // swipe direction
- optional string input = 3; // keyboard input
+ optional string input = 3; // keyboard input
/**
- * Structure representing swipe direction
- */
+ * Structure representing swipe direction
+ */
enum DebugSwipeDirection {
UP = 0;
DOWN = 1;
@@ -31,26 +32,50 @@ message DebugLinkDecision {
}
/**
- * Structure representing button presses
- */
+ * Structure representing button presses
+ */
enum DebugButton {
NO = 0;
YES = 1;
INFO = 2;
}
- optional uint32 x = 4; // touch X coordinate
- optional uint32 y = 5; // touch Y coordinate
- optional bool wait = 6; // wait for layout change
- optional uint32 hold_ms = 7; // touch hold duration
+ /**
+ * Structure representing button presses of UI Caesar
+ */
+ // TODO: probably delete the middle_btn as it is not a physical one
+ enum DebugPhysicalButton {
+ LEFT_BTN = 0;
+ MIDDLE_BTN = 1;
+ RIGHT_BTN = 2;
+ }
+
+ optional uint32 x = 4; // touch X coordinate
+ optional uint32 y = 5; // touch Y coordinate
+ optional bool wait = 6 [deprecated = true]; // wait for layout change
+ optional uint32 hold_ms = 7; // touch hold duration
+ optional DebugPhysicalButton physical_button = 8; // physical button press
+
+ /**
+ * Explicit touch event type, used to separate TOUCH_START and TOUCH_END
+ * If not set, defaults to full click behavior (TOUCH_START + optional hold + TOUCH_END)
+ */
+ enum DebugTouchEventType {
+ TOUCH_FULL_CLICK = 0;
+ TOUCH_START = 1;
+ TOUCH_END = 2;
+ }
+
+ optional DebugTouchEventType touch_event_type = 9;
}
/**
- * Response: Device text layout
+ * Response: Device text layout as a list of tokens as returned by Rust
* @end
*/
message DebugLinkLayout {
- repeated string lines = 1;
+ option deprecated = true;
+ repeated string tokens = 1;
}
/**
@@ -68,18 +93,38 @@ message DebugLinkReseedRandom {
* @next Success
*/
message DebugLinkRecordScreen {
- optional string target_directory = 1; // empty or missing to stop recording
+ optional string target_directory = 1; // empty or missing to stop recording
+ optional uint32 refresh_index = 2 [default = 0]; // which index to give the screenshots (after emulator restarts)
}
/**
- * Request: Computer asks for device state
+ * Request: Host asks for device state
* @start
* @next DebugLinkState
*/
message DebugLinkGetState {
- optional bool wait_word_list = 1; // Trezor T only - wait until mnemonic words are shown
- optional bool wait_word_pos = 2; // Trezor T only - wait until reset word position is requested
- optional bool wait_layout = 3; // wait until current layout changes
+ /// Wait behavior of the call.
+ enum DebugWaitType {
+ /// Respond immediately. If no layout is currently displayed, the layout
+ /// response will be empty.
+ IMMEDIATE = 0;
+ /// Wait for next layout. If a layout is displayed, waits for it to change.
+ /// If no layout is displayed, waits for one to come up.
+ NEXT_LAYOUT = 1;
+ /// Return current layout. If no layout is currently displayed, waits for
+ /// one to come up.
+ CURRENT_LAYOUT = 2;
+ }
+
+ // Trezor T < 2.6.0 only - wait until mnemonic words are shown
+ optional bool wait_word_list = 1 [deprecated = true];
+ // Trezor T < 2.6.0 only - wait until reset word position is requested
+ optional bool wait_word_pos = 2 [deprecated = true];
+ // trezor-core only - wait until current layout changes
+ // changed in 2.6.4: multiple wait types instead of true/false.
+ optional DebugWaitType wait_layout = 3 [default = IMMEDIATE];
+ // Responds immediately with an empty `DebugLinkState` (used for client-side synchronization).
+ optional bool return_empty_state = 4 [default = false];
}
/**
@@ -87,28 +132,51 @@ message DebugLinkGetState {
* @end
*/
message DebugLinkState {
- optional bytes layout = 1; // raw buffer of display
- optional string pin = 2; // current PIN, blank if PIN is not set/enabled
- optional string matrix = 3; // current PIN matrix
- optional bytes mnemonic_secret = 4; // current mnemonic secret
- optional common.HDNodeType node = 5; // current BIP-32 node
- optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase?
- optional string reset_word = 7; // word on device display during ResetDevice workflow
- optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow
- optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow
- optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting during RecoveryDevice workflow
- optional uint32 reset_word_pos = 11; // index of mnemonic word the device is expecting during ResetDevice workflow
- optional management.BackupType mnemonic_type = 12; // current mnemonic type (BIP-39/SLIP-39)
- repeated string layout_lines = 13; // current layout text
+ optional bytes layout = 1; // raw buffer of display
+ optional string pin = 2; // current PIN, blank if PIN is not set/enabled
+ optional string matrix = 3; // current PIN matrix
+ optional bytes mnemonic_secret = 4; // current mnemonic secret
+ optional common.HDNodeType node = 5; // current BIP-32 node
+ optional bool passphrase_protection = 6; // is node/mnemonic encrypted using passphrase?
+ optional string reset_word = 7; // word on device display during ResetDevice workflow
+ optional bytes reset_entropy = 8; // current entropy during ResetDevice workflow
+ optional string recovery_fake_word = 9; // (fake) word on display during RecoveryDevice workflow
+ optional uint32 recovery_word_pos = 10; // index of mnemonic word the device is expecting
+ // during RecoveryDevice workflow
+ optional uint32 reset_word_pos = 11; // index of mnemonic word the device is expecting during ResetDevice workflow
+ optional management.BackupType mnemonic_type = 12; // current mnemonic type (BIP-39/SLIP-39)
+ repeated string tokens = 13; // current layout represented as a list of string tokens
}
/**
- * Request: Ask device to restart
+ * Request: Host asks for device pairing info
* @start
+ * @next DebugLinkPairingInfo
*/
-message DebugLinkStop {
+message DebugLinkGetPairingInfo {
+ optional bytes channel_id = 1; // ID of the THP channel to get pairing info from
+ optional bytes handshake_hash = 2; // handshake hash of the THP channel
+ optional bytes nfc_secret_host = 3; // host's NFC secret (In case of NFC pairing)
}
+/**
+ * Response: Device pairing info
+ * @end
+ */
+message DebugLinkPairingInfo {
+ optional bytes channel_id = 1; // ID of the THP channel the pairing info is from
+ optional bytes handshake_hash = 2; // handshake hash of the THP channel
+ optional uint32 code_entry_code = 3; // CodeEntry pairing code
+ optional bytes code_qr_code = 4; // QrCode pairing code
+ optional bytes nfc_secret_trezor = 5; // NFC secret used in NFC pairing
+}
+
+/**
+ * Request: Ask device to restart
+ * @start
+ */
+message DebugLinkStop {}
+
/**
* Response: Device wants host to log event
* @ignore
@@ -161,7 +229,6 @@ message DebugLinkFlashErase {
optional uint32 sector = 1;
}
-
/**
* Request: Erase the SD card
* @start
@@ -173,6 +240,20 @@ message DebugLinkEraseSdCard {
// if false, it will be all 0xFF bytes.
}
+/**
+ * Request: Set battery/power state on the emulator.
+ * @start
+ * @next Success
+ */
+message DebugLinkSetBatteryState {
+ optional uint32 soc = 1; // state of charge percentage (0-100)
+ optional bool usb_connected = 2; // USB cable connected
+ optional bool wireless_connected = 3; // wireless charging pad connected
+ optional bool ntc_connected = 4; // temperature sensor connected
+ optional bool charging_limited = 5; // charging current is limited
+ optional bool temp_control_active = 6; // temperature control is limiting charging
+ optional bool battery_connected = 7; // battery is physically connected
+}
/**
* Request: Start or stop tracking layout changes
@@ -180,6 +261,93 @@ message DebugLinkEraseSdCard {
* @next Success
*/
message DebugLinkWatchLayout {
+ option deprecated = true;
optional bool watch = 1; // if true, start watching layout.
// if false, stop.
}
+
+/**
+ * Request: Remove all the previous debug event state
+ * @start
+ * @next Success
+ */
+message DebugLinkResetDebugEvents {
+ option deprecated = true;
+}
+
+/**
+ * Request: Set Optiga's security even counter to maximum
+ * @start
+ * @next Success
+ */
+message DebugLinkOptigaSetSecMax {}
+
+/**
+ * Request: Get GC heap information.
+ * @start
+ * @next DebugLinkGcInfo
+ */
+message DebugLinkGetGcInfo {}
+
+/**
+ * Response: GC heap information details.
+ * @end
+ */
+message DebugLinkGcInfo {
+ repeated DebugLinkGcInfoItem items = 1;
+
+ /**
+ * Key-value pair.
+ */
+ message DebugLinkGcInfoItem {
+ required string name = 1;
+ required uint64 value = 2;
+ }
+}
+
+/**
+ * Request: Set logging filter string.
+ * @start
+ * @next Success
+ */
+message DebugLinkSetLogFilter {
+ optional string filter = 1; // filter string
+}
+
+/**
+ * Request: Start N4W1 exchange over DebugLink (initiated by the host).
+ * Blocks until there is a N4W1 request to be handled.
+ * @start
+ * @next DebugLinkN4W1Read
+ * @next DebugLinkN4W1Write
+ */
+message DebugLinkN4W1Connected {}
+
+/**
+ * Request: Simulate N4W1 write over DebugLink (sent by the device).
+ * @start
+ * @next DebugLinkN4W1Response
+ */
+message DebugLinkN4W1Write {
+ optional string key = 1;
+ optional bytes value = 2; // if is None, the entry is deleted
+}
+
+/**
+ * Request: Simulate N4W1 read over DebugLink (sent by the device).
+ * @start
+ * @next DebugLinkN4W1Response
+ */
+message DebugLinkN4W1Read {
+ optional string key = 1;
+}
+
+/**
+ * Response: Simulate N4W1 read/write result over DebugLink (sent by the host).
+ * @next DebugLinkN4W1Read
+ * @next DebugLinkN4W1Write
+ * @next Success
+ */
+message DebugLinkN4W1Response {
+ optional bytes value = 1; // existing value is returned on write/delete, `None` if key is missing
+}
diff --git a/src/device_trezor/trezor/protob/messages-management.proto b/src/device_trezor/trezor/protob/messages-management.proto
index 590575f..97cdae8 100644
--- a/src/device_trezor/trezor/protob/messages-management.proto
+++ b/src/device_trezor/trezor/protob/messages-management.proto
@@ -1,21 +1,33 @@
syntax = "proto2";
package hw.trezor.messages.management;
+import "options.proto";
+
// Sugar for easier handling in Java
-option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageManagement";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+// Include in BTC-only firmware
option (include_in_bitcoin_only) = true;
-import "messages.proto";
-
/**
* Type of the mnemonic backup given/received by the device during reset/recovery.
*/
enum BackupType {
- Bip39 = 0; // also called "Single Backup", see BIP-0039
- Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039
- Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme
+ Bip39 = 0; // also called "Single Backup", see BIP-0039
+ Slip39_Basic = 1; // also called "Shamir Backup", see SLIP-0039
+ Slip39_Advanced = 2; // also called "Super Shamir" or "Shamir with Groups", see SLIP-0039#two-level-scheme
+ Slip39_Single_Extendable = 3; // extendable single-share Shamir backup
+ Slip39_Basic_Extendable = 4; // extendable multi-share Shamir backup
+ Slip39_Advanced_Extendable = 5; // extendable multi-share Shamir backup with groups
+}
+
+/**
+ * Backup method of the mnemonic shares.
+ */
+enum BackupMethod {
+ Display = 0; // the share words are displayed on the device screen
+ N4W1 = 1;
}
/**
@@ -27,13 +39,23 @@ enum SafetyCheckLevel {
PromptTemporarily = 2; // like PromptAlways but reverts to Strict after reboot
}
+/**
+ * Allowed display rotation angles (in degrees from North)
+ */
+enum DisplayRotation {
+ North = 0;
+ East = 90;
+ South = 180;
+ West = 270;
+}
/**
* Format of the homescreen image
*/
enum HomescreenFormat {
- Toif144x144 = 1;
- Jpeg240x240 = 2;
+ Toif = 1; // full-color toif
+ Jpeg = 2; // jpeg
+ ToiG = 3; // greyscale toif
}
/**
@@ -42,8 +64,8 @@ enum HomescreenFormat {
* @next Features
*/
message Initialize {
- optional bytes session_id = 1; // assumed device session id; Trezor clears caches if it is different or empty
- optional bool _skip_passphrase = 2 [deprecated=true]; // removed as part of passphrase redesign
+ optional bytes session_id = 1; // assumed device session id; Trezor clears caches if it is different or empty
+ optional bool _skip_passphrase = 2 [deprecated = true]; // removed as part of passphrase redesign
optional bool derive_cardano = 3; // whether to derive Cardano Icarus root keys in this session
}
@@ -52,49 +74,100 @@ message Initialize {
* @start
* @next Features
*/
-message GetFeatures {
-}
+message GetFeatures {}
/**
* Response: Reports various information about the device
* @end
*/
message Features {
- optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io"
- required uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1
- required uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0
- required uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0
- optional bool bootloader_mode = 5; // is device in bootloader mode?
- optional string device_id = 6; // device's unique identifier
- optional bool pin_protection = 7; // is device protected by PIN?
- optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase?
- optional string language = 9; // device language
- optional string label = 10; // device description label
- optional bool initialized = 12; // does device contain seed?
- optional bytes revision = 13; // SCM revision of firmware
- optional bytes bootloader_hash = 14; // hash of the bootloader
- optional bool imported = 15; // was storage imported from an external source?
- optional bool unlocked = 16; // is the device unlocked? called "pin_cached" previously
- optional bool _passphrase_cached = 17 [deprecated=true]; // is passphrase already cached in session?
- optional bool firmware_present = 18; // is valid firmware loaded?
- optional bool needs_backup = 19; // does storage need backup? (equals to Storage.needs_backup)
- optional uint32 flags = 20; // device flags (equals to Storage.flags)
- optional string model = 21; // device hardware model
- optional uint32 fw_major = 22; // reported firmware version if in bootloader mode
- optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode
- optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode
- optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode
- // optional bytes fw_vendor_keys = 26; // obsoleted, use fw_vendor
- optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup)
- optional bool no_backup = 28; // report no backup (equals to Storage.no_backup)
- optional bool recovery_mode = 29; // is recovery mode in progress
- repeated Capability capabilities = 30; // list of supported capabilities
+ optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io"
+ required uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1
+ required uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0
+ required uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0
+ optional uint32 build_version = 61; // build version of the firmware/bootloader, e.g. 0
+ optional bool bootloader_mode = 5; // is device in bootloader mode?
+ optional string device_id = 6; // device's unique identifier
+ optional bool pin_protection = 7; // is device protected by PIN?
+ optional bool passphrase_protection = 8; // is node/mnemonic encrypted using passphrase?
+ optional string language = 9; // device language
+ optional string label = 10; // device description label
+ optional bool initialized = 12; // does device contain seed?
+ optional bytes revision = 13; // SCM revision of firmware
+ optional bytes bootloader_hash = 14; // hash of the bootloader
+ optional bool imported = 15; // was storage imported from an external source?
+ optional bool unlocked = 16; // is the device unlocked? called "pin_cached" previously
+ optional bool _passphrase_cached = 17 [deprecated = true]; // is passphrase already cached in session?
+ optional bool firmware_present = 18; // is firmware loaded?
+ optional BackupAvailability backup_availability = 19; // does storage need backup? is repeated backup unlocked?
+ optional uint32 flags = 20; // device flags (equals to Storage.flags)
+ optional string model = 21; // device hardware model
+ optional uint32 fw_major = 22; // reported firmware version if in bootloader mode
+ optional uint32 fw_minor = 23; // reported firmware version if in bootloader mode
+ optional uint32 fw_patch = 24; // reported firmware version if in bootloader mode
+ optional uint32 fw_build = 62; // reported firmware version if in bootloader mode
+ optional string fw_vendor = 25; // reported firmware vendor if in bootloader mode
+ // optional bytes fw_vendor_keys = 26; // obsoleted, use fw_vendor
+ optional bool unfinished_backup = 27; // report unfinished backup (equals to Storage.unfinished_backup)
+ optional bool no_backup = 28; // report no backup (equals to Storage.no_backup)
+ optional RecoveryStatus recovery_status = 29; // whether or not we are in recovery mode and of what kind
+ repeated Capability capabilities = 30; // list of supported capabilities
+ optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced)
+ optional bool sd_card_present = 32; // is SD card present
+ optional bool sd_protection = 33; // is SD Protect enabled
+ optional bool wipe_code_protection = 34; // is wipe code protection enabled
+ optional bytes session_id = 35;
+ optional bool passphrase_always_on_device = 36; // device enforces passphrase entry on Trezor
+ optional SafetyCheckLevel safety_checks = 37; // safety check level, set to Prompt to limit path
+ // namespace enforcement
+ optional uint32 auto_lock_delay_ms = 38; // number of milliseconds after which the device locks itself
+ optional DisplayRotation display_rotation = 39; // rotation of display (in degrees from North)
+ optional bool experimental_features = 40; // are experimental message types enabled?
+ optional bool busy = 41; // is the device busy, showing "Do not disconnect"?
+ optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf, 2 = jpg, 3 = TOIG
+ optional bool hide_passphrase_from_host = 43; // should we hide the passphrase when it comes from host?
+ optional string internal_model = 44; // internal model name
+ optional uint32 unit_color = 45; // color of the unit/device
+ optional bool unit_btconly = 46; // unit/device is intended as bitcoin only
+ optional uint32 homescreen_width = 47; // homescreen width in pixels
+ optional uint32 homescreen_height = 48; // homescreen height in pixels
+ optional bool bootloader_locked = 49; // bootloader is locked
+ optional bool language_version_matches = 50 [default = true]; // translation blob version matches firmware version
+ optional uint32 unit_packaging = 51; // unit/device packaging version
+ optional bool haptic_feedback = 52; // haptic feedback is enabled
+ optional RecoveryType recovery_type = 53; // what type of recovery we are in
+ // NB: this works in conjunction with recovery_status
+ optional uint32 optiga_sec = 54; // Optiga's security event counter.
+ optional uint32 soc = 55; // Battery state of charge (0 - 100%)
+ optional bool firmware_corrupted = 56; // true if the firmware is corrupted
+ optional uint32 auto_lock_delay_battery_ms = 57; // number of milliseconds after which
+ // the battery-powered device locks itself
+ optional bool led = 58; // RGB LED settings
+ optional bool usb_connected = 59; // USB connected
+ optional bool wireless_connected = 60; // Wireless charger connected
+ optional bool tap_to_wake = 63; // tap to wake is enabled (None = not supported)
+
+ enum BackupAvailability {
+ /// Device is already backed up, or a previous backup has failed.
+ NotAvailable = 0;
+ /// Device is not backed up. Backup is required.
+ Required = 1;
+ /// Device is already backed up and can be backed up again.
+ Available = 2;
+ }
+
+ enum RecoveryStatus {
+ Nothing = 0; // we are not in recovery mode
+ Recovery = 1; // we are in "Normal" or "DryRun" recovery
+ Backup = 2; // we are in repeated backup mode
+ }
+
enum Capability {
option (has_bitcoin_only_values) = true;
Capability_Bitcoin = 1 [(bitcoin_only) = true];
Capability_Bitcoin_like = 2; // Altcoins based on the Bitcoin source code
- Capability_Binance = 3;
+ Capability_Binance = 3; // BNB Smart Chain
Capability_Cardano = 4;
Capability_Crypto = 5 [(bitcoin_only) = true]; // generic crypto operations for GPG, SSH, etc.
Capability_EOS = 6;
@@ -108,21 +181,19 @@ message Features {
Capability_U2F = 14;
Capability_Shamir = 15 [(bitcoin_only) = true];
Capability_ShamirGroups = 16 [(bitcoin_only) = true];
- Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry directly on the device
+ Capability_PassphraseEntry = 17 [(bitcoin_only) = true]; // the device is capable of passphrase entry
+ // directly on the device
+ Capability_Solana = 18;
+ Capability_Translations = 19 [(bitcoin_only) = true];
+ Capability_Brightness = 20 [(bitcoin_only) = true];
+ Capability_Haptic = 21 [(bitcoin_only) = true];
+ Capability_BLE = 22 [(bitcoin_only) = true]; // Bluetooth Low Energy
+ Capability_NFC = 23 [(bitcoin_only) = true]; // Near Field Communications
+ Capability_Tron = 24;
+ Capability_N4W1 = 25 [(bitcoin_only) = true];
+ Capability_TouchWakeup = 26 [(bitcoin_only) = true]; // Touch to wake from sleep
+ reserved 27; // reserved for internal use
}
- optional BackupType backup_type = 31; // type of device backup (BIP-39 / SLIP-39 basic / SLIP-39 advanced)
- optional bool sd_card_present = 32; // is SD card present
- optional bool sd_protection = 33; // is SD Protect enabled
- optional bool wipe_code_protection = 34; // is wipe code protection enabled
- optional bytes session_id = 35;
- optional bool passphrase_always_on_device = 36; // device enforces passphrase entry on Trezor
- optional SafetyCheckLevel safety_checks = 37; // safety check level, set to Prompt to limit path namespace enforcement
- optional uint32 auto_lock_delay_ms = 38; // number of milliseconds after which the device locks itself
- optional uint32 display_rotation = 39; // in degrees from North
- optional bool experimental_features = 40; // are experimental message types enabled?
- optional bool busy = 41; // is the device busy, showing "Do not disconnect"?
- optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf 144x144, 2 = jpg 240x240
- optional bool hide_passphrase_from_host = 43; // should we hide the passphrase when it comes from host?
}
/**
@@ -130,8 +201,7 @@ message Features {
* @start
* @next Success
*/
-message LockDevice {
-}
+message LockDevice {}
/**
* Request: Show a "Do not disconnect" dialog instead of the standard homescreen.
@@ -139,37 +209,84 @@ message LockDevice {
* @next Success
*/
message SetBusy {
- optional uint32 expiry_ms = 1; // The time in milliseconds after which the dialog will automatically disappear. Overrides any previously set expiry. If not set, then the dialog is hidden.
+ optional uint32 expiry_ms = 1; // The time in milliseconds after which the dialog will automatically disappear.
+ // Overrides any previously set expiry. If not set, then the dialog is hidden.
}
/**
- * Request: end the current session. Following actions must call Initialize again.
+ * Request: end the current sesson. Following actions must call Initialize again.
* Cache for the current session is discarded, other sessions remain intact.
* Device is not PIN-locked.
* @start
* @next Success
*/
-message EndSession {
-}
+message EndSession {}
/**
- * Request: change language and/or label of the device
+ * Request: change some property of the device, e.g. label or homescreen
* @start
* @next Success
+ * @next DataChunkRequest
* @next Failure
*/
message ApplySettings {
- optional string language = 1;
+ optional string language = 1 [deprecated = true];
optional string label = 2;
optional bool use_passphrase = 3;
- optional bytes homescreen = 4;
- optional uint32 _passphrase_source = 5 [deprecated=true]; // ASK = 0; DEVICE = 1; HOST = 2;
+ optional bytes homescreen = 4; // homescreen image in single array, deprecated for 14
+ optional uint32 _passphrase_source = 5 [deprecated = true]; // ASK = 0; DEVICE = 1; HOST = 2;
optional uint32 auto_lock_delay_ms = 6;
- optional uint32 display_rotation = 7; // in degrees from North
- optional bool passphrase_always_on_device = 8; // do not prompt for passphrase, enforce device entry
- optional SafetyCheckLevel safety_checks = 9; // Safety check level, set to Prompt to limit path namespace enforcement
- optional bool experimental_features = 10; // enable experimental message types
- optional bool hide_passphrase_from_host = 11; // do not show passphrase coming from host
+ optional DisplayRotation display_rotation = 7; // rotation of display (in degrees from North)
+ optional bool passphrase_always_on_device = 8; // do not prompt for passphrase, enforce device entry
+ optional SafetyCheckLevel safety_checks = 9; // Safety check level,
+ // set to Prompt to limit path namespace enforcement
+ optional bool experimental_features = 10; // enable experimental message types
+ optional bool hide_passphrase_from_host = 11; // do not show passphrase coming from host
+ optional bool haptic_feedback = 13; // enable haptic feedback
+ optional uint32 homescreen_length = 14; // byte length of new homescreen, device will request chunks
+ optional uint32 auto_lock_delay_battery_ms = 15; // time in ms after which device locks when on battery
+ // or wireless charger
+}
+
+/**
+ * Request: change the device language via translation data.
+ * Does not send the translation data itself, as they are too large for one message.
+ * Device will request the translation data in chunks.
+ * @start
+ * @next DataChunkRequest
+ * @next Failure
+ */
+message ChangeLanguage {
+ // byte length of the whole translation blob (set to 0 for default language - english)
+ required uint32 data_length = 1;
+ // Prompt the user on screen.
+ // In certain conditions (such as freshly installed device), the confirmation prompt
+ // is not mandatory. Setting show_display=false will skip the prompt if that's
+ // the case. If the device does not allow skipping the prompt, a request with
+ // show_display=false will return a failure. (This way the host can safely try
+ // to change the language without invoking a prompt.)
+ // Setting show_display to true will always show the prompt.
+ // Leaving the option unset will show the prompt only when necessary.
+ optional bool show_display = 2;
+}
+
+/**
+ * Response: Device asks for more data from translation/homescreen image.
+ * @end
+ * @next DataChunkAck
+ */
+message DataChunkRequest {
+ required uint32 data_length = 1; // Number of bytes being requested
+ required uint32 data_offset = 2; // Offset of the first byte being requested
+}
+
+/**
+ * Request: Translation/homescreen payload data.
+ * @next DataChunkRequest
+ * @next Success
+ */
+message DataChunkAck {
+ required bytes data_chunk = 1; // Bytes from translation/homescreen payload
}
/**
@@ -189,7 +306,7 @@ message ApplyFlags {
* @next Failure
*/
message ChangePin {
- optional bool remove = 1; // is PIN removal requested?
+ optional bool remove = 1; // is PIN removal requested?
}
/**
@@ -199,7 +316,7 @@ message ChangePin {
* @next Failure
*/
message ChangeWipeCode {
- optional bool remove = 1; // is wipe code removal requested?
+ optional bool remove = 1; // is wipe code removal requested?
}
/**
@@ -211,8 +328,8 @@ message ChangeWipeCode {
message SdProtect {
required SdProtectOperationType operation = 1;
/**
- * Structure representing SD card protection operation
- */
+ * Structure representing SD card protection operation
+ */
enum SdProtectOperationType {
DISABLE = 0;
ENABLE = 1;
@@ -226,8 +343,8 @@ message SdProtect {
* @next Success
*/
message Ping {
- optional string message = 1 [default=""]; // message to send back in Success message
- optional bool button_protection = 2; // ask for button press
+ optional string message = 1 [default = ""]; // message to send back in Success message
+ optional bool button_protection = 2; // ask for button press
}
/**
@@ -235,8 +352,7 @@ message Ping {
* @start
* @next Failure
*/
-message Cancel {
-}
+message Cancel {}
/**
* Request: Request a sample of random data generated by hardware RNG. May be used for testing.
@@ -245,7 +361,7 @@ message Cancel {
* @next Failure
*/
message GetEntropy {
- required uint32 size = 1; // size of requested entropy
+ required uint32 size = 1; // size of requested entropy
}
/**
@@ -253,7 +369,7 @@ message GetEntropy {
* @end
*/
message Entropy {
- required bytes entropy = 1; // chunk of random generated bytes
+ required bytes entropy = 1; // chunk of random generated bytes
}
/**
@@ -263,7 +379,7 @@ message Entropy {
* @next Failure
*/
message GetFirmwareHash {
- optional bytes challenge = 1; // Blake2s key up to 32 bytes in length.
+ optional bytes challenge = 1; // Blake2s key up to 32 bytes in length.
}
/**
@@ -274,14 +390,85 @@ message FirmwareHash {
required bytes hash = 1;
}
+/**
+ * Request: Request a signature of the provided challenge.
+ * @start
+ * @next AuthenticityProof
+ * @next AuthenticityProofSizes
+ * @next Failure
+ */
+message AuthenticateDevice {
+ required bytes challenge = 1; // A random challenge to sign.
+ optional bool stream = 2; // If set, the certificates and signatures data is sent using a stream of
+ // AuthenticityProofChunk responses (to avoid sending one large response).
+}
+
+/**
+ * Response: Signature of the provided challenge along with a certificate issued by the Trezor company.
+ * @end
+ */
+message AuthenticityProof {
+ repeated bytes optiga_certificates = 1; // A certificate chain starting with the Optiga device certificate,
+ // followed by intermediate CA certificates, the last of which is signed by
+ // Trezor company's root CA.
+ required bytes optiga_signature = 2; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed
+ // challenge that should be verified using the Optiga device certificate.
+ repeated bytes tropic_certificates = 3; // A certificate chain starting with the Tropic device certificate,
+ // followed by intermediate CA certificates, the last of which is signed by
+ // Trezor company's root CA.
+ optional bytes tropic_signature = 4; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed
+ // challenge that should be verified using the Tropic device certificate.
+ repeated bytes mcu_certificates = 5; // An MCU device certificate signed by Trezor company's root CA.
+ optional bytes mcu_signature = 6; // A DER-encoded signature of "\x13AuthenticateDevice:" + length-prefixed
+ // challenge that should be verified using the MCU device certificate.
+}
+
+/**
+ * Response: Sizes of the corresponding proof parts (see above).
+ * @next GetAuthenticityProofChunk
+ */
+message AuthenticityProofSizes {
+ repeated uint32 optiga_certificates = 1;
+ required uint32 optiga_signature = 2;
+ repeated uint32 tropic_certificates = 3;
+ optional uint32 tropic_signature = 4;
+ repeated uint32 mcu_certificates = 5;
+ optional uint32 mcu_signature = 6;
+}
+
+/**
+ * Request: Request authenticity proof data chunk, or finish the workflow if `proof_type` is not set.
+ * @next AuthenticityProofChunk
+ * @next Success
+ */
+message GetAuthenticityProofChunk {
+ optional AuthenticityProofType proof_type = 1; // Specifies proof part to fetch.
+ optional uint32 index = 2; // If set, certificates[index] is fetched. Otherwise, signature is fetched.
+ required uint32 offset = 3; // Data chunk offset (in bytes).
+ required uint32 size = 4; // Data chunk size (in bytes).
+
+ enum AuthenticityProofType {
+ OPTIGA = 0;
+ TROPIC = 1;
+ MCU = 2;
+ }
+}
+
+/**
+ * Response: Return requested authenticity proof data chunk.
+ * @next GetAuthenticityProofChunk
+ */
+message AuthenticityProofChunk {
+ required bytes chunk = 1;
+}
+
/**
* Request: Request device to wipe all sensitive data and settings
* @start
* @next Success
* @next Failure
*/
-message WipeDevice {
-}
+message WipeDevice {}
/**
* Request: Load seed and related internal settings from the computer
@@ -290,15 +477,16 @@ message WipeDevice {
* @next Failure
*/
message LoadDevice {
- repeated string mnemonics = 1; // seed encoded as mnemonic (12, 18 or 24 words for BIP39, 20 or 33 for SLIP39)
- optional string pin = 3; // set PIN protection
- optional bool passphrase_protection = 4; // enable master node encryption using passphrase
- optional string language = 5 [default='en-US']; // device language (IETF BCP 47 language tag)
- optional string label = 6; // device label
- optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum
- optional uint32 u2f_counter = 8; // U2F counter
- optional bool needs_backup = 9; // set "needs backup" flag
- optional bool no_backup = 10; // indicate that no backup is going to be made
+ repeated string mnemonics = 1; // seed encoded as mnemonic (12, 18 or 24 words for BIP39, 20 or 33 for SLIP39)
+ optional string pin = 3; // set PIN protection
+ optional bool passphrase_protection = 4; // enable master node encryption using passphrase
+ optional string language = 5 [deprecated = true]; // deprecated (use ChangeLanguage)
+ optional string label = 6; // device label
+ optional bool skip_checksum = 7; // do not test mnemonic for valid BIP-39 checksum
+ optional uint32 u2f_counter = 8; // U2F counter
+ optional bool needs_backup = 9; // set "needs backup" flag
+ optional bool no_backup = 10; // indicate that no backup is going to be made
+ optional bool unfinished_backup = 11; // indicate that backup process has failed
}
/**
@@ -308,16 +496,18 @@ message LoadDevice {
* @next Failure
*/
message ResetDevice {
- optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy
- optional uint32 strength = 2 [default=256]; // strength of seed in bits
- optional bool passphrase_protection = 3; // enable master node encryption using passphrase
- optional bool pin_protection = 4; // enable PIN protection
- optional string language = 5 [default='en-US']; // device language (IETF BCP 47 language tag)
- optional string label = 6; // device label
- optional uint32 u2f_counter = 7; // U2F counter
- optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow
- optional bool no_backup = 9; // indicate that no backup is going to be made
- optional BackupType backup_type = 10 [default=Bip39]; // type of the mnemonic backup
+ reserved 1; // unused display_random
+ optional uint32 strength = 2 [default = 256]; // strength of seed in bits
+ optional bool passphrase_protection = 3; // enable master node encryption using passphrase
+ optional bool pin_protection = 4; // enable PIN protection
+ optional string language = 5 [deprecated = true]; // deprecated (use ChangeLanguage)
+ optional string label = 6; // device label
+ optional uint32 u2f_counter = 7; // U2F counter
+ optional bool skip_backup = 8; // postpone seed backup to BackupDevice workflow
+ optional bool no_backup = 9; // indicate that no backup is going to be made
+ optional BackupType backup_type = 10 [default = Bip39]; // type of the mnemonic backup
+ optional bool entropy_check = 11; // run with entropy check protocol
+ optional BackupMethod backup_method = 12 [default = Display]; // how the mnemonic shares should be backed up
}
/**
@@ -326,6 +516,13 @@ message ResetDevice {
* @next Success
*/
message BackupDevice {
+ optional uint32 group_threshold = 1;
+ message Slip39Group {
+ required uint32 member_threshold = 1;
+ required uint32 member_count = 2;
+ }
+ repeated Slip39Group groups = 2;
+ optional BackupMethod backup_method = 3 [default = Display]; // how the mnemonic shares should be backed up
}
/**
@@ -333,14 +530,34 @@ message BackupDevice {
* @next EntropyAck
*/
message EntropyRequest {
+ optional bytes entropy_commitment = 1; // HMAC-SHA256 of Trezor's internal entropy used in entropy check.
+ optional bytes prev_entropy = 2; // Trezor's internal entropy from the previous round of entropy check.
}
/**
* Request: Provide additional entropy for seed generation function
* @next Success
+ * @next EntropyCheckReady
*/
message EntropyAck {
- required bytes entropy = 1; // 256 bits (32 bytes) of random data
+ required bytes entropy = 1; // 256 bits (32 bytes) of the host's random data
+}
+
+/**
+ * Response: Trezor is ready for the next phase of the entropy check protocol.
+ * @next EntropyCheckContinue
+ * @next GetPublicKey
+ */
+message EntropyCheckReady {}
+
+/**
+ * Request: Proceed with the next phase of the entropy check protocol, asking Trezor to either reveal its internal
+ * entropy or to finish and store the seed.
+ * @next Success
+ * @next EntropyRequest
+ */
+message EntropyCheckContinue {
+ optional bool finish = 1 [default = false]; // finish the entropy check protocol, store the seed
}
/**
@@ -350,31 +567,38 @@ message EntropyAck {
* @next WordRequest
*/
message RecoveryDevice {
- optional uint32 word_count = 1; // number of words in BIP-39 mnemonic
- optional bool passphrase_protection = 2; // enable master node encryption using passphrase
- optional bool pin_protection = 3; // enable PIN protection
- optional string language = 4; // device language (IETF BCP 47 language tag)
- optional string label = 5; // device label
- optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process
- // 7 reserved for unused recovery method
- optional RecoveryDeviceType type = 8; // supported recovery type
- optional uint32 u2f_counter = 9; // U2F counter
- optional bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation)
+ optional uint32 word_count = 1; // number of words in BIP-39 mnemonic (T1 only)
+ optional bool passphrase_protection = 2; // enable master node encryption using passphrase
+ optional bool pin_protection = 3; // enable PIN protection
+ optional string language = 4 [deprecated = true]; // deprecated (use ChangeLanguage)
+ optional string label = 5; // device label
+ optional bool enforce_wordlist = 6; // enforce BIP-39 wordlist during the process (T1 only)
+ reserved 7; // unused recovery method
+ optional RecoveryDeviceInputMethod input_method = 8; // supported recovery input method (T1 only)
+ optional uint32 u2f_counter = 9; // U2F counter
+ optional RecoveryType type = 10 [default = NormalRecovery]; // the type of recovery to perform
+ optional BackupMethod backup_method = 11; // how the shares should be recovered from backup
/**
* Type of recovery procedure. These should be used as bitmask, e.g.,
- * `RecoveryDeviceType_ScrambledWords | RecoveryDeviceType_Matrix`
+ * `RecoveryDeviceInputMethod_ScrambledWords | RecoveryDeviceInputMethod_Matrix`
* listing every method supported by the host computer.
*
- * Note that ScrambledWords must be supported by every implementation
- * for backward compatibility; there is no way to not support it.
+ * Note that Matrix recovery is the recommended recovery method. ScrambledWords
+ * is allowed only for 24 word recovery, unless safety checks are disabled.
*/
- enum RecoveryDeviceType {
+ enum RecoveryDeviceInputMethod {
// use powers of two when extending this field
- RecoveryDeviceType_ScrambledWords = 0; // words in scrambled order
- RecoveryDeviceType_Matrix = 1; // matrix recovery type
+ ScrambledWords = 0; // words in scrambled order
+ Matrix = 1; // matrix recovery type
}
}
+enum RecoveryType {
+ NormalRecovery = 0; // recovery from seedphrase on an uninitialized device
+ DryRun = 1; // mnemonic validation
+ UnlockRepeatedBackup = 2; // unlock SLIP-39 repeated backup
+}
+
/**
* Response: Device is waiting for user to enter word of the mnemonic
* Its position is shown only on device's internal display.
@@ -383,8 +607,8 @@ message RecoveryDevice {
message WordRequest {
required WordRequestType type = 1;
/**
- * Type of Recovery Word request
- */
+ * Type of Recovery Word request
+ */
enum WordRequestType {
WordRequestType_Plain = 0;
WordRequestType_Matrix9 = 1;
@@ -399,7 +623,7 @@ message WordRequest {
* @next Failure
*/
message WordAck {
- required string word = 1; // one word of mnemonic on asked position
+ required string word = 1; // one word of mnemonic on asked position
}
/**
@@ -416,8 +640,7 @@ message SetU2FCounter {
* @start
* @next NextU2FCounter
*/
-message GetNextU2FCounter {
-}
+message GetNextU2FCounter {}
/**
* Request: Set U2F counter
@@ -433,8 +656,7 @@ message NextU2FCounter {
* @next PreauthorizedRequest
* @next Failure
*/
-message DoPreauthorized {
-}
+message DoPreauthorized {}
/**
* Request: Device awaits a preauthorized operation.
@@ -442,8 +664,7 @@ message DoPreauthorized {
* @next SignTx
* @next GetOwnershipProof
*/
-message PreauthorizedRequest {
-}
+message PreauthorizedRequest {}
/**
* Request: Cancel any outstanding authorization in the current session.
@@ -451,15 +672,28 @@ message PreauthorizedRequest {
* @next Success
* @next Failure
*/
-message CancelAuthorization {
-}
+message CancelAuthorization {}
/**
* Request: Reboot firmware to bootloader
* @start
* @next Success
+ * @next DataChunkRequest
*/
message RebootToBootloader {
+ // Action to be performed after rebooting to bootloader
+ optional BootCommand boot_command = 1 [default = STOP_AND_WAIT];
+ // Firmware header to be flashed after rebooting to bootloader
+ optional bytes firmware_header = 2;
+ // Deprecated (length of language blob to be installed before upgrading firmware)
+ reserved 3;
+
+ enum BootCommand {
+ // Go to bootloader menu
+ STOP_AND_WAIT = 0;
+ // Connect to host and wait for firmware update
+ INSTALL_UPGRADE = 1;
+ }
}
/**
@@ -467,18 +701,14 @@ message RebootToBootloader {
* @start
* @next Nonce
*/
-message GetNonce {
- option (experimental_message) = true;
-}
+message GetNonce {}
/**
* Response: Contains a random nonce
* @end
*/
message Nonce {
- option (experimental_message) = true;
-
- required bytes nonce = 1; // a 32-byte random value generated by Trezor
+ required bytes nonce = 1; // a 32-byte random value generated by Trezor
}
/**
@@ -488,8 +718,8 @@ message Nonce {
* @next Failure
*/
message UnlockPath {
- repeated uint32 address_n = 1; // prefix of the BIP-32 path leading to the account (m / purpose')
- optional bytes mac = 2; // the MAC returned by UnlockedPathRequest
+ repeated uint32 address_n = 1; // prefix of the BIP-32 path leading to the account (m / purpose')
+ optional bytes mac = 2; // the MAC returned by UnlockedPathRequest
}
/**
@@ -500,5 +730,44 @@ message UnlockPath {
* @next GetAddress
*/
message UnlockedPathRequest {
- optional bytes mac = 1; // authentication code for future UnlockPath calls
+ required bytes mac = 1; // authentication code for future UnlockPath calls
+}
+
+/**
+ * Request: Show tutorial screens on the device
+ * @start
+ * @next Success
+ */
+message ShowDeviceTutorial {}
+
+/**
+ * Request: Unlocks bootloader, !irreversible!
+ * @start
+ * @next Success
+ * @next Failure
+ */
+message UnlockBootloader {}
+
+/**
+ * Request: Set device brightness
+ * @start
+ * @next Success
+ */
+message SetBrightness {
+ optional uint32 value = 1; // if not specified, let the user choose
+}
+
+/**
+ * Request: Get unit serial number
+ * @start
+ * @next SerialNumber
+ */
+message GetSerialNumber {}
+
+/**
+ * Response: contains unit serial number
+ * @end
+ */
+message SerialNumber {
+ required string serial_number = 1;
}
diff --git a/src/device_trezor/trezor/protob/messages-monero.proto b/src/device_trezor/trezor/protob/messages-monero.proto
index c88218d..0e9c680 100644
--- a/src/device_trezor/trezor/protob/messages-monero.proto
+++ b/src/device_trezor/trezor/protob/messages-monero.proto
@@ -2,8 +2,8 @@ syntax = "proto2";
package hw.trezor.messages.monero;
// Sugar for easier handling in Java
-option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageMonero";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
enum MoneroNetworkType {
MAINNET = 0;
@@ -18,12 +18,13 @@ enum MoneroNetworkType {
*/
message MoneroTransactionSourceEntry {
repeated MoneroOutputEntry outputs = 1; // all outputs including decoys (forms the ring)
- optional uint64 real_output = 2; // index denoting which item in `outputs` is our real output (not a decoy)
- optional bytes real_out_tx_key = 3; // tx key located in the real output's tx
+ optional uint64 real_output = 2; // index denoting which item in `outputs` is our real output (not a decoy)
+ optional bytes real_out_tx_key = 3; // tx key located in the real output's tx
repeated bytes real_out_additional_tx_keys = 4; // additional tx keys if applicable
- optional uint64 real_output_in_tx_index = 5; // index of our real output in the tx (aka which output was it in the transaction)
+ optional uint64 real_output_in_tx_index = 5; // index of our real output in the tx
+ // (aka which output was it in the transaction)
optional uint64 amount = 6;
- optional bool rct = 7; // is RingCT used (true for newer UTXOs)
+ optional bool rct = 7; // is RingCT used (true for newer UTXOs)
optional bytes mask = 8;
optional MoneroMultisigKLRki multisig_kLRki = 9;
optional uint32 subaddr_minor = 10; // minor subaddr index UTXO was sent to
@@ -67,12 +68,12 @@ message MoneroTransactionDestinationEntry {
* @embed
*/
message MoneroTransactionRsigData {
- optional uint32 rsig_type = 1; // range signature (aka proof) type
+ optional uint32 rsig_type = 1; // range signature (aka proof) type
optional uint32 offload_type = 2;
- repeated uint64 grouping = 3; // aggregation scheme for BP
+ repeated uint64 grouping = 3; // aggregation scheme for BP
- optional bytes mask = 4; // mask vector
- optional bytes rsig = 5; // range sig data, all of it or partial (based on rsig_parts)
+ optional bytes mask = 4; // mask vector
+ optional bytes rsig = 5; // range sig data, all of it or partial (based on rsig_parts)
repeated bytes rsig_parts = 6;
optional uint32 bp_version = 7; // Bulletproof version
}
@@ -84,12 +85,13 @@ message MoneroTransactionRsigData {
* @next Failure
*/
message MoneroGetAddress {
- repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
- optional bool show_display = 2; // Optionally show on display before sending the result
- optional MoneroNetworkType network_type = 3 [default=MAINNET]; // Network type
- optional uint32 account = 4; // Major subaddr index
- optional uint32 minor = 5; // Minor subaddr index
- optional bytes payment_id = 6; // Payment ID for integrated address
+ repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
+ optional bool show_display = 2; // Optionally show on display before sending the result
+ optional MoneroNetworkType network_type = 3 [default = MAINNET]; // Network type
+ optional uint32 account = 4; // Major subaddr index
+ optional uint32 minor = 5; // Minor subaddr index
+ optional bytes payment_id = 6; // Payment ID for integrated address
+ optional bool chunkify = 7; // display the address in chunks of 4 characters
}
/**
@@ -97,7 +99,7 @@ message MoneroGetAddress {
* @end
*/
message MoneroAddress {
- optional bytes address = 1;
+ required bytes address = 1;
}
/**
@@ -107,8 +109,8 @@ message MoneroAddress {
* @next Failure
*/
message MoneroGetWatchKey {
- repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
- optional MoneroNetworkType network_type = 2 [default=MAINNET]; // Network type
+ repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
+ optional MoneroNetworkType network_type = 2 [default = MAINNET]; // Network type
}
/**
@@ -116,8 +118,8 @@ message MoneroGetWatchKey {
* @end
*/
message MoneroWatchKey {
- optional bytes watch_key = 1;
- optional bytes address = 2;
+ required bytes watch_key = 1;
+ required bytes address = 2;
}
/**
@@ -128,7 +130,7 @@ message MoneroWatchKey {
message MoneroTransactionInitRequest {
optional uint32 version = 1;
repeated uint32 address_n = 2;
- optional MoneroNetworkType network_type = 3 [default=MAINNET]; // Network type
+ optional MoneroNetworkType network_type = 3 [default = MAINNET]; // Network type
optional MoneroTransactionData tsx_data = 4;
/**
* Structure representing Monero initial transaction information
@@ -149,6 +151,7 @@ message MoneroTransactionInitRequest {
optional uint32 client_version = 13; // connected client version
optional uint32 hard_fork = 14; // transaction hard fork number
optional bytes monero_version = 15; // monero software version
+ optional bool chunkify = 16; // display the address in chunks of 4 characters
}
}
@@ -175,7 +178,7 @@ message MoneroTransactionSetInputRequest {
* @next MoneroTransactionInputViniRequest
*/
message MoneroTransactionSetInputAck {
- optional bytes vini = 1; // xmrtypes.TxinToKey
+ optional bytes vini = 1; // xmrtypes.TxinToKey
optional bytes vini_hmac = 2;
optional bytes pseudo_out = 3;
optional bytes pseudo_out_hmac = 4;
@@ -189,7 +192,7 @@ message MoneroTransactionSetInputAck {
*/
message MoneroTransactionInputViniRequest {
optional MoneroTransactionSourceEntry src_entr = 1;
- optional bytes vini = 2; // xmrtypes.TxinToKey
+ optional bytes vini = 2; // xmrtypes.TxinToKey
optional bytes vini_hmac = 3;
optional bytes pseudo_out = 4;
optional bytes pseudo_out_hmac = 5;
@@ -201,15 +204,13 @@ message MoneroTransactionInputViniRequest {
* @next MoneroTransactionInputViniRequest
* @next MoneroTransactionAllInputsSetRequest
*/
-message MoneroTransactionInputViniAck {
-}
+message MoneroTransactionInputViniAck {}
/**
- * Request: Sub request of MoneroTransactionSign. Sent after all inputs have been sent. Useful for rangeisg offloading.
+ * Request: Sub request of MoneroTransactionSign. Sent after all inputs have been sent. Useful for rangesig offloading.
* @next MoneroTransactionAllInputsSetAck
*/
-message MoneroTransactionAllInputsSetRequest {
-}
+message MoneroTransactionAllInputsSetRequest {}
/**
* Response: Response to after all inputs have been set.
@@ -277,7 +278,7 @@ message MoneroTransactionAllOutSetAck {
*/
message MoneroTransactionSignInputRequest {
optional MoneroTransactionSourceEntry src_entr = 1;
- optional bytes vini = 2; // xmrtypes.TxinToKey
+ optional bytes vini = 2; // xmrtypes.TxinToKey
optional bytes vini_hmac = 3;
optional bytes pseudo_out = 4;
optional bytes pseudo_out_hmac = 5;
@@ -297,14 +298,14 @@ message MoneroTransactionSignInputAck {
}
/**
- * Request: Sub request of MoneroTransactionSign. Final message of the procol after all UTXOs are signed
+ * Request: Sub request of MoneroTransactionSign. Final message of the protocol after all UTXOs are signed
* @next MoneroTransactionFinalAck
*/
-message MoneroTransactionFinalRequest {
-}
+message MoneroTransactionFinalRequest {}
/**
- * Response: Contains transaction metadata and encryption keys needed for further transaction operations (e.g. multisig, send proof).
+ * Response: Contains transaction metadata and encryption keys needed for further transaction operations (e.g. multisig,
+ * send proof).
* @end
*/
message MoneroTransactionFinalAck {
@@ -323,8 +324,8 @@ message MoneroTransactionFinalAck {
message MoneroKeyImageExportInitRequest {
required uint64 num = 1;
required bytes hash = 2;
- repeated uint32 address_n = 3; // BIP-32 path to derive the key from master node
- optional MoneroNetworkType network_type = 4 [default=MAINNET]; // network type
+ repeated uint32 address_n = 3; // BIP-32 path to derive the key from master node
+ optional MoneroNetworkType network_type = 4 [default = MAINNET]; // network type
repeated MoneroSubAddressIndicesList subs = 5;
/**
* Structure representing Monero list of sub-addresses
@@ -339,8 +340,7 @@ message MoneroKeyImageExportInitRequest {
* Response: Response to key image sync initialization.
* @next MoneroKeyImageSyncStepRequest
*/
-message MoneroKeyImageExportInitAck {
-}
+message MoneroKeyImageExportInitAck {}
/**
* Request: Sub request of MoneroKeyImageSync. Contains batch of the UTXO to export key image for.
@@ -381,8 +381,7 @@ message MoneroKeyImageSyncStepAck {
* Request: Sub request of MoneroKeyImageSync. Final message of the sync protocol.
* @next MoneroKeyImageSyncFinalAck
*/
-message MoneroKeyImageSyncFinalRequest {
-}
+message MoneroKeyImageSyncFinalRequest {}
/**
* Response: Response to key image sync step. Contains encryption keys for exported key images.
@@ -397,15 +396,15 @@ message MoneroKeyImageSyncFinalAck {
* @next MoneroGetTxKeyAck
*/
message MoneroGetTxKeyRequest {
- repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
- optional MoneroNetworkType network_type = 2 [default=MAINNET]; // network type
+ repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
+ optional MoneroNetworkType network_type = 2 [default = MAINNET]; // network type
required bytes salt1 = 3;
required bytes salt2 = 4;
required bytes tx_enc_keys = 5;
required bytes tx_prefix_hash = 6;
- optional uint32 reason = 7; // reason to display for user. e.g., tx_proof
- optional bytes view_public_key = 8; // addr for derivation
+ optional uint32 reason = 7; // reason to display for user. e.g., tx_proof
+ optional bytes view_public_key = 8; // addr for derivation
}
/**
@@ -423,8 +422,8 @@ message MoneroGetTxKeyAck {
* @next MoneroLiveRefreshStartAck
*/
message MoneroLiveRefreshStartRequest {
- repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
- optional MoneroNetworkType network_type = 2 [default=MAINNET]; // network type
+ repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
+ optional MoneroNetworkType network_type = 2 [default = MAINNET]; // network type
}
/**
@@ -432,9 +431,7 @@ message MoneroLiveRefreshStartRequest {
* @next MoneroLiveRefreshStepRequest
* @next MoneroLiveRefreshFinalRequest
*/
-message MoneroLiveRefreshStartAck {
-
-}
+message MoneroLiveRefreshStartAck {}
/**
* Request: Request to compute a single key image during live sync
@@ -462,17 +459,13 @@ message MoneroLiveRefreshStepAck {
* Request: Request terminating live refresh mode.
* @next MoneroLiveRefreshFinishedAck
*/
-message MoneroLiveRefreshFinalRequest {
-
-}
+message MoneroLiveRefreshFinalRequest {}
/**
* Response: Response on termination of live refresh mode.
* @end
*/
-message MoneroLiveRefreshFinalAck {
-
-}
+message MoneroLiveRefreshFinalAck {}
/**
* Request: Universal Monero protocol implementation diagnosis request.
diff --git a/src/device_trezor/trezor/protob/messages.proto b/src/device_trezor/trezor/protob/messages.proto
index c0ea0ff..50028dc 100644
--- a/src/device_trezor/trezor/protob/messages.proto
+++ b/src/device_trezor/trezor/protob/messages.proto
@@ -1,80 +1,25 @@
syntax = "proto2";
package hw.trezor.messages;
+import "options.proto";
+
/**
* Messages for Trezor communication
*/
// Sugar for easier handling in Java
-option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessage";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+// Include in BTC-only firmware
option (include_in_bitcoin_only) = true;
-import "google/protobuf/descriptor.proto";
-
-/************************* WARNING ***********************
-Due to the way extensions are accessed in pb2py, there needs to be a globally unique
-name-ID mapping for extensions. That means that two different extensions, e.g. for
-EnumValueOptions and FieldOptions, MUST NOT have the same ID.
-
-Using the same ID indicates the same purpose (protobuf does not allow multiple
-extensions with the same name), such as EnumValueOptions.bitcoin_only and
-FileOptions.include_in_bitcoin_only. pb2py can then find the extension under
-either name.
-
-The convention to achieve this is as follows:
- - extensions specific to a type have the same prefix:
- * 50xxx for EnumValueOptions
- * 51xxx for EnumOptions
- * 52xxx for MessageOptions
- * 53xxx for FieldOptions
- - extensions that might be used across types have the same "global" prefix 60xxx
-*/
-/**
- * Options for specifying message direction and type of wire (normal/debug)
- */
-extend google.protobuf.EnumValueOptions {
- optional bool wire_in = 50002; // message can be transmitted via wire from PC to Trezor
- optional bool wire_out = 50003; // message can be transmitted via wire from Trezor to PC
- optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to Trezor
- optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from Trezor to PC
- optional bool wire_tiny = 50006; // message is handled by Trezor when the USB stack is in tiny mode
- optional bool wire_bootloader = 50007; // message is only handled by Trezor Bootloader
- optional bool wire_no_fsm = 50008; // message is not handled by Trezor unless the USB stack is in tiny mode
-
- optional bool bitcoin_only = 60000; // enum value is available on BITCOIN_ONLY build
- // (messages not marked bitcoin_only will be EXCLUDED)
-}
-
-/** Options for tagging enum types */
-extend google.protobuf.EnumOptions {
- optional bool has_bitcoin_only_values = 51001; // indicate that some values should be excluded on BITCOIN_ONLY builds
-}
-
-/** Options for tagging message types */
-extend google.protobuf.MessageOptions {
- optional bool experimental_message = 52001; // indicate that a message is intended for development and beta testing only and its definition may change at any time
- optional uint32 wire_type = 52002; // override wire type specified in the MessageType enum
-}
-
-/** Options for tagging field types */
-extend google.protobuf.FieldOptions {
- optional bool experimental_field = 53001; // indicate that a field is intended for development and beta testing only
-}
-
-/** Options for tagging files with protobuf definitions */
-extend google.protobuf.FileOptions {
- optional bool include_in_bitcoin_only = 60000; // definitions are available on BITCOIN_ONLY build
- // intentionally identical to `bitcoin_only` from enum
-}
-
-
/**
* Mapping between Trezor wire identifier (uint) and a protobuf message
*/
enum MessageType {
option (has_bitcoin_only_values) = true;
+ option (wire_enum) = true;
// Management
MessageType_Initialize = 0 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true];
@@ -102,6 +47,9 @@ enum MessageType {
MessageType_BackupDevice = 34 [(bitcoin_only) = true, (wire_in) = true];
MessageType_EntropyRequest = 35 [(bitcoin_only) = true, (wire_out) = true];
MessageType_EntropyAck = 36 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_PaymentRequest = 37 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_EntropyCheckReady = 994 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_EntropyCheckContinue = 995 [(bitcoin_only) = true, (wire_in) = true];
MessageType_PassphraseRequest = 41 [(bitcoin_only) = true, (wire_out) = true];
MessageType_PassphraseAck = 42 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
MessageType_RecoveryDevice = 45 [(bitcoin_only) = true, (wire_in) = true];
@@ -120,21 +68,35 @@ enum MessageType {
reserved 90 to 92;
MessageType_UnlockPath = 93 [(bitcoin_only) = true, (wire_in) = true];
MessageType_UnlockedPathRequest = 94 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_ShowDeviceTutorial = 95 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_UnlockBootloader = 96 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_AuthenticateDevice = 97 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_AuthenticityProof = 98 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_AuthenticityProofSizes = 99 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_ChangeLanguage = 990 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_DataChunkRequest = 991 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_DataChunkAck = 992 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_SetBrightness = 993 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_GetSerialNumber = 996 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_SerialNumber = 997 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_GetAuthenticityProofChunk = 998 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_AuthenticityProofChunk = 999 [(bitcoin_only) = true, (wire_out) = true];
MessageType_SetU2FCounter = 63 [(wire_in) = true];
MessageType_GetNextU2FCounter = 80 [(wire_in) = true];
MessageType_NextU2FCounter = 81 [(wire_out) = true];
- // Deprecated messages, kept for protobuf compatibility.
- // Both are marked wire_out so that we don't need to implement incoming handler for legacy
- MessageType_Deprecated_PassphraseStateRequest = 77 [deprecated = true];
- MessageType_Deprecated_PassphraseStateAck = 78 [deprecated = true];
+ // Deprecated passphrase-related messages (used <2.3.0)
+ reserved 77 to 78;
// Bootloader
MessageType_FirmwareErase = 6 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true];
MessageType_FirmwareUpload = 7 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true];
MessageType_FirmwareRequest = 8 [(bitcoin_only) = true, (wire_out) = true, (wire_bootloader) = true];
- MessageType_SelfTest = 32 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true];
+ MessageType_ProdTestT1 = 32 [(bitcoin_only) = true, (wire_in) = true, (wire_bootloader) = true];
+
+ // BLE
+ MessageType_BleUnpair = 8001 [(bitcoin_only) = true, (wire_in) = true];
// Bitcoin
MessageType_GetPublicKey = 11 [(bitcoin_only) = true, (wire_in) = true];
@@ -144,7 +106,6 @@ enum MessageType {
MessageType_TxAck = 22 [(bitcoin_only) = true, (wire_in) = true];
MessageType_GetAddress = 29 [(bitcoin_only) = true, (wire_in) = true];
MessageType_Address = 30 [(bitcoin_only) = true, (wire_out) = true];
- MessageType_TxAckPaymentRequest = 37 [(wire_in) = true];
MessageType_SignMessage = 38 [(bitcoin_only) = true, (wire_in) = true];
MessageType_VerifyMessage = 39 [(bitcoin_only) = true, (wire_in) = true];
MessageType_MessageSignature = 40 [(bitcoin_only) = true, (wire_out) = true];
@@ -161,13 +122,13 @@ enum MessageType {
MessageType_SignedIdentity = 54 [(bitcoin_only) = true, (wire_out) = true];
MessageType_GetECDHSessionKey = 61 [(bitcoin_only) = true, (wire_in) = true];
MessageType_ECDHSessionKey = 62 [(bitcoin_only) = true, (wire_out) = true];
- MessageType_CosiCommit = 71 [(bitcoin_only) = true, (wire_in) = true];
- MessageType_CosiCommitment = 72 [(bitcoin_only) = true, (wire_out) = true];
- MessageType_CosiSign = 73 [(bitcoin_only) = true, (wire_in) = true];
- MessageType_CosiSignature = 74 [(bitcoin_only) = true, (wire_out) = true];
+ // dropped: CosiCommit, CosiCommitment, CosiSign, CosiSignature
+ MessageType_PaymentNotification = 52 [(bitcoin_only) = true, (wire_in) = true];
+ reserved 71 to 74;
// Debug
- MessageType_DebugLinkDecision = 100 [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
+ MessageType_DebugLinkDecision = 100
+ [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
MessageType_DebugLinkGetState = 101 [(bitcoin_only) = true, (wire_debug_in) = true, (wire_tiny) = true];
MessageType_DebugLinkState = 102 [(bitcoin_only) = true, (wire_debug_out) = true];
MessageType_DebugLinkStop = 103 [(bitcoin_only) = true, (wire_debug_in) = true];
@@ -181,6 +142,18 @@ enum MessageType {
MessageType_DebugLinkRecordScreen = 9003 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkEraseSdCard = 9005 [(bitcoin_only) = true, (wire_debug_in) = true];
MessageType_DebugLinkWatchLayout = 9006 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkResetDebugEvents = 9007 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkOptigaSetSecMax = 9008 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkGetGcInfo = 9009 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkGcInfo = 9010 [(bitcoin_only) = true, (wire_debug_out) = true];
+ MessageType_DebugLinkGetPairingInfo = 9011 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkPairingInfo = 9012 [(bitcoin_only) = true, (wire_debug_out) = true];
+ MessageType_DebugLinkSetLogFilter = 9013 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkN4W1Connected = 9014 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkN4W1Write = 9015 [(bitcoin_only) = true, (wire_debug_out) = true];
+ MessageType_DebugLinkN4W1Read = 9016 [(bitcoin_only) = true, (wire_debug_out) = true];
+ MessageType_DebugLinkN4W1Response = 9017 [(bitcoin_only) = true, (wire_debug_in) = true];
+ MessageType_DebugLinkSetBatteryState = 9018 [(bitcoin_only) = true, (wire_debug_in) = true];
// Ethereum
MessageType_EthereumGetPublicKey = 450 [(wire_in) = true];
@@ -201,6 +174,10 @@ enum MessageType {
MessageType_EthereumTypedDataValueAck = 468 [(wire_in) = true];
MessageType_EthereumTypedDataSignature = 469 [(wire_out) = true];
MessageType_EthereumSignTypedHash = 470 [(wire_in) = true];
+ MessageType_EthereumDefinitionRequest = 471 [(wire_out) = true];
+ MessageType_EthereumDefinitionAck = 472 [(wire_in) = true];
+ MessageType_EthereumSignAuth7702 = 473 [(wire_in) = true];
+ MessageType_EthereumAuth7702Signature = 474 [(wire_out) = true];
// NEM
MessageType_NEMGetAddress = 67 [(wire_in) = true];
@@ -223,6 +200,7 @@ enum MessageType {
MessageType_LiskPublicKey = 122 [(wire_out) = true];
*/
reserved 114 to 122;
+ reserved 123 to 149; // reserved for internal use
// Tezos
MessageType_TezosGetAddress = 150 [(wire_in) = true];
@@ -246,12 +224,29 @@ enum MessageType {
MessageType_StellarChangeTrustOp = 216 [(wire_in) = true];
MessageType_StellarAllowTrustOp = 217 [(wire_in) = true];
MessageType_StellarAccountMergeOp = 218 [(wire_in) = true];
- // omitted: StellarInflationOp is not a supported operation, would be 219
+ reserved 219; // omitted: StellarInflationOp
MessageType_StellarManageDataOp = 220 [(wire_in) = true];
MessageType_StellarBumpSequenceOp = 221 [(wire_in) = true];
MessageType_StellarManageBuyOfferOp = 222 [(wire_in) = true];
MessageType_StellarPathPaymentStrictSendOp = 223 [(wire_in) = true];
+ reserved 224; // omitted: StellarCreateClaimableBalanceOp
+ MessageType_StellarClaimClaimableBalanceOp = 225 [(wire_in) = true];
+ reserved 226; // omitted: StellarBeginSponsoringFutureReservesOp
+ reserved 227; // omitted: StellarEndSponsoringFutureReservesOp
+ reserved 228; // omitted: StellarRevokeSponsorshipOp
+ reserved 229; // omitted: StellarClawbackOp
MessageType_StellarSignedTx = 230 [(wire_out) = true];
+ reserved 231; // omitted: StellarClawbackClaimableBalanceOp
+ reserved 232; // omitted: StellarSetTrustLineFlagsOp
+ reserved 233; // omitted: StellarLiquidityPoolDepositOp
+ reserved 234; // omitted: StellarLiquidityPoolWithdrawOp
+ MessageType_StellarInvokeHostFunctionOp = 235 [(wire_in) = true];
+ reserved 236; // omitted: StellarExtendFootprintTtl
+ reserved 237; // omitted: StellarRestoreFootprint
+ MessageType_StellarTxExtRequest = 238 [(wire_out) = true];
+ MessageType_StellarTxExt = 239 [(wire_in) = true];
+ MessageType_StellarSignSorobanAuthorization = 240 [(wire_in) = true];
+ MessageType_StellarSorobanAuthorizationSignature = 241 [(wire_out) = true];
// Cardano
// dropped Sign/VerifyMessage ids 300-302
@@ -287,35 +282,39 @@ enum MessageType {
MessageType_CardanoTxInlineDatumChunk = 335 [(wire_in) = true];
MessageType_CardanoTxReferenceScriptChunk = 336 [(wire_in) = true];
MessageType_CardanoTxReferenceInput = 337 [(wire_in) = true];
+ MessageType_CardanoSignMessageInit = 338 [(wire_in) = true];
+ MessageType_CardanoMessageDataRequest = 339 [(wire_out) = true];
+ MessageType_CardanoMessageDataResponse = 340 [(wire_in) = true];
+ MessageType_CardanoMessageSignature = 341 [(wire_out) = true];
// Ripple
MessageType_RippleGetAddress = 400 [(wire_in) = true];
MessageType_RippleAddress = 401 [(wire_out) = true];
MessageType_RippleSignTx = 402 [(wire_in) = true];
- MessageType_RippleSignedTx = 403 [(wire_in) = true];
+ MessageType_RippleSignedTx = 403 [(wire_out) = true];
// Monero
- MessageType_MoneroTransactionInitRequest = 501 [(wire_out) = true];
+ MessageType_MoneroTransactionInitRequest = 501 [(wire_in) = true];
MessageType_MoneroTransactionInitAck = 502 [(wire_out) = true];
- MessageType_MoneroTransactionSetInputRequest = 503 [(wire_out) = true];
+ MessageType_MoneroTransactionSetInputRequest = 503 [(wire_in) = true];
MessageType_MoneroTransactionSetInputAck = 504 [(wire_out) = true];
- MessageType_MoneroTransactionInputViniRequest = 507 [(wire_out) = true];
+ MessageType_MoneroTransactionInputViniRequest = 507 [(wire_in) = true];
MessageType_MoneroTransactionInputViniAck = 508 [(wire_out) = true];
- MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_out) = true];
+ MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_in) = true];
MessageType_MoneroTransactionAllInputsSetAck = 510 [(wire_out) = true];
- MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_out) = true];
+ MessageType_MoneroTransactionSetOutputRequest = 511 [(wire_in) = true];
MessageType_MoneroTransactionSetOutputAck = 512 [(wire_out) = true];
- MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_out) = true];
+ MessageType_MoneroTransactionAllOutSetRequest = 513 [(wire_in) = true];
MessageType_MoneroTransactionAllOutSetAck = 514 [(wire_out) = true];
- MessageType_MoneroTransactionSignInputRequest = 515 [(wire_out) = true];
+ MessageType_MoneroTransactionSignInputRequest = 515 [(wire_in) = true];
MessageType_MoneroTransactionSignInputAck = 516 [(wire_out) = true];
- MessageType_MoneroTransactionFinalRequest = 517 [(wire_out) = true];
+ MessageType_MoneroTransactionFinalRequest = 517 [(wire_in) = true];
MessageType_MoneroTransactionFinalAck = 518 [(wire_out) = true];
- MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_out) = true];
+ MessageType_MoneroKeyImageExportInitRequest = 530 [(wire_in) = true];
MessageType_MoneroKeyImageExportInitAck = 531 [(wire_out) = true];
- MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_out) = true];
+ MessageType_MoneroKeyImageSyncStepRequest = 532 [(wire_in) = true];
MessageType_MoneroKeyImageSyncStepAck = 533 [(wire_out) = true];
- MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_out) = true];
+ MessageType_MoneroKeyImageSyncFinalRequest = 534 [(wire_in) = true];
MessageType_MoneroKeyImageSyncFinalAck = 535 [(wire_out) = true];
MessageType_MoneroGetAddress = 540 [(wire_in) = true];
MessageType_MoneroAddress = 541 [(wire_out) = true];
@@ -340,21 +339,72 @@ enum MessageType {
MessageType_EosTxActionAck = 604 [(wire_in) = true];
MessageType_EosSignedTx = 605 [(wire_out) = true];
- // Binance
- MessageType_BinanceGetAddress = 700 [(wire_in) = true];
- MessageType_BinanceAddress = 701 [(wire_out) = true];
- MessageType_BinanceGetPublicKey = 702 [(wire_in) = true];
- MessageType_BinancePublicKey = 703 [(wire_out) = true];
- MessageType_BinanceSignTx = 704 [(wire_in) = true];
- MessageType_BinanceTxRequest = 705 [(wire_out) = true];
- MessageType_BinanceTransferMsg = 706 [(wire_in) = true];
- MessageType_BinanceOrderMsg = 707 [(wire_in) = true];
- MessageType_BinanceCancelMsg = 708 [(wire_in) = true];
- MessageType_BinanceSignedTx = 709 [(wire_out) = true];
+ // BNB Beacon Chain (deprecated)
+ reserved 700 to 709;
// WebAuthn
MessageType_WebAuthnListResidentCredentials = 800 [(wire_in) = true];
MessageType_WebAuthnCredentials = 801 [(wire_out) = true];
MessageType_WebAuthnAddResidentCredential = 802 [(wire_in) = true];
MessageType_WebAuthnRemoveResidentCredential = 803 [(wire_in) = true];
+ MessageType_WebAuthnCredentialsAck = 804 [(wire_in) = true];
+
+ // Solana
+ MessageType_SolanaGetPublicKey = 900 [(wire_in) = true];
+ MessageType_SolanaPublicKey = 901 [(wire_out) = true];
+ MessageType_SolanaGetAddress = 902 [(wire_in) = true];
+ MessageType_SolanaAddress = 903 [(wire_out) = true];
+ MessageType_SolanaSignTx = 904 [(wire_in) = true];
+ MessageType_SolanaTxSignature = 905 [(wire_out) = true];
+ MessageType_SolanaSignMessage = 906 [(wire_in) = true];
+ MessageType_SolanaMessageSignature = 907 [(wire_out) = true];
+ MessageType_SolanaVerifyMessage = 908 [(wire_in) = true];
+
+ // THP
+ MessageType_ThpCreateNewSession = 1000 [(wire_in) = true, (bitcoin_only) = true];
+ reserved 1001 to 1015; // see ThpMessageType in messages-thp.proto
+ MessageType_ThpCredentialRequest = 1016 [(wire_in) = true, (bitcoin_only) = true];
+ MessageType_ThpCredentialResponse = 1017 [(wire_out) = true, (bitcoin_only) = true];
+ reserved 1018 to 1099; // see ThpMessageType in messages-thp.proto
+
+ // Nostr
+ MessageType_NostrGetPubkey = 2001 [(wire_in) = true];
+ MessageType_NostrPubkey = 2002 [(wire_out) = true];
+ MessageType_NostrSignEvent = 2003 [(wire_in) = true];
+ MessageType_NostrEventSignature = 2004 [(wire_out) = true];
+
+ // Evolu
+ MessageType_EvoluGetNode = 2100 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_EvoluNode = 2101 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_EvoluSignRegistrationRequest = 2102 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_EvoluRegistrationRequest = 2103 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_EvoluGetDelegatedIdentityKey = 2104 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_EvoluDelegatedIdentityKey = 2105 [(bitcoin_only) = true, (wire_out) = true];
+ MessageType_EvoluIndexManagement = 2106 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_EvoluIndexManagementResponse = 2107 [(bitcoin_only) = true, (wire_out) = true];
+
+ // Tron
+ MessageType_TronGetAddress = 2200 [(wire_in) = true];
+ MessageType_TronAddress = 2201 [(wire_out) = true];
+ MessageType_TronSignTx = 2202 [(wire_in) = true];
+ MessageType_TronSignature = 2203 [(wire_out) = true];
+ MessageType_TronContractRequest = 2204 [(wire_out) = true];
+ MessageType_TronTransferContract = 2205 [(wire_in) = true];
+ MessageType_TronTriggerSmartContract = 2206 [(wire_in) = true];
+ MessageType_TronFreezeBalanceV2Contract = 2207 [(wire_in) = true];
+ MessageType_TronUnfreezeBalanceV2Contract = 2208 [(wire_in) = true];
+ MessageType_TronWithdrawUnfreeze = 2209 [(wire_in) = true];
+ MessageType_TronVoteWitnessContract = 2210 [(wire_in) = true];
+ // 2 indexes reserved for (un)delegation. PR in review.
+ MessageType_TronWithdrawBalance = 2213 [(wire_in) = true];
+
+ // Benchmark
+ MessageType_BenchmarkListNames = 9100 [(bitcoin_only) = true];
+ MessageType_BenchmarkNames = 9101 [(bitcoin_only) = true];
+ MessageType_BenchmarkRun = 9102 [(bitcoin_only) = true];
+ MessageType_BenchmarkResult = 9103 [(bitcoin_only) = true];
+
+ // Telemetry
+ MessageType_TelemetryGet = 1100 [(bitcoin_only) = true, (wire_in) = true];
+ MessageType_Telemetry = 1101 [(bitcoin_only) = true, (wire_out) = true];
}
diff --git a/src/device_trezor/trezor/protob/options.proto b/src/device_trezor/trezor/protob/options.proto
new file mode 100644
index 0000000..93ad736
--- /dev/null
+++ b/src/device_trezor/trezor/protob/options.proto
@@ -0,0 +1,72 @@
+syntax = "proto2";
+package hw.trezor.messages;
+
+import "google/protobuf/descriptor.proto";
+
+// Sugar for easier handling in Java
+option java_outer_classname = "TrezorOptions";
+option java_package = "com.satoshilabs.trezor.lib.protobuf";
+
+/************************* WARNING ***********************
+Due to the way extensions are accessed in pb2py, there needs to be a globally unique
+name-ID mapping for extensions. That means that two different extensions, e.g. for
+EnumValueOptions and FieldOptions, MUST NOT have the same ID.
+
+Using the same ID indicates the same purpose (protobuf does not allow multiple
+extensions with the same name), such as EnumValueOptions.bitcoin_only and
+FileOptions.include_in_bitcoin_only. pb2py can then find the extension under
+either name.
+
+The convention to achieve this is as follows:
+ - extensions specific to a type have the same prefix:
+ * 50xxx for EnumValueOptions
+ * 51xxx for EnumOptions
+ * 52xxx for MessageOptions
+ * 53xxx for FieldOptions
+ - extensions that might be used across types have the same "global" prefix 60xxx
+*/
+
+/**
+ * Options for specifying message direction and type of wire (normal/debug)
+ */
+extend google.protobuf.EnumValueOptions {
+ optional bool wire_in = 50002; // message can be transmitted via wire from PC to Trezor
+ optional bool wire_out = 50003; // message can be transmitted via wire from Trezor to PC
+ optional bool wire_debug_in = 50004; // message can be transmitted via debug wire from PC to Trezor
+ optional bool wire_debug_out = 50005; // message can be transmitted via debug wire from Trezor to PC
+ optional bool wire_tiny = 50006; // message is handled by Trezor when the USB stack is in tiny mode
+ optional bool wire_bootloader = 50007; // message is only handled by Trezor Bootloader
+ optional bool wire_no_fsm = 50008; // message is not handled by Trezor unless the USB stack is in tiny mode
+
+ optional bool bitcoin_only = 60000; // enum value is available on BITCOIN_ONLY build
+ // (messages not marked bitcoin_only will be EXCLUDED)
+}
+
+/** Options for tagging enum types */
+extend google.protobuf.EnumOptions {
+ optional bool has_bitcoin_only_values = 51001; // indicate that some values should be excluded
+ // on BITCOIN_ONLY builds
+ optional bool wire_enum = 51002; // this enum is used for mapping wire type integer to message
+ // type, it cannot be used as normal enum
+}
+
+/** Options for tagging message types */
+extend google.protobuf.MessageOptions {
+ optional bool experimental_message = 52001; // indicate that a message is intended for development and beta testing
+ // only and its definition may change at any time
+ optional uint32 wire_type = 52002; // override wire type specified in the MessageType enum
+ optional bool internal_only = 52003; // indicate that a message is intended for internal use
+ // only and should not be transmitted via the wire
+}
+
+/** Options for tagging field types */
+extend google.protobuf.FieldOptions {
+ optional bool experimental_field = 53001; // indicate that a field is intended for development
+ // and beta testing only
+}
+
+/** Options for tagging files with protobuf definitions */
+extend google.protobuf.FileOptions {
+ optional bool include_in_bitcoin_only = 60000; // definitions are available on BITCOIN_ONLY build
+ // intentionally identical to `bitcoin_only` from enum
+}
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.