syntax = "proto2";
package hw.trezor.messages.management;

// Sugar for easier handling in Java
option java_package = "com.satoshilabs.trezor.lib.protobuf";
option java_outer_classname = "TrezorMessageManagement";

import "options.proto";

option (include_in_bitcoin_only) = true;

/**
 * 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
    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
}

/**
 * Level of safety checks for unsafe actions like spending from invalid path namespace or setting high transaction fee.
 */
enum SafetyCheckLevel {
    Strict = 0;             // disallow unsafe actions, this is the default
    PromptAlways = 1;       // ask user before unsafe action
    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 {
    Toif = 1;   // full-color toif
    Jpeg = 2;   // jpeg
    ToiG = 3;   // greyscale toif
}

/**
 * Request: Reset device to default state and ask for device details
 * @start
 * @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 bool derive_cardano = 3;  // whether to derive Cardano Icarus root keys in this session
}

/**
 * Request: Ask for device details (no device reset)
 * @start
 * @next Features
 */
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 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

    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;                         // BNB Smart Chain
        Capability_Cardano = 4;
        Capability_Crypto = 5 [(bitcoin_only) = true];  // generic crypto operations for GPG, SSH, etc.
        Capability_EOS = 6;
        Capability_Ethereum = 7;
        Capability_Lisk = 8 [deprecated = true];
        Capability_Monero = 9;
        Capability_NEM = 10;
        Capability_Ripple = 11;
        Capability_Stellar = 12;
        Capability_Tezos = 13;
        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_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;
    }
}

/**
 * Request: soft-lock the device. Following actions will require PIN. Passphrases remain cached.
 * @start
 * @next Success
 */
message LockDevice {
}

/**
 * Request: Show a "Do not disconnect" dialog instead of the standard homescreen.
 * @start
 * @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.
}

/**
 * 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 {
}

/**
 * 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 [deprecated=true];
    optional string label = 2;
    optional bool use_passphrase = 3;
    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 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
}

/**
 * Request: set flags of the device
 * @start
 * @next Success
 * @next Failure
 */
message ApplyFlags {
    required uint32 flags = 1;  // bitmask, can only set bits, not unset
}

/**
 * Request: Starts workflow for setting/changing/removing the PIN
 * @start
 * @next Success
 * @next Failure
 */
message ChangePin {
    optional bool remove = 1;   // is PIN removal requested?
}

/**
 * Request: Starts workflow for setting/removing the wipe code
 * @start
 * @next Success
 * @next Failure
 */
message ChangeWipeCode {
    optional bool remove = 1;   // is wipe code removal requested?
}

/**
 * Request: Starts workflow for enabling/regenerating/disabling SD card protection
 * @start
 * @next Success
 * @next Failure
 */
message SdProtect {
    required SdProtectOperationType operation = 1;
    /**
    * Structure representing SD card protection operation
    */
    enum SdProtectOperationType {
        DISABLE = 0;
        ENABLE = 1;
        REFRESH = 2;
    }
}

/**
 * Request: Test if the device is alive, device sends back the message in Success response
 * @start
 * @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
}

/**
 * Request: Abort last operation that required user interaction
 * @start
 * @next Failure
 */
message Cancel {
}

/**
 * Request: Request a sample of random data generated by hardware RNG. May be used for testing.
 * @start
 * @next Entropy
 * @next Failure
 */
message GetEntropy {
    required uint32 size = 1;       // size of requested entropy
}

/**
 * Response: Reply with random data generated by internal RNG
 * @end
 */
message Entropy {
    required bytes entropy = 1;     // chunk of random generated bytes
}

/**
 * Request: Get a hash of the installed firmware combined with an optional challenge.
 * @start
 * @next FirmwareHash
 * @next Failure
 */
message GetFirmwareHash {
    optional bytes challenge = 1;   // Blake2s key up to 32 bytes in length.
}

/**
 * Response: Hash of the installed firmware combined with the optional challenge.
 * @end
 */
message FirmwareHash {
    required bytes hash = 1;
}

/**
 * Request: Request a signature of the provided challenge.
 * @start
 * @next AuthenticityProof
 * @next Failure
 */
message AuthenticateDevice {
    required bytes challenge = 1;  // A random challenge to sign.
}

/**
 * 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 "\0x13AuthenticateDevice:" + 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 "\0x13AuthenticateDevice:" + length-prefixed challenge that should be verified using the Tropic device certificate.
}

/**
 * Request: Request device to wipe all sensitive data and settings
 * @start
 * @next Success
 * @next Failure
 */
message WipeDevice {
}

/**
 * Request: Load seed and related internal settings from the computer
 * @start
 * @next Success
 * @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 [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
}

/**
 * Request: Ask device to do initialization involving user interaction
 * @start
 * @next EntropyRequest
 * @next Failure
 */
message ResetDevice {
    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
}

/**
 * Request: Perform backup of the device seed if not backed up using ResetDevice
 * @start
 * @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;
}

/**
 * Response: Ask for additional entropy from host computer
 * @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 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
}

/**
 * Request: Start recovery workflow asking user for specific words of mnemonic
 * Used to recovery device safely even on untrusted computer.
 * @start
 * @next WordRequest
 */
message RecoveryDevice {
    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
    /**
     * Type of recovery procedure. These should be used as bitmask, e.g.,
     * `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.
     */
    enum RecoveryDeviceInputMethod {
        // use powers of two when extending this field
        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.
 * @next WordAck
 */
message WordRequest {
    required WordRequestType type = 1;
    /**
    * Type of Recovery Word request
    */
    enum WordRequestType {
        WordRequestType_Plain = 0;
        WordRequestType_Matrix9 = 1;
        WordRequestType_Matrix6 = 2;
    }
}

/**
 * Request: Computer replies with word from the mnemonic
 * @next WordRequest
 * @next Success
 * @next Failure
 */
message WordAck {
    required string word = 1;           // one word of mnemonic on asked position
}

/**
 * Request: Set U2F counter
 * @start
 * @next Success
 */
message SetU2FCounter {
    required uint32 u2f_counter = 1;
}

/**
 * Request: Set U2F counter
 * @start
 * @next NextU2FCounter
 */
message GetNextU2FCounter {
}

/**
 * Request: Set U2F counter
 * @end
 */
message NextU2FCounter {
    required uint32 u2f_counter = 1;
}

/**
 * Request: Ask device to prepare for a preauthorized operation.
 * @start
 * @next PreauthorizedRequest
 * @next Failure
 */
message DoPreauthorized {
}

/**
 * Request: Device awaits a preauthorized operation.
 * @start
 * @next SignTx
 * @next GetOwnershipProof
 */
message PreauthorizedRequest {
}

/**
 * Request: Cancel any outstanding authorization in the current session.
 * @start
 * @next Success
 * @next Failure
 */
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;
    }
}

/**
 * Request: Ask device to generate a random nonce and store it in the session's cache
 * @start
 * @next Nonce
 */
message GetNonce {
}

/**
 * Response: Contains a random nonce
 * @end
 */
message Nonce {
    required bytes nonce = 1; // a 32-byte random value generated by Trezor
}

/**
 * Request: Ask device to unlock a subtree of the keychain.
 * @start
 * @next UnlockedPathRequest
 * @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
}

/**
 * Request: Device awaits an operation.
 * @start
 * @next SignTx
 * @next GetPublicKey
 * @next GetAddress
 */
message UnlockedPathRequest {
    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;
 }
