messages.proto 28.2 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903
// This file originates from the SatoshiLabs Trezor `common` repository at:
//   https://github.com/trezor/trezor-common/blob/master/protob/messages.proto
// dated 28.07.2017, commit dd8ec3231fb5f7992360aff9bdfe30bb58130f4b.

/**
 * Messages for TREZOR communication
 */

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

import "types.proto";

/**
 * Mapping between Trezor wire identifier (uint) and a protobuf message
 */
enum MessageType {
	MessageType_Initialize = 0 [(wire_in) = true];
	MessageType_Ping = 1 [(wire_in) = true];
	MessageType_Success = 2 [(wire_out) = true];
	MessageType_Failure = 3 [(wire_out) = true];
	MessageType_ChangePin = 4 [(wire_in) = true];
	MessageType_WipeDevice = 5 [(wire_in) = true];
	MessageType_FirmwareErase = 6 [(wire_in) = true, (wire_bootloader) = true];
	MessageType_FirmwareUpload = 7 [(wire_in) = true, (wire_bootloader) = true];
	MessageType_FirmwareRequest = 8 [(wire_out) = true, (wire_bootloader) = true];
	MessageType_GetEntropy = 9 [(wire_in) = true];
	MessageType_Entropy = 10 [(wire_out) = true];
	MessageType_GetPublicKey = 11 [(wire_in) = true];
	MessageType_PublicKey = 12 [(wire_out) = true];
	MessageType_LoadDevice = 13 [(wire_in) = true];
	MessageType_ResetDevice = 14 [(wire_in) = true];
	MessageType_SignTx = 15 [(wire_in) = true];
	MessageType_SimpleSignTx = 16 [(wire_in) = true, deprecated = true];
	MessageType_Features = 17 [(wire_out) = true];
	MessageType_PinMatrixRequest = 18 [(wire_out) = true];
	MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true];
	MessageType_Cancel = 20 [(wire_in) = true];
	MessageType_TxRequest = 21 [(wire_out) = true];
	MessageType_TxAck = 22 [(wire_in) = true];
	MessageType_CipherKeyValue = 23 [(wire_in) = true];
	MessageType_ClearSession = 24 [(wire_in) = true];
	MessageType_ApplySettings = 25 [(wire_in) = true];
	MessageType_ButtonRequest = 26 [(wire_out) = true];
	MessageType_ButtonAck = 27 [(wire_in) = true, (wire_tiny) = true];
	MessageType_ApplyFlags = 28 [(wire_in) = true];
	MessageType_GetAddress = 29 [(wire_in) = true];
	MessageType_Address = 30 [(wire_out) = true];
	MessageType_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true];
	MessageType_BackupDevice = 34 [(wire_in) = true];
	MessageType_EntropyRequest = 35 [(wire_out) = true];
	MessageType_EntropyAck = 36 [(wire_in) = true];
	MessageType_SignMessage = 38 [(wire_in) = true];
	MessageType_VerifyMessage = 39 [(wire_in) = true];
	MessageType_MessageSignature = 40 [(wire_out) = true];
	MessageType_PassphraseRequest = 41 [(wire_out) = true];
	MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true];
	MessageType_EstimateTxSize = 43 [(wire_in) = true, deprecated = true];
	MessageType_TxSize = 44 [(wire_out) = true, deprecated = true];
	MessageType_RecoveryDevice = 45 [(wire_in) = true];
	MessageType_WordRequest = 46 [(wire_out) = true];
	MessageType_WordAck = 47 [(wire_in) = true];
	MessageType_CipheredKeyValue = 48 [(wire_out) = true];
	MessageType_EncryptMessage = 49 [(wire_in) = true, deprecated = true];
	MessageType_EncryptedMessage = 50 [(wire_out) = true, deprecated = true];
	MessageType_DecryptMessage = 51 [(wire_in) = true, deprecated = true];
	MessageType_DecryptedMessage = 52 [(wire_out) = true, deprecated = true];
	MessageType_SignIdentity = 53 [(wire_in) = true];
	MessageType_SignedIdentity = 54 [(wire_out) = true];
	MessageType_GetFeatures = 55 [(wire_in) = true];
	MessageType_EthereumGetAddress = 56 [(wire_in) = true];
	MessageType_EthereumAddress = 57 [(wire_out) = true];
	MessageType_EthereumSignTx = 58 [(wire_in) = true];
	MessageType_EthereumTxRequest = 59 [(wire_out) = true];
	MessageType_EthereumTxAck = 60 [(wire_in) = true];
	MessageType_GetECDHSessionKey = 61 [(wire_in) = true];
	MessageType_ECDHSessionKey = 62 [(wire_out) = true];
	MessageType_SetU2FCounter = 63 [(wire_in) = true];
	MessageType_EthereumSignMessage = 64 [(wire_in) = true];
	MessageType_EthereumVerifyMessage = 65 [(wire_in) = true];
	MessageType_EthereumMessageSignature = 66 [(wire_out) = true];
	MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true];
	MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true];
	MessageType_DebugLinkState = 102 [(wire_debug_out) = true];
	MessageType_DebugLinkStop = 103 [(wire_debug_in) = true];
	MessageType_DebugLinkLog = 104 [(wire_debug_out) = true];
	MessageType_DebugLinkMemoryRead = 110 [(wire_debug_in) = true];
	MessageType_DebugLinkMemory = 111 [(wire_debug_out) = true];
	MessageType_DebugLinkMemoryWrite = 112 [(wire_debug_in) = true];
	MessageType_DebugLinkFlashErase = 113 [(wire_debug_in) = true];
}

////////////////////
// Basic messages //
////////////////////

/**
 * Request: Reset device to default state and ask for device details
 * @next Features
 */
message Initialize {
}

/**
 * Request: Ask for device details (no device reset)
 * @next Features
 */
message GetFeatures {
}

/**
 * Response: Reports various information about the device
 * @prev Initialize
 * @prev GetFeatures
 */
message Features {
	optional string vendor = 1;			// name of the manufacturer, e.g. "bitcointrezor.com"
	optional uint32 major_version = 2;		// major version of the device, e.g. 1
	optional uint32 minor_version = 3;		// minor version of the device, e.g. 0
	optional uint32 patch_version = 4;		// patch version of the device, 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
	repeated CoinType coins = 11;			// supported coins
	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 pin_cached = 16;			// is PIN already cached in session?
	optional bool passphrase_cached = 17;		// 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)
}

/**
 * Request: clear session (removes cached PIN, passphrase, etc).
 * @next Success
 */
message ClearSession {
}

/**
 * Request: change language and/or label of the device
 * @next Success
 * @next Failure
 * @next ButtonRequest
 * @next PinMatrixRequest
 */
message ApplySettings {
	optional string language = 1;
	optional string label = 2;
	optional bool use_passphrase = 3;
	optional bytes homescreen = 4;
}

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

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

/**
 * Request: Test if the device is alive, device sends back the message in Success response
 * @next Success
 */
message Ping {
	optional string message = 1;			// message to send back in Success message
	optional bool button_protection = 2;		// ask for button press
	optional bool pin_protection = 3;		// ask for PIN if set in device
	optional bool passphrase_protection = 4;	// ask for passphrase if set in device
}

/**
 * Response: Success of the previous request
 */
message Success {
	optional string message = 1;	// human readable description of action or request-specific payload
}

/**
 * Response: Failure of the previous request
 */
message Failure {
	optional FailureType code = 1;	// computer-readable definition of the error state
	optional string message = 2;	// human-readable message of the error state
}

/**
 * Response: Device is waiting for HW button press.
 * @next ButtonAck
 * @next Cancel
 */
message ButtonRequest {
	optional ButtonRequestType code = 1;
	optional string data = 2;
}

/**
 * Request: Computer agrees to wait for HW button press
 * @prev ButtonRequest
 */
message ButtonAck {
}

/**
 * Response: Device is asking computer to show PIN matrix and awaits PIN encoded using this matrix scheme
 * @next PinMatrixAck
 * @next Cancel
 */
message PinMatrixRequest {
	optional PinMatrixRequestType type = 1;
}

/**
 * Request: Computer responds with encoded PIN
 * @prev PinMatrixRequest
 */
message PinMatrixAck {
	required string pin = 1;		// matrix encoded PIN entered by user
}

/**
 * Request: Abort last operation that required user interaction
 * @prev ButtonRequest
 * @prev PinMatrixRequest
 * @prev PassphraseRequest
 */
message Cancel {
}

/**
 * Response: Device awaits encryption passphrase
 * @next PassphraseAck
 * @next Cancel
 */
message PassphraseRequest {
}

/**
 * Request: Send passphrase back
 * @prev PassphraseRequest
 */
message PassphraseAck {
	required string passphrase = 1;
}

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

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

/**
 * Request: Ask device for public key corresponding to address_n path
 * @next PassphraseRequest
 * @next PublicKey
 * @next Failure
 */
message GetPublicKey {
	repeated uint32 address_n = 1;		// BIP-32 path to derive the key from master node
	optional string ecdsa_curve_name = 2;	// ECDSA curve name to use
	optional bool show_display = 3;		// optionally show on display before sending the result
	optional string coin_name = 4 [default='Bitcoin'];
}

/**
 * Response: Contains public key derived from device private seed
 * @prev GetPublicKey
 */
message PublicKey {
	required HDNodeType node = 1;		// BIP32 public node
	optional string xpub = 2;		// serialized form of public node
}

/**
 * Request: Ask device for address corresponding to address_n path
 * @next PassphraseRequest
 * @next Address
 * @next Failure
 */
message GetAddress {
	repeated uint32 address_n = 1;						// BIP-32 path to derive the key from master node
	optional string coin_name = 2 [default='Bitcoin'];
	optional bool show_display = 3			;			// optionally show on display before sending the result
	optional MultisigRedeemScriptType multisig = 4;				// filled if we are showing a multisig address
	optional InputScriptType script_type = 5 [default=SPENDADDRESS];	// used to distinguish between various address formats (non-segwit, segwit, etc.)
}

/**
 * Request: Ask device for Ethereum address corresponding to address_n path
 * @next PassphraseRequest
 * @next EthereumAddress
 * @next Failure
 */
message EthereumGetAddress {
	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
}

/**
 * Response: Contains address derived from device private seed
 * @prev GetAddress
 */
message Address {
	required string address = 1;		// Coin address in Base58 encoding
}

/**
 * Response: Contains an Ethereum address derived from device private seed
 * @prev EthereumGetAddress
 */
message EthereumAddress {
	required bytes address = 1;		// Coin address as an Ethereum 160 bit hash
}

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

/**
 * Request: Load seed and related internal settings from the computer
 * @next ButtonRequest
 * @next Success
 * @next Failure
 */
message LoadDevice {
	optional string mnemonic = 1;				// seed encoded as BIP-39 mnemonic (12, 18 or 24 words)
	optional HDNodeType node = 2;				// BIP-32 node
	optional string pin = 3;				// set PIN protection
	optional bool passphrase_protection = 4;		// enable master node encryption using passphrase
	optional string language = 5 [default='english'];	// device language
	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
}

/**
 * Request: Ask device to do initialization involving user interaction
 * @next EntropyRequest
 * @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='english'];	// device language
	optional string label = 6;				// device label
	optional uint32 u2f_counter = 7;			// U2F counter
	optional bool skip_backup = 8;				// postpone seed backup to BackupDevice workflow
}

/**
 * Request: Perform backup of the device seed if not backed up using ResetDevice
 * @next ButtonRequest
 */
message BackupDevice {
}

/**
 * Response: Ask for additional entropy from host computer
 * @prev ResetDevice
 * @next EntropyAck
 */
message EntropyRequest {
}

/**
 * Request: Provide additional entropy for seed generation function
 * @prev EntropyRequest
 * @next ButtonRequest
 */
message EntropyAck {
	optional bytes entropy = 1;				// 256 bits (32 bytes) of random data
}

/**
 * Request: Start recovery workflow asking user for specific words of mnemonic
 * Used to recovery device safely even on untrusted computer.
 * @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 [default='english'];	// device language
	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 uint32 type = 8;				// supported recovery type (see RecoveryType)
	optional uint32 u2f_counter = 9;			// U2F counter
	optional bool dry_run = 10;				// perform dry-run recovery workflow (for safe mnemonic validation)
}

/**
 * Response: Device is waiting for user to enter word of the mnemonic
 * Its position is shown only on device's internal display.
 * @prev RecoveryDevice
 * @prev WordAck
 */
message WordRequest {
	optional WordRequestType type = 1;
}

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

//////////////////////////////
// Message signing messages //
//////////////////////////////

/**
 * Request: Ask device to sign message
 * @next MessageSignature
 * @next Failure
 */
message SignMessage {
	repeated uint32 address_n = 1;						// BIP-32 path to derive the key from master node
	required bytes message = 2;						// message to be signed
	optional string coin_name = 3 [default='Bitcoin'];			// coin to use for signing
	optional InputScriptType script_type = 4 [default=SPENDADDRESS];	// used to distinguish between various address formats (non-segwit, segwit, etc.)
}

/**
 * Request: Ask device to verify message
 * @next Success
 * @next Failure
 */
message VerifyMessage {
	optional string address = 1;				// address to verify
	optional bytes signature = 2;				// signature to verify
	optional bytes message = 3;				// message to verify
	optional string coin_name = 4 [default='Bitcoin'];	// coin to use for verifying
}

/**
 * Response: Signed message
 * @prev SignMessage
 */
message MessageSignature {
	optional string address = 1;				// address used to sign the message
	optional bytes signature = 2;				// signature of the message
}

///////////////////////////
// Encryption/decryption //
///////////////////////////

/**
 * Request: Ask device to encrypt message
 * @next EncryptedMessage
 * @next Failure
 */
message EncryptMessage {
	optional bytes pubkey = 1;				// public key
	optional bytes message = 2;				// message to encrypt
	optional bool display_only = 3;				// show just on display? (don't send back via wire)
	repeated uint32 address_n = 4;				// BIP-32 path to derive the signing key from master node
	optional string coin_name = 5 [default='Bitcoin'];	// coin to use for signing
}

/**
 * Response: Encrypted message
 * @prev EncryptMessage
 */
message EncryptedMessage {
	optional bytes nonce = 1;				// nonce used during encryption
	optional bytes message = 2;				// encrypted message
	optional bytes hmac = 3;				// message hmac
}

/**
 * Request: Ask device to decrypt message
 * @next Success
 * @next Failure
 */
message DecryptMessage {
	repeated uint32 address_n = 1;				// BIP-32 path to derive the decryption key from master node
	optional bytes nonce = 2;				// nonce used during encryption
	optional bytes message = 3;				// message to decrypt
	optional bytes hmac = 4;				// message hmac
}

/**
 * Response: Decrypted message
 * @prev DecryptedMessage
 */
message DecryptedMessage {
	optional bytes message = 1;				// decrypted message
	optional string address = 2;				// address used to sign the message (if used)
}

/**
 * Request: Ask device to encrypt or decrypt value of given key
 * @next CipheredKeyValue
 * @next Failure
 */
message CipherKeyValue {
	repeated uint32 address_n = 1;		// BIP-32 path to derive the key from master node
	optional string key = 2;		// key component of key:value
	optional bytes value = 3;		// value component of key:value
	optional bool encrypt = 4;		// are we encrypting (True) or decrypting (False)?
	optional bool ask_on_encrypt = 5;	// should we ask on encrypt operation?
	optional bool ask_on_decrypt = 6;	// should we ask on decrypt operation?
	optional bytes iv = 7;			// initialization vector (will be computed if not set)
}

/**
 * Response: Return ciphered/deciphered value
 * @prev CipherKeyValue
 */
message CipheredKeyValue {
	optional bytes value = 1;		// ciphered/deciphered value
}

//////////////////////////////////
// Transaction signing messages //
//////////////////////////////////

/**
 * Request: Estimated size of the transaction
 * This behaves exactly like SignTx, which means that it can ask using TxRequest
 * This call is non-blocking (except possible PassphraseRequest to unlock the seed)
 * @next TxSize
 * @next Failure
 */
message EstimateTxSize {
	required uint32 outputs_count = 1;			// number of transaction outputs
	required uint32 inputs_count = 2;			// number of transaction inputs
	optional string coin_name = 3 [default='Bitcoin'];	// coin to use
}

/**
 * Response: Estimated size of the transaction
 * @prev EstimateTxSize
 */
message TxSize {
	optional uint32 tx_size = 1;				// estimated size of transaction in bytes
}

/**
 * Request: Ask device to sign transaction
 * @next PassphraseRequest
 * @next PinMatrixRequest
 * @next TxRequest
 * @next Failure
 */
message SignTx {
	required uint32 outputs_count = 1;			// number of transaction outputs
	required uint32 inputs_count = 2;			// number of transaction inputs
	optional string coin_name = 3 [default='Bitcoin'];	// coin to use
	optional uint32 version = 4 [default=1];		// transaction version
	optional uint32 lock_time = 5 [default=0];		// transaction lock_time
}

/**
 * Request: Simplified transaction signing
 * This method doesn't support streaming, so there are hardware limits in number of inputs and outputs.
 * In case of success, the result is returned using TxRequest message.
 * @next PassphraseRequest
 * @next PinMatrixRequest
 * @next TxRequest
 * @next Failure
 */
message SimpleSignTx {
	repeated TxInputType inputs = 1;			// transaction inputs
	repeated TxOutputType outputs = 2;			// transaction outputs
	repeated TransactionType transactions = 3;		// transactions whose outputs are used to build current inputs
	optional string coin_name = 4 [default='Bitcoin'];	// coin to use
	optional uint32 version = 5 [default=1];		// transaction version
	optional uint32 lock_time = 6 [default=0];		// transaction lock_time
}

/**
 * Response: Device asks for information for signing transaction or returns the last result
 * If request_index is set, device awaits TxAck message (with fields filled in according to request_type)
 * If signature_index is set, 'signature' contains signed input of signature_index's input
 * @prev SignTx
 * @prev SimpleSignTx
 * @prev TxAck
 */
message TxRequest {
	optional RequestType request_type = 1;			// what should be filled in TxAck message?
	optional TxRequestDetailsType details = 2;		// request for tx details
	optional TxRequestSerializedType serialized = 3;	// serialized data and request for next
}

/**
 * Request: Reported transaction data
 * @prev TxRequest
 * @next TxRequest
 */
message TxAck {
	optional TransactionType tx = 1;
}

/**
 * Request: Ask device to sign transaction
 * All fields are optional from the protocol's point of view. Each field defaults to value `0` if missing.
 * Note: the first at most 1024 bytes of data MUST be transmitted as part of this message.
 * @next PassphraseRequest
 * @next PinMatrixRequest
 * @next EthereumTxRequest
 * @next Failure
 */
message EthereumSignTx {
	repeated uint32 address_n = 1;			// BIP-32 path to derive the key from master node
	optional bytes nonce = 2;			// <=256 bit unsigned big endian
	optional bytes gas_price = 3;			// <=256 bit unsigned big endian (in wei)
	optional bytes gas_limit = 4;			// <=256 bit unsigned big endian
	optional bytes to = 5;				// 160 bit address hash
	optional bytes value = 6;			// <=256 bit unsigned big endian (in wei)
	optional bytes data_initial_chunk = 7;		// The initial data chunk (<= 1024 bytes)
	optional uint32 data_length = 8;		// Length of transaction payload
	optional uint32 chain_id = 9;			// Chain Id for EIP 155
}

/**
 * Response: Device asks for more data from transaction payload, or returns the signature.
 * If data_length is set, device awaits that many more bytes of payload.
 * Otherwise, the signature_* fields contain the computed transaction signature. All three fields will be present.
 * @prev EthereumSignTx
 * @next EthereumTxAck
 */
message EthereumTxRequest {
	optional uint32 data_length = 1;		// Number of bytes being requested (<= 1024)
	optional uint32 signature_v = 2;		// Computed signature (recovery parameter, limited to 27 or 28)
	optional bytes signature_r = 3;			// Computed signature R component (256 bit)
	optional bytes signature_s = 4;			// Computed signature S component (256 bit)
}

/**
 * Request: Transaction payload data.
 * @prev EthereumTxRequest
 * @next EthereumTxRequest
 */
message EthereumTxAck {
	optional bytes data_chunk = 1;			// Bytes from transaction payload (<= 1024 bytes)
}

////////////////////////////////////////
// Ethereum: Message signing messages //
////////////////////////////////////////

/**
 * Request: Ask device to sign message
 * @next EthereumMessageSignature
 * @next Failure
 */
message EthereumSignMessage {
	repeated uint32 address_n = 1;				// BIP-32 path to derive the key from master node
	required bytes message = 2;				// message to be signed
}

/**
 * Request: Ask device to verify message
 * @next Success
 * @next Failure
 */
message EthereumVerifyMessage {
	optional bytes address = 1;				// address to verify
	optional bytes signature = 2;				// signature to verify
	optional bytes message = 3;				// message to verify
}

/**
 * Response: Signed message
 * @prev EthereumSignMessage
 */
message EthereumMessageSignature {
	optional bytes address = 1;				// address used to sign the message
	optional bytes signature = 2;				// signature of the message
}

///////////////////////
// Identity messages //
///////////////////////

/**
 * Request: Ask device to sign identity
 * @next SignedIdentity
 * @next Failure
 */
message SignIdentity {
	optional IdentityType identity = 1;		// identity
	optional bytes challenge_hidden = 2;		// non-visible challenge
	optional string challenge_visual = 3;		// challenge shown on display (e.g. date+time)
	optional string ecdsa_curve_name = 4;		// ECDSA curve name to use
}

/**
 * Response: Device provides signed identity
 * @prev SignIdentity
 */
message SignedIdentity {
	optional string address = 1;			// identity address
	optional bytes public_key = 2;			// identity public key
	optional bytes signature = 3;			// signature of the identity data
}

///////////////////
// ECDH messages //
///////////////////

/**
 * Request: Ask device to generate ECDH session key
 * @next ECDHSessionKey
 * @next Failure
 */
message GetECDHSessionKey {
	optional IdentityType identity = 1;		// identity
	optional bytes peer_public_key = 2;		// peer's public key
	optional string ecdsa_curve_name = 3;		// ECDSA curve name to use
}

/**
 * Response: Device provides ECDH session key
 * @prev GetECDHSessionKey
 */
message ECDHSessionKey {
	optional bytes session_key = 1;			// ECDH session key
}

///////////////////
// U2F messages //
///////////////////

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

/////////////////////////
// Bootloader messages //
/////////////////////////

/**
 * Request: Ask device to erase its firmware (so it can be replaced via FirmwareUpload)
 * @next Success
 * @next FirmwareRequest
 * @next Failure
 */
message FirmwareErase {
	optional uint32 length = 1;			// length of new firmware
}

/**
 * Response: Ask for firmware chunk
 * @next FirmwareUpload
 */
message FirmwareRequest {
	optional uint32 offset = 1;			// offset of requested firmware chunk
	optional uint32 length = 2;			// length of requested firmware chunk
}

/**
 * Request: Send firmware in binary form to the device
 * @next Success
 * @next Failure
 */
message FirmwareUpload {
	required bytes payload = 1;			// firmware to be loaded into device
	optional bytes hash = 2;			// hash of the payload
}


/**
 * Request: Perform a device self-test
 * @next Success
 * @next Failure
 */
message SelfTest {
	optional bytes payload = 1;			// payload to be used in self-test
}

/////////////////////////////////////////////////////////////
// Debug messages (only available if DebugLink is enabled) //
/////////////////////////////////////////////////////////////

/**
 * Request: "Press" the button on the device
 * @next Success
 */
message DebugLinkDecision {
	required bool yes_no = 1;			// true for "Confirm", false for "Cancel"
}

/**
 * Request: Computer asks for device state
 * @next DebugLinkState
 */
message DebugLinkGetState {
}

/**
 * Response: Device current state
 * @prev DebugLinkGetState
 */
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 string mnemonic = 4;			// current BIP-39 mnemonic
	optional 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
}

/**
 * Request: Ask device to restart
 */
message DebugLinkStop {
}

/**
 * Response: Device wants host to log event
 */
message DebugLinkLog {
	optional uint32 level = 1;
	optional string bucket = 2;
	optional string text = 3;
}

/**
 * Request: Read memory from device
 * @next DebugLinkMemory
 */
message DebugLinkMemoryRead {
	optional uint32 address = 1;
	optional uint32 length = 2;
}

/**
 * Response: Device sends memory back
 * @prev DebugLinkMemoryRead
 */
message DebugLinkMemory {
	optional bytes memory = 1;
}

/**
 * Request: Write memory to device.
 * WARNING: Writing to the wrong location can irreparably break the device.
 */
message DebugLinkMemoryWrite {
	optional uint32 address = 1;
	optional bytes memory = 2;
	optional bool flash = 3;
}

/**
 * Request: Erase block of flash on device
 * WARNING: Writing to the wrong location can irreparably break the device.
 */
message DebugLinkFlashErase {
	optional uint32 sector = 1;
}