mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 12:46:44 +00:00
Add support for signing EIP-712 typed data for both Ledger and Trezor devices
This commit is contained in:
parent
b1eb33ce8b
commit
bfd5914a1d
20 changed files with 8093 additions and 3697 deletions
106
accounts/usbwallet/data_type.go
Normal file
106
accounts/usbwallet/data_type.go
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// Copyright 2017 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package usbwallet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
)
|
||||
|
||||
type dataType byte
|
||||
|
||||
const (
|
||||
CustomType dataType = iota
|
||||
IntType
|
||||
UintType
|
||||
AddressType
|
||||
BoolType
|
||||
StringType
|
||||
FixedBytesType
|
||||
BytesType
|
||||
)
|
||||
|
||||
var nameToType = map[string]dataType{
|
||||
"int": IntType,
|
||||
"uint": UintType,
|
||||
"address": AddressType,
|
||||
"bool": BoolType,
|
||||
"string": StringType,
|
||||
"bytes": BytesType,
|
||||
}
|
||||
|
||||
func parseType(data apitypes.TypedData, field apitypes.Type) (dt dataType, name string, byteLength int, arrayLevels []*int, err error) {
|
||||
name = strings.TrimSpace(field.Type)
|
||||
arrayLengths := regexp.MustCompile(`\[(\d*)]`).FindAllStringSubmatch(name, -1)
|
||||
if len(arrayLengths) > 0 {
|
||||
arrayLevels = make([]*int, len(arrayLengths))
|
||||
for i, arrayLength := range arrayLengths {
|
||||
if len(arrayLength[1]) == 0 {
|
||||
arrayLevels[i] = nil // nil means dynamic length
|
||||
} else {
|
||||
length, _ := strconv.Atoi(arrayLength[1]) // guaranteed to be a digit, ignore error
|
||||
arrayLevels[i] = &length
|
||||
}
|
||||
}
|
||||
name = name[0:strings.Index(name, "[")]
|
||||
}
|
||||
if data.Types[name] != nil {
|
||||
dt = CustomType
|
||||
return
|
||||
}
|
||||
|
||||
matches := regexp.MustCompile(`^(.+?)(\d*)$`).FindStringSubmatch(name)
|
||||
name = matches[1]
|
||||
lengthStr := matches[2]
|
||||
|
||||
var ok bool
|
||||
if dt, ok = nameToType[name]; !ok {
|
||||
err = fmt.Errorf("unknown type: %s", field.Type)
|
||||
return
|
||||
}
|
||||
|
||||
byteLength, _ = strconv.Atoi(lengthStr)
|
||||
if dt == UintType || dt == IntType {
|
||||
if lengthStr == "" {
|
||||
byteLength = 32
|
||||
} else if byteLength%8 != 0 {
|
||||
err = fmt.Errorf("invalid length for %s: %s", field.Type, lengthStr)
|
||||
return
|
||||
} else {
|
||||
byteLength /= 8
|
||||
}
|
||||
} else if lengthStr != "" {
|
||||
if dt == BytesType {
|
||||
dt = FixedBytesType
|
||||
} else {
|
||||
err = fmt.Errorf("invalid type: %s", field.Type)
|
||||
return
|
||||
}
|
||||
} else if dt == AddressType {
|
||||
byteLength = 20 // address is always 20 bytes
|
||||
}
|
||||
if lengthStr != "" && (byteLength < 1 || byteLength > 32) {
|
||||
err = fmt.Errorf("invalid length for %s: %s", field.Type, lengthStr)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/event"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/karalabe/hid"
|
||||
"github.com/karalabe/usb"
|
||||
)
|
||||
|
||||
// LedgerScheme is the protocol scheme prefixing account and wallet URLs.
|
||||
|
|
@ -105,7 +105,7 @@ func NewTrezorHubWithWebUSB() (*Hub, error) {
|
|||
|
||||
// newHub creates a new hardware wallet manager for generic USB devices.
|
||||
func newHub(scheme string, vendorID uint16, productIDs []uint16, usageID uint16, endpointID int, makeDriver func(log.Logger) driver) (*Hub, error) {
|
||||
if !hid.Supported() {
|
||||
if !usb.Supported() {
|
||||
return nil, errors.New("unsupported platform")
|
||||
}
|
||||
hub := &Hub{
|
||||
|
|
@ -151,7 +151,7 @@ func (hub *Hub) refreshWallets() {
|
|||
return
|
||||
}
|
||||
// Retrieve the current list of USB wallet devices
|
||||
var devices []hid.DeviceInfo
|
||||
var devices []usb.DeviceInfo
|
||||
|
||||
if runtime.GOOS == "linux" {
|
||||
// hidapi on Linux opens the device during enumeration to retrieve some infos,
|
||||
|
|
@ -166,7 +166,7 @@ func (hub *Hub) refreshWallets() {
|
|||
return
|
||||
}
|
||||
}
|
||||
infos, err := hid.Enumerate(hub.vendorID, 0)
|
||||
infos, err := usb.Enumerate(hub.vendorID, 0)
|
||||
if err != nil {
|
||||
failcount := hub.enumFails.Add(1)
|
||||
if runtime.GOOS == "linux" {
|
||||
|
|
|
|||
|
|
@ -27,14 +27,18 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/common/math"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
)
|
||||
|
||||
// ledgerOpcode is an enumeration encoding the supported Ledger opcodes.
|
||||
|
|
@ -48,21 +52,60 @@ type ledgerParam1 byte
|
|||
// specific opcodes. The same parameter values may be reused between opcodes.
|
||||
type ledgerParam2 byte
|
||||
|
||||
// ledgerStatus is an enumeration encoding ledger status words.
|
||||
type ledgerStatus uint16
|
||||
|
||||
const (
|
||||
ledgerOpRetrieveAddress ledgerOpcode = 0x02 // Returns the public key and Ethereum address for a given BIP 32 path
|
||||
ledgerOpSignTransaction ledgerOpcode = 0x04 // Signs an Ethereum transaction after having the user validate the parameters
|
||||
ledgerOpGetConfiguration ledgerOpcode = 0x06 // Returns specific wallet application configuration
|
||||
ledgerOpSignPersonalMessage ledgerOpcode = 0x08 // Signs a personal message following the EIP 712 specification
|
||||
ledgerOpSignTypedMessage ledgerOpcode = 0x0c // Signs an Ethereum message following the EIP 712 specification
|
||||
ledgerOpEip712SendStructDef ledgerOpcode = 0x1a // Sends EIP-712 struct types to the ledger
|
||||
ledgerOpEip712SendStructImpl ledgerOpcode = 0x1c // Sends EIP-712 struct values to the ledger
|
||||
|
||||
ledgerP1DirectlyFetchAddress ledgerParam1 = 0x00 // Return address directly from the wallet
|
||||
ledgerP1InitTypedMessageData ledgerParam1 = 0x00 // First chunk of Typed Message data
|
||||
ledgerP1InitTransactionData ledgerParam1 = 0x00 // First transaction data block for signing
|
||||
ledgerP1ContTransactionData ledgerParam1 = 0x80 // Subsequent transaction data block for signing
|
||||
ledgerP1CompleteSend ledgerParam1 = 0x00 // Complete the value (in one go, or after partial)
|
||||
ledgerP1PartialSend ledgerParam1 = 0x01 // Send partial data
|
||||
ledgerP2DiscardAddressChainCode ledgerParam2 = 0x00 // Do not return the chain code along with the address
|
||||
ledgerP2ProcessAndStartFlow ledgerParam2 = 0x00 // Process and start transaction signing flow
|
||||
ledgerP2V0Implementation ledgerParam2 = 0x00 // EIP-712 V0 implementation (hashes only)
|
||||
ledgerP2StructName ledgerParam2 = 0x00 // Send EIP-712 struct name
|
||||
ledgerP2RootStruct ledgerParam2 = 0x00 // Send EIP-712 root struct
|
||||
ledgerP2Array ledgerParam2 = 0x0f // Send EIP-712 array
|
||||
ledgerP2StructField ledgerParam2 = 0xff // Send EIP-712 struct field
|
||||
ledgerP2FullImplementation ledgerParam2 = 0x01 // EIP-712 full implementation (typed data)
|
||||
|
||||
ledgerStatusNormalEnd ledgerStatus = 0x9000
|
||||
ledgerEip155Size int = 3 // Size of the EIP-155 chain_id,r,s in unsigned transactions
|
||||
)
|
||||
|
||||
var ledgerStatuses = map[ledgerStatus]string{
|
||||
0x5515: "Device is locked",
|
||||
0x6001: "Mode check fail",
|
||||
0x6501: "TransactionType not supported",
|
||||
0x6502: "Output buffer too small for chainId conversion",
|
||||
0x6511: "Ethereum app not open",
|
||||
//0x68xx: "Internal error (Please report)",
|
||||
0x6982: "Security status not satisfied (Canceled by user)",
|
||||
0x6983: "Wrong Data length",
|
||||
0x6984: "Plugin not installed",
|
||||
0x6985: "Condition not satisfied",
|
||||
0x6A00: "Error without info",
|
||||
0x6A80: "Invalid data",
|
||||
0x6A84: "Insufficient memory",
|
||||
0x6A88: "Data not found",
|
||||
0x6B00: "Incorrect parameter P1 or P2",
|
||||
0x6D00: "Incorrect parameter INS",
|
||||
0x6E00: "Incorrect parameter CLA",
|
||||
0x6F00: "Incorrect parameter CLA",
|
||||
0x6F01: "Technical problem (Internal error, please report)",
|
||||
0x911C: "Command code not supported (i.e. Ledger-PKI not yet available)",
|
||||
}
|
||||
|
||||
// errLedgerReplyInvalidHeader is the error message returned by a Ledger data exchange
|
||||
// if the device replies with a mismatching header. This usually means the device
|
||||
// is in browser mode.
|
||||
|
|
@ -72,6 +115,10 @@ var errLedgerReplyInvalidHeader = errors.New("ledger: invalid reply header")
|
|||
// when a response does arrive, but it does not contain the expected data.
|
||||
var errLedgerInvalidVersionReply = errors.New("ledger: invalid version reply")
|
||||
|
||||
// errLedgerInvalidStatus is the error message returned if the ledger doesn't respond with a
|
||||
// 0x9000 status.
|
||||
var errLedgerInvalidStatus = errors.New("ledger: invalid status")
|
||||
|
||||
// ledgerDriver implements the communication with a Ledger hardware wallet.
|
||||
type ledgerDriver struct {
|
||||
device io.ReadWriter // USB device connection to communicate through
|
||||
|
|
@ -119,7 +166,7 @@ func (w *ledgerDriver) Open(device io.ReadWriter, passphrase string) error {
|
|||
_, err := w.ledgerDerive(accounts.DefaultBaseDerivationPath)
|
||||
if err != nil {
|
||||
// Ethereum app is not running or in browser mode, nothing more to do, return
|
||||
if err == errLedgerReplyInvalidHeader {
|
||||
if errors.Is(err, errLedgerReplyInvalidHeader) {
|
||||
w.browser = true
|
||||
}
|
||||
return nil
|
||||
|
|
@ -141,7 +188,7 @@ func (w *ledgerDriver) Close() error {
|
|||
// Heartbeat implements usbwallet.driver, performing a sanity check against the
|
||||
// Ledger to see if it's still online.
|
||||
func (w *ledgerDriver) Heartbeat() error {
|
||||
if _, err := w.ledgerVersion(); err != nil && err != errLedgerInvalidVersionReply {
|
||||
if _, err := w.ledgerVersion(); err != nil && !errors.Is(err, errLedgerInvalidVersionReply) {
|
||||
w.failure = err
|
||||
return err
|
||||
}
|
||||
|
|
@ -166,7 +213,7 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
|
|||
return common.Address{}, nil, accounts.ErrWalletClosed
|
||||
}
|
||||
// Ensure the wallet is capable of signing the given transaction
|
||||
if chainID != nil && (w.version[0] < 1 || (w.version[0] == 1 && w.version[1] == 0 && w.version[2] < 3)) {
|
||||
if chainID != nil && w.version[0] <= 1 && w.version[1] <= 0 && w.version[2] <= 2 {
|
||||
//lint:ignore ST1005 brand name displayed on the console
|
||||
return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2])
|
||||
}
|
||||
|
|
@ -174,11 +221,11 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
|
|||
return w.ledgerSign(path, tx, chainID)
|
||||
}
|
||||
|
||||
// SignTypedMessage implements usbwallet.driver, sending the message to the Ledger and
|
||||
// SignTypedHash implements usbwallet.driver, sending the message to the Ledger and
|
||||
// waiting for the user to sign or deny the transaction.
|
||||
//
|
||||
// Note: this was introduced in the ledger 1.5.0 firmware
|
||||
func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
func (w *ledgerDriver) SignTypedHash(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
// If the Ethereum app doesn't run, abort
|
||||
if w.offline() {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
|
|
@ -189,7 +236,39 @@ func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash
|
|||
return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2])
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
return w.ledgerSignTypedMessage(path, domainHash, messageHash)
|
||||
return w.ledgerSignTypedHash(path, domainHash, messageHash)
|
||||
}
|
||||
|
||||
// SignText implements usbwallet.driver, sending the message to the Ledger and
|
||||
// waiting for the user to confirm or deny the signature.
|
||||
func (w *ledgerDriver) SignText(path accounts.DerivationPath, text []byte) ([]byte, error) {
|
||||
// If the Ethereum app doesn't run, abort
|
||||
if w.offline() {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
// Ensure the wallet is capable of signing the given transaction
|
||||
if w.version[0] < 1 && w.version[1] < 5 {
|
||||
//lint:ignore ST1005 brand name displayed on the console
|
||||
return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2])
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
return w.ledgerSignPersonalMessage(path, text)
|
||||
}
|
||||
|
||||
// SignedTypedData implements usbwallet.driver, sending the message to the Ledger and
|
||||
// waiting for the user to sign or deny signing an EIP-712 typed data struct.
|
||||
func (w *ledgerDriver) SignedTypedData(path accounts.DerivationPath, data apitypes.TypedData) ([]byte, error) {
|
||||
// If the Ethereum app doesn't run, abort
|
||||
if w.offline() {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
// Ensure the wallet is capable of signing the given transaction
|
||||
if w.version[0] < 1 && w.version[1] < 5 {
|
||||
//lint:ignore ST1005 brand name displayed on the console
|
||||
return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2])
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
return w.ledgerSignTypedData(path, data)
|
||||
}
|
||||
|
||||
// ledgerVersion retrieves the current version of the Ethereum wallet app running
|
||||
|
|
@ -360,7 +439,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
|
|||
|
||||
// Send the request and wait for the response
|
||||
var (
|
||||
op = ledgerP1InitTransactionData
|
||||
p1 = ledgerP1InitTransactionData
|
||||
reply []byte
|
||||
)
|
||||
|
||||
|
|
@ -378,13 +457,13 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
|
|||
chunk = len(payload)
|
||||
}
|
||||
// Send the chunk over, ensuring it's processed correctly
|
||||
reply, err = w.ledgerExchange(ledgerOpSignTransaction, op, 0, payload[:chunk])
|
||||
reply, err = w.ledgerExchange(ledgerOpSignTransaction, p1, ledgerP2ProcessAndStartFlow, payload[:chunk])
|
||||
if err != nil {
|
||||
return common.Address{}, nil, err
|
||||
}
|
||||
// Shift the payload and ensure subsequent chunks are marked as such
|
||||
payload = payload[chunk:]
|
||||
op = ledgerP1ContTransactionData
|
||||
p1 = ledgerP1ContTransactionData
|
||||
}
|
||||
// Extract the Ethereum signature and do a sanity validation
|
||||
if len(reply) != crypto.SignatureLength {
|
||||
|
|
@ -414,7 +493,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
|
|||
return sender, signed, nil
|
||||
}
|
||||
|
||||
// ledgerSignTypedMessage sends the transaction to the Ledger wallet, and waits for the user
|
||||
// ledgerSignTypedHash sends the transaction to the Ledger wallet, and waits for the user
|
||||
// to confirm or deny the transaction.
|
||||
//
|
||||
// The signing protocol is defined as follows:
|
||||
|
|
@ -441,7 +520,7 @@ func (w *ledgerDriver) ledgerSign(derivationPath []uint32, tx *types.Transaction
|
|||
// signature V | 1 byte
|
||||
// signature R | 32 bytes
|
||||
// signature S | 32 bytes
|
||||
func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
func (w *ledgerDriver) ledgerSignTypedHash(derivationPath []uint32, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
// Flatten the derivation path into the Ledger request
|
||||
path := make([]byte, 1+4*len(derivationPath))
|
||||
path[0] = byte(len(derivationPath))
|
||||
|
|
@ -454,13 +533,12 @@ func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHas
|
|||
|
||||
// Send the request and wait for the response
|
||||
var (
|
||||
op = ledgerP1InitTypedMessageData
|
||||
reply []byte
|
||||
err error
|
||||
)
|
||||
|
||||
// Send the message over, ensuring it's processed correctly
|
||||
reply, err = w.ledgerExchange(ledgerOpSignTypedMessage, op, 0, payload)
|
||||
reply, err = w.ledgerExchange(ledgerOpSignTypedMessage, ledgerP1InitTypedMessageData, ledgerP2V0Implementation, payload)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -474,6 +552,281 @@ func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHas
|
|||
return signature, nil
|
||||
}
|
||||
|
||||
// ledgerSignPersonalMessage sends the transaction to the Ledger wallet, and waits for the user
|
||||
// to confirm or deny the transaction.
|
||||
//
|
||||
// The signing protocol is defined as follows:
|
||||
//
|
||||
// CLA | INS | P1 | P2 | Lc | Le
|
||||
// ----+-----+----+-----------------------------+-----+---
|
||||
// E0 | 08 | 00 | implementation version : 00 | variable | variable
|
||||
//
|
||||
// Where the input is:
|
||||
//
|
||||
// Description | Length
|
||||
// -------------------------------------------------+----------
|
||||
// Number of BIP 32 derivations to perform (max 10) | 1 byte
|
||||
// First derivation index (big endian) | 4 bytes
|
||||
// ... | 4 bytes
|
||||
// Last derivation index (big endian) | 4 bytes
|
||||
// text | arbitrary
|
||||
//
|
||||
// And the output data is:
|
||||
//
|
||||
// Description | Length
|
||||
// ------------+---------
|
||||
// signature V | 1 byte
|
||||
// signature R | 32 bytes
|
||||
// signature S | 32 bytes
|
||||
func (w *ledgerDriver) ledgerSignPersonalMessage(derivationPath []uint32, text []byte) ([]byte, error) {
|
||||
// Flatten the derivation path into the Ledger request
|
||||
path := make([]byte, 5+4*len(derivationPath))
|
||||
path[0] = byte(len(derivationPath))
|
||||
for i, component := range derivationPath {
|
||||
binary.BigEndian.PutUint32(path[1+4*i:], component)
|
||||
}
|
||||
binary.BigEndian.PutUint32(path[1+4*len(derivationPath):], uint32(len(text)))
|
||||
// Create the 712 message
|
||||
payload := append(path, text...)
|
||||
|
||||
// Send the request and wait for the response
|
||||
var (
|
||||
reply []byte
|
||||
err error
|
||||
)
|
||||
|
||||
// Send the message over, ensuring it's processed correctly
|
||||
reply, err = w.ledgerExchange(ledgerOpSignPersonalMessage, ledgerP1InitTransactionData, 0, payload)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract the Ethereum signature and do a sanity validation
|
||||
if len(reply) != crypto.SignatureLength {
|
||||
return nil, errors.New("reply lacks signature")
|
||||
}
|
||||
signature := append(reply[1:], reply[0])
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// ledgerSignTypedData sends the transaction to the Ledger wallet, and waits for the user
|
||||
// to confirm or deny the transaction.
|
||||
//
|
||||
// The typed data struct fields and values need to be sent to the Ledger first.
|
||||
// See https://github.com/LedgerHQ/app-ethereum/blob/develop/doc/eip712.md.
|
||||
//
|
||||
// After the data is sent, the signing protocol is defined as follows:
|
||||
//
|
||||
// CLA | INS | P1 | P2 | Lc | Le
|
||||
// ----+-----+----+-----------------------------+-----+---
|
||||
// E0 | 0C | 00 | implementation version : 00 | variable | variable
|
||||
//
|
||||
// Where the input is:
|
||||
//
|
||||
// Description | Length
|
||||
// -------------------------------------------------+----------
|
||||
// Number of BIP 32 derivations to perform (max 10) | 1 byte
|
||||
// First derivation index (big endian) | 4 bytes
|
||||
// ... | 4 bytes
|
||||
// Last derivation index (big endian) | 4 bytes
|
||||
//
|
||||
// And the output data is:
|
||||
//
|
||||
// Description | Length
|
||||
// ------------+---------
|
||||
// signature V | 1 byte
|
||||
// signature R | 32 bytes
|
||||
// signature S | 32 bytes
|
||||
func (w *ledgerDriver) ledgerSignTypedData(derivationPath []uint32, data apitypes.TypedData) ([]byte, error) {
|
||||
// Check if the EIP712Domain and primary type are present in the data
|
||||
domainStruct := data.Types["EIP712Domain"]
|
||||
if domainStruct == nil {
|
||||
return nil, fmt.Errorf("EIP712Domain type is required")
|
||||
}
|
||||
primaryType := data.Types[data.PrimaryType]
|
||||
if primaryType == nil {
|
||||
return nil, fmt.Errorf("primary type %s not found in types", data.PrimaryType)
|
||||
}
|
||||
|
||||
// sendField is a function for sending an EIP-712 struct field name + type
|
||||
sendField := func(field apitypes.Type) error {
|
||||
dt, name, byteLength, arrays, err := parseType(data, field)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
typeDesc := byte(dt)
|
||||
|
||||
var typeName []byte
|
||||
var typeSize []byte
|
||||
switch dt {
|
||||
case CustomType:
|
||||
typeName = append([]byte{byte(len(name))}, []byte(name)...)
|
||||
case IntType, UintType, FixedBytesType:
|
||||
typeSize = []byte{byte(byteLength)}
|
||||
typeDesc |= 0x40
|
||||
default:
|
||||
}
|
||||
|
||||
var arrayLevels []byte
|
||||
if len(arrays) > 0 {
|
||||
typeDesc |= 0x80
|
||||
arrayLevels = []byte{byte(len(arrays))}
|
||||
for _, length := range arrays {
|
||||
if length == nil {
|
||||
arrayLevels = append(arrayLevels, 0)
|
||||
} else {
|
||||
arrayLevels = append(arrayLevels, 1, byte(*length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
payload := []byte{typeDesc}
|
||||
payload = append(payload, typeName...)
|
||||
payload = append(payload, typeSize...)
|
||||
payload = append(payload, arrayLevels...)
|
||||
payload = append(payload, byte(len(field.Name)))
|
||||
payload = append(payload, []byte(field.Name)...)
|
||||
_, err = w.ledgerExchange(ledgerOpEip712SendStructDef, 0, ledgerP2StructField, payload)
|
||||
return err
|
||||
}
|
||||
|
||||
// sendValue is a recursive function that sends the value of a field
|
||||
var sendValue func(t, name string, value interface{}) error
|
||||
sendValue = func(t, name string, value interface{}) error {
|
||||
if value == nil {
|
||||
return fmt.Errorf("nil value for field %s", name)
|
||||
}
|
||||
if strings.HasSuffix(t, "]") {
|
||||
a, ok := value.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("expected array for field %s, got %T", name, value)
|
||||
}
|
||||
if _, err := w.ledgerExchange(ledgerOpEip712SendStructImpl, ledgerP1CompleteSend, ledgerP2Array, []byte{byte(len(a))}); err != nil {
|
||||
return fmt.Errorf("failed to send array length: %w", err)
|
||||
}
|
||||
t = t[:strings.LastIndex(t, "[")]
|
||||
for _, item := range a {
|
||||
if err := sendValue(t, name, item); err != nil {
|
||||
return fmt.Errorf("failed to send array item: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
s := data.Types[t]
|
||||
if s != nil {
|
||||
m, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("expected struct for field %s, got %T", name, value)
|
||||
}
|
||||
for _, field := range s {
|
||||
if err := sendValue(field.Type, field.Name, m[field.Name]); err != nil {
|
||||
return fmt.Errorf("failed to send struct field %s: %w", field.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
var enc []byte
|
||||
var err error
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
if t == "string" {
|
||||
enc = []byte(v)
|
||||
} else if strings.HasPrefix(v, "0x") {
|
||||
enc, err = hex.DecodeString(v[2:])
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode hex string for field %s: %w", name, err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("invalid string value for field %s: %s", name, v)
|
||||
}
|
||||
case bool:
|
||||
if v {
|
||||
enc = []byte{1}
|
||||
} else {
|
||||
enc = []byte{0}
|
||||
}
|
||||
case float64:
|
||||
enc = new(big.Int).SetInt64(int64(v)).Bytes()
|
||||
case *math.HexOrDecimal256:
|
||||
if v == nil {
|
||||
return fmt.Errorf("nil value for field %s", name)
|
||||
}
|
||||
h := big.Int(*v)
|
||||
enc = (&h).Bytes()
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported type for field %s: %T", name, value)
|
||||
}
|
||||
|
||||
chunk := 255
|
||||
payload := binary.BigEndian.AppendUint16([]byte{}, uint16(len(enc)))
|
||||
payload = append(payload, enc...)
|
||||
for len(payload) > 0 {
|
||||
p1 := ledgerP1PartialSend
|
||||
if chunk >= len(payload) {
|
||||
chunk = len(payload)
|
||||
p1 = ledgerP1CompleteSend
|
||||
}
|
||||
if _, err := w.ledgerExchange(ledgerOpEip712SendStructImpl, p1, ledgerP2StructField, payload[:chunk]); err != nil {
|
||||
return fmt.Errorf("failed to send field %s: %w", name, err)
|
||||
}
|
||||
payload = payload[chunk:]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// first send all the EIP-712 struct definitions
|
||||
for name, fields := range data.Types {
|
||||
_, err := w.ledgerExchange(ledgerOpEip712SendStructDef, 0, ledgerP2StructName, []byte(name))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to send type name %s: %w", name, err)
|
||||
}
|
||||
for _, field := range fields {
|
||||
if err := sendField(field); err != nil {
|
||||
return nil, fmt.Errorf("failed to send field %s: %w", field.Name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send the EIP-712 domain field values
|
||||
if _, err := w.ledgerExchange(ledgerOpEip712SendStructImpl, ledgerP1CompleteSend, ledgerP2RootStruct, []byte("EIP712Domain")); err != nil {
|
||||
return nil, fmt.Errorf("failed to send domain type name: %w", err)
|
||||
}
|
||||
if err := sendValue("EIP712Domain", "domain", data.Domain.Map()); err != nil {
|
||||
return nil, fmt.Errorf("failed to send domain fields: %w", err)
|
||||
}
|
||||
|
||||
// send the message field values
|
||||
if _, err := w.ledgerExchange(ledgerOpEip712SendStructImpl, ledgerP1CompleteSend, ledgerP2RootStruct, []byte(data.PrimaryType)); err != nil {
|
||||
return nil, fmt.Errorf("failed to send primary type name: %w", err)
|
||||
}
|
||||
if err := sendValue(data.PrimaryType, "message", data.Message); err != nil {
|
||||
return nil, fmt.Errorf("failed to send primary type fields: %w", err)
|
||||
}
|
||||
|
||||
// Flatten the derivation path into the Ledger request
|
||||
path := make([]byte, 1+4*len(derivationPath))
|
||||
path[0] = byte(len(derivationPath))
|
||||
for i, component := range derivationPath {
|
||||
binary.BigEndian.PutUint32(path[1+4*i:], component)
|
||||
}
|
||||
|
||||
// Send the message over, ensuring it's processed correctly
|
||||
reply, err := w.ledgerExchange(ledgerOpSignTypedMessage, 0, ledgerP2FullImplementation, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract the Ethereum signature and do a sanity validation
|
||||
if len(reply) != crypto.SignatureLength {
|
||||
return nil, fmt.Errorf("invalid signature length: %d", len(reply))
|
||||
}
|
||||
signature := append(reply[1:], reply[0])
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// ledgerExchange performs a data exchange with the Ledger wallet, sending it a
|
||||
// message and retrieving the response.
|
||||
//
|
||||
|
|
@ -508,6 +861,16 @@ func (w *ledgerDriver) ledgerSignTypedMessage(derivationPath []uint32, domainHas
|
|||
// APDU length | 1 byte
|
||||
// Optional APDU data | arbitrary
|
||||
func (w *ledgerDriver) ledgerExchange(opcode ledgerOpcode, p1 ledgerParam1, p2 ledgerParam2, data []byte) ([]byte, error) {
|
||||
for i := 1; ; i++ {
|
||||
res, err := w._ledgerExchange(opcode, p1, p2, data)
|
||||
// on failure, try the exchange 3 times in total
|
||||
if err == nil || i == 3 {
|
||||
return res, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (w *ledgerDriver) _ledgerExchange(opcode ledgerOpcode, p1 ledgerParam1, p2 ledgerParam2, data []byte) ([]byte, error) {
|
||||
// Construct the message payload, possibly split into multiple chunks
|
||||
apdu := make([]byte, 2, 7+len(data))
|
||||
|
||||
|
|
@ -569,5 +932,16 @@ func (w *ledgerDriver) ledgerExchange(opcode ledgerOpcode, p1 ledgerParam1, p2 l
|
|||
break
|
||||
}
|
||||
}
|
||||
if len(reply) < 2 {
|
||||
return nil, errLedgerInvalidStatus
|
||||
}
|
||||
status := ledgerStatus(binary.BigEndian.Uint16(reply[len(reply)-2:]))
|
||||
if status != ledgerStatusNormalEnd {
|
||||
s := ledgerStatuses[status]
|
||||
if s == "" {
|
||||
s = "unknown error"
|
||||
}
|
||||
return nil, fmt.Errorf("%w: 0x%s (%s)", errLedgerInvalidStatus, strconv.FormatUint(uint64(status), 16), s)
|
||||
}
|
||||
return reply[:len(reply)-2], nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"reflect"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
||||
|
|
@ -34,29 +35,32 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
pin "github.com/reserve-protocol/trezor"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In
|
||||
// this case, the calling application should display a pinpad and send back the
|
||||
// encoded passphrase.
|
||||
var ErrTrezorPINNeeded = errors.New("trezor: pin needed")
|
||||
|
||||
// ErrTrezorPassphraseNeeded is returned if opening the trezor requires a passphrase
|
||||
var ErrTrezorPassphraseNeeded = errors.New("trezor: passphrase needed")
|
||||
|
||||
// errTrezorReplyInvalidHeader is the error message returned by a Trezor data exchange
|
||||
// if the device replies with a mismatching header. This usually means the device
|
||||
// is in browser mode.
|
||||
var errTrezorReplyInvalidHeader = errors.New("trezor: invalid reply header")
|
||||
|
||||
type TrezorFailure struct {
|
||||
*trezor.Failure
|
||||
}
|
||||
|
||||
// Error implements the error interface for the TrezorFailure type, returning
|
||||
// a formatted error message containing the failure reason.
|
||||
func (f *TrezorFailure) Error() string {
|
||||
return fmt.Sprintf("trezor: %s", f.GetMessage())
|
||||
}
|
||||
|
||||
// trezorDriver implements the communication with a Trezor hardware wallet.
|
||||
type trezorDriver struct {
|
||||
device io.ReadWriter // USB device connection to communicate through
|
||||
version [3]uint32 // Current version of the Trezor firmware
|
||||
label string // Current textual label of the Trezor device
|
||||
pinwait bool // Flags whether the device is waiting for PIN entry
|
||||
passphrasewait bool // Flags whether the device is waiting for passphrase entry
|
||||
passphrase string
|
||||
failure error // Any failure that would make the device unusable
|
||||
log log.Logger // Contextual logger to tag the trezor with its id
|
||||
}
|
||||
|
|
@ -77,33 +81,18 @@ func (w *trezorDriver) Status() (string, error) {
|
|||
if w.device == nil {
|
||||
return "Closed", w.failure
|
||||
}
|
||||
if w.pinwait {
|
||||
return fmt.Sprintf("Trezor v%d.%d.%d '%s' waiting for PIN", w.version[0], w.version[1], w.version[2], w.label), w.failure
|
||||
}
|
||||
return fmt.Sprintf("Trezor v%d.%d.%d '%s' online", w.version[0], w.version[1], w.version[2], w.label), w.failure
|
||||
}
|
||||
|
||||
// Open implements usbwallet.driver, attempting to initialize the connection to
|
||||
// the Trezor hardware wallet. Initializing the Trezor is a two or three phase operation:
|
||||
// - The first phase is to initialize the connection and read the wallet's
|
||||
// features. This phase is invoked if the provided passphrase is empty. The
|
||||
// device will display the pinpad as a result and will return an appropriate
|
||||
// error to notify the user that a second open phase is needed.
|
||||
// - The second phase is to unlock access to the Trezor, which is done by the
|
||||
// user actually providing a passphrase mapping a keyboard keypad to the pin
|
||||
// number of the user (shuffled according to the pinpad displayed).
|
||||
// - If needed the device will ask for passphrase which will require calling
|
||||
// open again with the actual passphrase (3rd phase)
|
||||
// the Trezor hardware wallet.
|
||||
func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error {
|
||||
w.device, w.failure = device, nil
|
||||
w.device, w.passphrase, w.failure = device, passphrase, nil
|
||||
|
||||
// If phase 1 is requested, init the connection and wait for user callback
|
||||
if passphrase == "" && !w.passphrasewait {
|
||||
// If we're already waiting for a PIN entry, insta-return
|
||||
if w.pinwait {
|
||||
return ErrTrezorPINNeeded
|
||||
if _, err := w.trezorExchange(&trezor.EndSession{}, new(trezor.Success)); err != nil {
|
||||
return err
|
||||
}
|
||||
// Initialize a connection to the device
|
||||
|
||||
features := new(trezor.Features)
|
||||
if _, err := w.trezorExchange(&trezor.Initialize{}, features); err != nil {
|
||||
return err
|
||||
|
|
@ -111,53 +100,13 @@ func (w *trezorDriver) Open(device io.ReadWriter, passphrase string) error {
|
|||
w.version = [3]uint32{features.GetMajorVersion(), features.GetMinorVersion(), features.GetPatchVersion()}
|
||||
w.label = features.GetLabel()
|
||||
|
||||
// Do a manual ping, forcing the device to ask for its PIN and Passphrase
|
||||
askPin := true
|
||||
askPassphrase := true
|
||||
res, err := w.trezorExchange(&trezor.Ping{PinProtection: &askPin, PassphraseProtection: &askPassphrase}, new(trezor.PinMatrixRequest), new(trezor.PassphraseRequest), new(trezor.Success))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Only return the PIN request if the device wasn't unlocked until now
|
||||
switch res {
|
||||
case 0:
|
||||
w.pinwait = true
|
||||
return ErrTrezorPINNeeded
|
||||
case 1:
|
||||
w.pinwait = false
|
||||
w.passphrasewait = true
|
||||
return ErrTrezorPassphraseNeeded
|
||||
case 2:
|
||||
return nil // responded with trezor.Success
|
||||
}
|
||||
}
|
||||
// Phase 2 requested with actual PIN entry
|
||||
if w.pinwait {
|
||||
w.pinwait = false
|
||||
res, err := w.trezorExchange(&trezor.PinMatrixAck{Pin: &passphrase}, new(trezor.Success), new(trezor.PassphraseRequest))
|
||||
if err != nil {
|
||||
w.failure = err
|
||||
return err
|
||||
}
|
||||
if res == 1 {
|
||||
w.passphrasewait = true
|
||||
return ErrTrezorPassphraseNeeded
|
||||
}
|
||||
} else if w.passphrasewait {
|
||||
w.passphrasewait = false
|
||||
if _, err := w.trezorExchange(&trezor.PassphraseAck{Passphrase: &passphrase}, new(trezor.Success)); err != nil {
|
||||
w.failure = err
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return w.Heartbeat()
|
||||
}
|
||||
|
||||
// Close implements usbwallet.driver, cleaning up and metadata maintained within
|
||||
// the Trezor driver.
|
||||
func (w *trezorDriver) Close() error {
|
||||
w.version, w.label, w.pinwait = [3]uint32{}, "", false
|
||||
w.version, w.label = [3]uint32{}, ""
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -186,8 +135,236 @@ func (w *trezorDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
|
|||
return w.trezorSign(path, tx, chainID)
|
||||
}
|
||||
|
||||
func (w *trezorDriver) SignTypedMessage(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
return nil, accounts.ErrNotSupported
|
||||
func (w *trezorDriver) SignTypedHash(path accounts.DerivationPath, domainHash []byte, messageHash []byte) ([]byte, error) {
|
||||
if w.device == nil {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
response := new(trezor.EthereumTypedDataSignature)
|
||||
_, err := w.trezorExchange(&trezor.EthereumSignTypedHash{
|
||||
AddressN: path,
|
||||
DomainSeparatorHash: domainHash,
|
||||
MessageHash: messageHash,
|
||||
}, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.Signature, nil
|
||||
}
|
||||
|
||||
func (w *trezorDriver) SignText(path accounts.DerivationPath, text []byte) ([]byte, error) {
|
||||
if w.device == nil {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
response := new(trezor.EthereumMessageSignature)
|
||||
_, err := w.trezorExchange(&trezor.EthereumSignMessage{
|
||||
AddressN: path,
|
||||
Message: text,
|
||||
}, response)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response.Signature, nil
|
||||
}
|
||||
|
||||
func (w *trezorDriver) SignedTypedData(path accounts.DerivationPath, data apitypes.TypedData) ([]byte, error) {
|
||||
if w.device == nil {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
|
||||
_, hashes, err := apitypes.TypedDataAndHash(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("trezor: error hashing typed data: %w", err)
|
||||
}
|
||||
domainHash, messageHash := hashes[2:34], hashes[34:66]
|
||||
if w.version[0] == 1 {
|
||||
// legacy Trezor devices don't support typed data; fallback to hash signing:
|
||||
return w.SignTypedHash(path, []byte(domainHash), []byte(messageHash))
|
||||
}
|
||||
|
||||
if w.version[0] == 2 && (w.version[1] < 9 || (w.version[1] == 9 && w.version[2] == 0)) {
|
||||
// ShowMessageHash was introduced in Trezor firmware v2.9.1
|
||||
return nil, fmt.Errorf("trezor: typed data signing requires firmware v2.9.1 or newer")
|
||||
}
|
||||
|
||||
signature := new(trezor.EthereumTypedDataSignature)
|
||||
structRequest := new(trezor.EthereumTypedDataStructRequest)
|
||||
valueRequest := new(trezor.EthereumTypedDataValueRequest)
|
||||
var req proto.Message = &trezor.EthereumSignTypedData{
|
||||
AddressN: path,
|
||||
PrimaryType: &data.PrimaryType,
|
||||
ShowMessageHash: []byte(messageHash),
|
||||
}
|
||||
nestedArray := false
|
||||
for {
|
||||
n, err := w.trezorExchange(req, signature, structRequest, valueRequest)
|
||||
if err != nil {
|
||||
var trezorFailure *TrezorFailure
|
||||
if nestedArray && errors.As(err, &trezorFailure) &&
|
||||
trezorFailure.Code != nil && *trezorFailure.Code == trezor.Failure_Failure_FirmwareError {
|
||||
return nil, fmt.Errorf("trezor: nested arrays are not supported by this firmware version: %w", err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
nestedArray = false
|
||||
switch n {
|
||||
case 0:
|
||||
// No additional data needed, return the signature
|
||||
return signature.Signature, nil
|
||||
case 1:
|
||||
fields := data.Types[structRequest.GetName()]
|
||||
if len(fields) == 0 {
|
||||
return nil, fmt.Errorf("trezor: no fields for struct %s", structRequest.GetName())
|
||||
}
|
||||
ack := &trezor.EthereumTypedDataStructAck{
|
||||
Members: make([]*trezor.EthereumTypedDataStructAck_EthereumStructMember, len(fields)),
|
||||
}
|
||||
for i, field := range fields {
|
||||
dt, name, byteLength, arrays, err := parseType(data, field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ubyteLength := uint32(byteLength)
|
||||
t := &trezor.EthereumTypedDataStructAck_EthereumFieldType{}
|
||||
inner := t
|
||||
for i := len(arrays) - 1; i >= 0; i-- {
|
||||
dataType := trezor.EthereumTypedDataStructAck_ARRAY
|
||||
inner.DataType = &dataType
|
||||
if arrays[i] != nil {
|
||||
length := uint32(*arrays[i])
|
||||
inner.Size = &length
|
||||
}
|
||||
inner.EntryType = &trezor.EthereumTypedDataStructAck_EthereumFieldType{}
|
||||
inner = inner.EntryType
|
||||
}
|
||||
var dataType trezor.EthereumTypedDataStructAck_EthereumDataType
|
||||
switch dt {
|
||||
case CustomType:
|
||||
inner.StructName = &name
|
||||
dataType = trezor.EthereumTypedDataStructAck_STRUCT
|
||||
members := uint32(len(data.Types[name]))
|
||||
inner.Size = &members
|
||||
case IntType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_INT
|
||||
inner.Size = &ubyteLength
|
||||
case UintType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_UINT
|
||||
inner.Size = &ubyteLength
|
||||
case AddressType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_ADDRESS
|
||||
case BoolType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_BOOL
|
||||
case StringType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_STRING
|
||||
case FixedBytesType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_BYTES
|
||||
inner.Size = &ubyteLength
|
||||
case BytesType:
|
||||
dataType = trezor.EthereumTypedDataStructAck_BYTES
|
||||
}
|
||||
inner.DataType = &dataType
|
||||
ack.Members[i] = &trezor.EthereumTypedDataStructAck_EthereumStructMember{
|
||||
Name: &field.Name,
|
||||
Type: t,
|
||||
}
|
||||
}
|
||||
req = ack
|
||||
case 2:
|
||||
structType := data.Types[data.PrimaryType]
|
||||
structValue := data.Message
|
||||
if valueRequest.MemberPath[0] == 0 {
|
||||
// populate with domain info
|
||||
structType = data.Types["EIP712Domain"]
|
||||
structValue = data.Domain.Map()
|
||||
}
|
||||
var value []byte
|
||||
for i := 1; i < len(valueRequest.MemberPath); i++ {
|
||||
p := valueRequest.MemberPath[i]
|
||||
if structType == nil {
|
||||
return nil, fmt.Errorf("trezor: no struct type for path %v", path)
|
||||
}
|
||||
if int(p) >= len(structType) {
|
||||
return nil, fmt.Errorf("trezor: invalid field index %d for struct %s", p, structRequest.GetName())
|
||||
}
|
||||
field := structType[p]
|
||||
nextValue := structValue[field.Name]
|
||||
dt, name, byteLength, arrays, err := parseType(data, field)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(arrays) > 1 {
|
||||
nestedArray = true
|
||||
}
|
||||
for j := 0; j < len(arrays) && i < len(valueRequest.MemberPath)-1; i, j = i+1, j+1 {
|
||||
k := reflect.TypeOf(nextValue).Kind()
|
||||
if !(k == reflect.Array || k == reflect.Slice) {
|
||||
return nil, fmt.Errorf("trezor: expected array at path %v, got %T", valueRequest.MemberPath[:i+1], nextValue)
|
||||
}
|
||||
a := reflect.ValueOf(nextValue)
|
||||
p = valueRequest.MemberPath[i+1]
|
||||
if int(p) >= a.Len() {
|
||||
return nil, fmt.Errorf("trezor: invalid array index %d for path %v", p, valueRequest.MemberPath[:i+1])
|
||||
}
|
||||
nextValue = a.Index(int(p)).Interface()
|
||||
}
|
||||
k := reflect.TypeOf(nextValue).Kind()
|
||||
if i < len(valueRequest.MemberPath)-1 {
|
||||
if reflect.TypeOf(nextValue).Kind() != reflect.Map {
|
||||
return nil, fmt.Errorf("trezor: expected map at path %v, got %T", valueRequest.MemberPath[:i+1], nextValue)
|
||||
}
|
||||
structType = data.Types[name]
|
||||
structValue = nextValue.(apitypes.TypedDataMessage)
|
||||
} else if k == reflect.Array || k == reflect.Slice {
|
||||
// Array value, return length as uint16
|
||||
value = binary.BigEndian.AppendUint16([]byte{}, uint16(reflect.ValueOf(nextValue).Len()))
|
||||
} else {
|
||||
// Last value, encode it as a primitive value
|
||||
switch dt {
|
||||
case CustomType:
|
||||
return nil, fmt.Errorf("trezor: cannot encode custom type %s at path %v", name, valueRequest.MemberPath[:i+1])
|
||||
case IntType, UintType, AddressType, FixedBytesType:
|
||||
if str, ok := nextValue.(string); ok {
|
||||
value = common.FromHex(str)
|
||||
} else if f, ok := nextValue.(float64); ok {
|
||||
value = new(big.Int).SetInt64(int64(f)).Bytes()
|
||||
}
|
||||
if len(value) > byteLength {
|
||||
return nil, fmt.Errorf("trezor: value at path %v is too long (%d bytes, expected %d)", valueRequest.MemberPath[:i+1], len(value), byteLength)
|
||||
}
|
||||
for len(value) < byteLength {
|
||||
value = append([]byte{0}, value...)
|
||||
}
|
||||
case BoolType:
|
||||
if b, ok := nextValue.(bool); ok {
|
||||
if b {
|
||||
value = []byte{1}
|
||||
} else {
|
||||
value = []byte{0}
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("trezor: expected bool at path %v, got %T", valueRequest.MemberPath[:i+1], nextValue)
|
||||
}
|
||||
case StringType:
|
||||
if str, ok := nextValue.(string); ok {
|
||||
value = []byte(str)
|
||||
} else {
|
||||
return nil, fmt.Errorf("trezor: expected string at path %v, got %T", valueRequest.MemberPath[:i+1], nextValue)
|
||||
}
|
||||
case BytesType:
|
||||
if str, ok := nextValue.(string); ok {
|
||||
value = common.FromHex(str)
|
||||
} else {
|
||||
return nil, fmt.Errorf("trezor: expected bytes at path %v, got %T", valueRequest.MemberPath[:i+1], nextValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
req = &trezor.EthereumTypedDataValueAck{
|
||||
Value: value,
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("trezor: unexpected reply index %d", n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// trezorDerive sends a derivation request to the Trezor device and returns the
|
||||
|
|
@ -197,10 +374,7 @@ func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, er
|
|||
if _, err := w.trezorExchange(&trezor.EthereumGetAddress{AddressN: derivationPath}, address); err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
if addr := address.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary formats
|
||||
return common.BytesToAddress(addr), nil
|
||||
}
|
||||
if addr := address.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal formats
|
||||
if addr := address.GetAddress(); len(addr) > 0 {
|
||||
return common.HexToAddress(addr), nil
|
||||
}
|
||||
return common.Address{}, errors.New("missing derived address")
|
||||
|
|
@ -224,8 +398,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction
|
|||
if to := tx.To(); to != nil {
|
||||
// Non contract deploy, set recipient explicitly
|
||||
hex := to.Hex()
|
||||
request.ToHex = &hex // Newer firmwares (old will ignore)
|
||||
request.ToBin = (*to)[:] // Older firmwares (new will ignore)
|
||||
request.To = &hex
|
||||
}
|
||||
if length > 1024 { // Send the data chunked if that was requested
|
||||
request.DataInitialChunk, data = data[:1024], data[1024:]
|
||||
|
|
@ -233,7 +406,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction
|
|||
request.DataInitialChunk, data = data, nil
|
||||
}
|
||||
if chainID != nil { // EIP-155 transaction, set chain ID explicitly (only 32 bit is supported!?)
|
||||
id := uint32(chainID.Int64())
|
||||
id := chainID.Uint64()
|
||||
request.ChainId = &id
|
||||
}
|
||||
// Send the initiation message and stream content until a signature is returned
|
||||
|
|
@ -250,11 +423,7 @@ func (w *trezorDriver) trezorSign(derivationPath []uint32, tx *types.Transaction
|
|||
}
|
||||
}
|
||||
// Extract the Ethereum signature and do a sanity validation
|
||||
if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 {
|
||||
return common.Address{}, nil, errors.New("reply lacks signature")
|
||||
} else if response.GetSignatureV() == 0 && int(chainID.Int64()) <= (math.MaxUint32-36)/2 {
|
||||
// for chainId >= (MaxUint32-36)/2, Trezor returns signature bit only
|
||||
// https://github.com/trezor/trezor-mcu/pull/399
|
||||
if len(response.GetSignatureR()) == 0 || len(response.GetSignatureS()) == 0 || response.GetSignatureV() == 0 {
|
||||
return common.Address{}, nil, errors.New("reply lacks signature")
|
||||
}
|
||||
signature := append(append(response.GetSignatureR(), response.GetSignatureS()...), byte(response.GetSignatureV()))
|
||||
|
|
@ -361,12 +530,22 @@ func (w *trezorDriver) trezorExchange(req proto.Message, results ...proto.Messag
|
|||
if err := proto.Unmarshal(reply, failure); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return 0, errors.New("trezor: " + failure.GetMessage())
|
||||
return 0, &TrezorFailure{Failure: failure}
|
||||
}
|
||||
if kind == uint16(trezor.MessageType_MessageType_ButtonRequest) {
|
||||
// Trezor is waiting for user confirmation, ack and wait for the next message
|
||||
return w.trezorExchange(&trezor.ButtonAck{}, results...)
|
||||
}
|
||||
if kind == uint16(trezor.MessageType_MessageType_PinMatrixRequest) {
|
||||
p, err := pin.GetPIN("Please enter your Trezor PIN")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return w.trezorExchange(&trezor.PinMatrixAck{Pin: &p}, results...)
|
||||
}
|
||||
if kind == uint16(trezor.MessageType_MessageType_PassphraseRequest) {
|
||||
return w.trezorExchange(&trezor.PassphraseAck{Passphrase: &w.passphrase}, results...)
|
||||
}
|
||||
for i, res := range results {
|
||||
if trezor.Type(res) == kind {
|
||||
return i, proto.Unmarshal(reply, res)
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto
|
||||
// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9.
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.34.2
|
||||
// protoc v5.27.1
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v4.25.3
|
||||
// source: messages-common.proto
|
||||
|
||||
package trezor
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -39,6 +41,12 @@ const (
|
|||
Failure_Failure_NotEnoughFunds Failure_FailureType = 10
|
||||
Failure_Failure_NotInitialized Failure_FailureType = 11
|
||||
Failure_Failure_PinMismatch Failure_FailureType = 12
|
||||
Failure_Failure_WipeCodeMismatch Failure_FailureType = 13
|
||||
Failure_Failure_InvalidSession Failure_FailureType = 14
|
||||
Failure_Failure_Busy Failure_FailureType = 15
|
||||
Failure_Failure_ThpUnallocatedSession Failure_FailureType = 16
|
||||
Failure_Failure_InvalidProtocol Failure_FailureType = 17
|
||||
Failure_Failure_BufferError Failure_FailureType = 18
|
||||
Failure_Failure_FirmwareError Failure_FailureType = 99
|
||||
)
|
||||
|
||||
|
|
@ -57,6 +65,12 @@ var (
|
|||
10: "Failure_NotEnoughFunds",
|
||||
11: "Failure_NotInitialized",
|
||||
12: "Failure_PinMismatch",
|
||||
13: "Failure_WipeCodeMismatch",
|
||||
14: "Failure_InvalidSession",
|
||||
15: "Failure_Busy",
|
||||
16: "Failure_ThpUnallocatedSession",
|
||||
17: "Failure_InvalidProtocol",
|
||||
18: "Failure_BufferError",
|
||||
99: "Failure_FirmwareError",
|
||||
}
|
||||
Failure_FailureType_value = map[string]int32{
|
||||
|
|
@ -72,6 +86,12 @@ var (
|
|||
"Failure_NotEnoughFunds": 10,
|
||||
"Failure_NotInitialized": 11,
|
||||
"Failure_PinMismatch": 12,
|
||||
"Failure_WipeCodeMismatch": 13,
|
||||
"Failure_InvalidSession": 14,
|
||||
"Failure_Busy": 15,
|
||||
"Failure_ThpUnallocatedSession": 16,
|
||||
"Failure_InvalidProtocol": 17,
|
||||
"Failure_BufferError": 18,
|
||||
"Failure_FirmwareError": 99,
|
||||
}
|
||||
)
|
||||
|
|
@ -131,8 +151,14 @@ const (
|
|||
ButtonRequest_ButtonRequest_PublicKey ButtonRequest_ButtonRequestType = 11
|
||||
ButtonRequest_ButtonRequest_MnemonicWordCount ButtonRequest_ButtonRequestType = 12
|
||||
ButtonRequest_ButtonRequest_MnemonicInput ButtonRequest_ButtonRequestType = 13
|
||||
ButtonRequest_ButtonRequest_PassphraseType ButtonRequest_ButtonRequestType = 14
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
ButtonRequest__Deprecated_ButtonRequest_PassphraseType ButtonRequest_ButtonRequestType = 14
|
||||
ButtonRequest_ButtonRequest_UnknownDerivationPath ButtonRequest_ButtonRequestType = 15
|
||||
ButtonRequest_ButtonRequest_RecoveryHomepage ButtonRequest_ButtonRequestType = 16
|
||||
ButtonRequest_ButtonRequest_Success ButtonRequest_ButtonRequestType = 17
|
||||
ButtonRequest_ButtonRequest_Warning ButtonRequest_ButtonRequestType = 18
|
||||
ButtonRequest_ButtonRequest_PassphraseEntry ButtonRequest_ButtonRequestType = 19
|
||||
ButtonRequest_ButtonRequest_PinEntry ButtonRequest_ButtonRequestType = 20
|
||||
)
|
||||
|
||||
// Enum value maps for ButtonRequest_ButtonRequestType.
|
||||
|
|
@ -151,8 +177,13 @@ var (
|
|||
11: "ButtonRequest_PublicKey",
|
||||
12: "ButtonRequest_MnemonicWordCount",
|
||||
13: "ButtonRequest_MnemonicInput",
|
||||
14: "ButtonRequest_PassphraseType",
|
||||
14: "_Deprecated_ButtonRequest_PassphraseType",
|
||||
15: "ButtonRequest_UnknownDerivationPath",
|
||||
16: "ButtonRequest_RecoveryHomepage",
|
||||
17: "ButtonRequest_Success",
|
||||
18: "ButtonRequest_Warning",
|
||||
19: "ButtonRequest_PassphraseEntry",
|
||||
20: "ButtonRequest_PinEntry",
|
||||
}
|
||||
ButtonRequest_ButtonRequestType_value = map[string]int32{
|
||||
"ButtonRequest_Other": 1,
|
||||
|
|
@ -168,8 +199,13 @@ var (
|
|||
"ButtonRequest_PublicKey": 11,
|
||||
"ButtonRequest_MnemonicWordCount": 12,
|
||||
"ButtonRequest_MnemonicInput": 13,
|
||||
"ButtonRequest_PassphraseType": 14,
|
||||
"_Deprecated_ButtonRequest_PassphraseType": 14,
|
||||
"ButtonRequest_UnknownDerivationPath": 15,
|
||||
"ButtonRequest_RecoveryHomepage": 16,
|
||||
"ButtonRequest_Success": 17,
|
||||
"ButtonRequest_Warning": 18,
|
||||
"ButtonRequest_PassphraseEntry": 19,
|
||||
"ButtonRequest_PinEntry": 20,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -218,6 +254,8 @@ const (
|
|||
PinMatrixRequest_PinMatrixRequestType_Current PinMatrixRequest_PinMatrixRequestType = 1
|
||||
PinMatrixRequest_PinMatrixRequestType_NewFirst PinMatrixRequest_PinMatrixRequestType = 2
|
||||
PinMatrixRequest_PinMatrixRequestType_NewSecond PinMatrixRequest_PinMatrixRequestType = 3
|
||||
PinMatrixRequest_PinMatrixRequestType_WipeCodeFirst PinMatrixRequest_PinMatrixRequestType = 4
|
||||
PinMatrixRequest_PinMatrixRequestType_WipeCodeSecond PinMatrixRequest_PinMatrixRequestType = 5
|
||||
)
|
||||
|
||||
// Enum value maps for PinMatrixRequest_PinMatrixRequestType.
|
||||
|
|
@ -226,11 +264,15 @@ var (
|
|||
1: "PinMatrixRequestType_Current",
|
||||
2: "PinMatrixRequestType_NewFirst",
|
||||
3: "PinMatrixRequestType_NewSecond",
|
||||
4: "PinMatrixRequestType_WipeCodeFirst",
|
||||
5: "PinMatrixRequestType_WipeCodeSecond",
|
||||
}
|
||||
PinMatrixRequest_PinMatrixRequestType_value = map[string]int32{
|
||||
"PinMatrixRequestType_Current": 1,
|
||||
"PinMatrixRequestType_NewFirst": 2,
|
||||
"PinMatrixRequestType_NewSecond": 3,
|
||||
"PinMatrixRequestType_WipeCodeFirst": 4,
|
||||
"PinMatrixRequestType_WipeCodeSecond": 5,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -275,20 +317,22 @@ func (PinMatrixRequest_PinMatrixRequestType) EnumDescriptor() ([]byte, []int) {
|
|||
// Response: Success of the previous request
|
||||
// @end
|
||||
type Success struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Message *string `protobuf:"bytes,1,opt,name=message,def=" json:"message,omitempty"` // human readable description of action or request-specific payload
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Message *string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` // human readable description of action or request-specific payload
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
// Default values for Success fields.
|
||||
const (
|
||||
Default_Success_Message = string("")
|
||||
)
|
||||
|
||||
func (x *Success) Reset() {
|
||||
*x = Success{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Success) String() string {
|
||||
|
|
@ -299,7 +343,7 @@ func (*Success) ProtoMessage() {}
|
|||
|
||||
func (x *Success) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -318,28 +362,25 @@ func (x *Success) GetMessage() string {
|
|||
if x != nil && x.Message != nil {
|
||||
return *x.Message
|
||||
}
|
||||
return ""
|
||||
return Default_Success_Message
|
||||
}
|
||||
|
||||
// *
|
||||
// Response: Failure of the previous request
|
||||
// @end
|
||||
type Failure struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code *Failure_FailureType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.Failure_FailureType" json:"code,omitempty"` // computer-readable definition of the error state
|
||||
Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` // human-readable message of the error state
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Failure) Reset() {
|
||||
*x = Failure{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Failure) String() string {
|
||||
|
|
@ -350,7 +391,7 @@ func (*Failure) ProtoMessage() {}
|
|||
|
||||
func (x *Failure) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -384,21 +425,19 @@ func (x *Failure) GetMessage() string {
|
|||
// @auxstart
|
||||
// @next ButtonAck
|
||||
type ButtonRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"` // enum identifier of the screen (deprecated)
|
||||
Pages *uint32 `protobuf:"varint,2,opt,name=pages" json:"pages,omitempty"` // if the screen is paginated, number of pages
|
||||
Name *string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` // name of the screen
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Code *ButtonRequest_ButtonRequestType `protobuf:"varint,1,opt,name=code,enum=hw.trezor.messages.common.ButtonRequest_ButtonRequestType" json:"code,omitempty"`
|
||||
Data *string `protobuf:"bytes,2,opt,name=data" json:"data,omitempty"`
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ButtonRequest) Reset() {
|
||||
*x = ButtonRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ButtonRequest) String() string {
|
||||
|
|
@ -409,7 +448,7 @@ func (*ButtonRequest) ProtoMessage() {}
|
|||
|
||||
func (x *ButtonRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -431,9 +470,16 @@ func (x *ButtonRequest) GetCode() ButtonRequest_ButtonRequestType {
|
|||
return ButtonRequest_ButtonRequest_Other
|
||||
}
|
||||
|
||||
func (x *ButtonRequest) GetData() string {
|
||||
if x != nil && x.Data != nil {
|
||||
return *x.Data
|
||||
func (x *ButtonRequest) GetPages() uint32 {
|
||||
if x != nil && x.Pages != nil {
|
||||
return *x.Pages
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *ButtonRequest) GetName() string {
|
||||
if x != nil && x.Name != nil {
|
||||
return *x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
@ -442,18 +488,16 @@ func (x *ButtonRequest) GetData() string {
|
|||
// Request: Computer agrees to wait for HW button press
|
||||
// @auxend
|
||||
type ButtonAck struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *ButtonAck) Reset() {
|
||||
*x = ButtonAck{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ButtonAck) String() string {
|
||||
|
|
@ -464,7 +508,7 @@ func (*ButtonAck) ProtoMessage() {}
|
|||
|
||||
func (x *ButtonAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -484,20 +528,17 @@ func (*ButtonAck) Descriptor() ([]byte, []int) {
|
|||
// @auxstart
|
||||
// @next PinMatrixAck
|
||||
type PinMatrixRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Type *PinMatrixRequest_PinMatrixRequestType `protobuf:"varint,1,opt,name=type,enum=hw.trezor.messages.common.PinMatrixRequest_PinMatrixRequestType" json:"type,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PinMatrixRequest) Reset() {
|
||||
*x = PinMatrixRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PinMatrixRequest) String() string {
|
||||
|
|
@ -508,7 +549,7 @@ func (*PinMatrixRequest) ProtoMessage() {}
|
|||
|
||||
func (x *PinMatrixRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -534,20 +575,17 @@ func (x *PinMatrixRequest) GetType() PinMatrixRequest_PinMatrixRequestType {
|
|||
// Request: Computer responds with encoded PIN
|
||||
// @auxend
|
||||
type PinMatrixAck struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Pin *string `protobuf:"bytes,1,req,name=pin" json:"pin,omitempty"` // matrix encoded PIN entered by user
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PinMatrixAck) Reset() {
|
||||
*x = PinMatrixAck{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PinMatrixAck) String() string {
|
||||
|
|
@ -558,7 +596,7 @@ func (*PinMatrixAck) ProtoMessage() {}
|
|||
|
||||
func (x *PinMatrixAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -585,20 +623,18 @@ func (x *PinMatrixAck) GetPin() string {
|
|||
// @auxstart
|
||||
// @next PassphraseAck
|
||||
type PassphraseRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
XOnDevice *bool `protobuf:"varint,1,opt,name=_on_device,json=OnDevice" json:"_on_device,omitempty"` // <2.3.0
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
OnDevice *bool `protobuf:"varint,1,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` // passphrase is being entered on the device
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PassphraseRequest) Reset() {
|
||||
*x = PassphraseRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PassphraseRequest) String() string {
|
||||
|
|
@ -609,7 +645,7 @@ func (*PassphraseRequest) ProtoMessage() {}
|
|||
|
||||
func (x *PassphraseRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -624,32 +660,32 @@ func (*PassphraseRequest) Descriptor() ([]byte, []int) {
|
|||
return file_messages_common_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *PassphraseRequest) GetOnDevice() bool {
|
||||
if x != nil && x.OnDevice != nil {
|
||||
return *x.OnDevice
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
func (x *PassphraseRequest) GetXOnDevice() bool {
|
||||
if x != nil && x.XOnDevice != nil {
|
||||
return *x.XOnDevice
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// *
|
||||
// Request: Send passphrase back
|
||||
// @next PassphraseStateRequest
|
||||
// @auxend
|
||||
type PassphraseAck struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Passphrase *string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"`
|
||||
State []byte `protobuf:"bytes,2,opt,name=state" json:"state,omitempty"` // expected device state
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
XState []byte `protobuf:"bytes,2,opt,name=_state,json=State" json:"_state,omitempty"` // <2.3.0
|
||||
OnDevice *bool `protobuf:"varint,3,opt,name=on_device,json=onDevice" json:"on_device,omitempty"` // user wants to enter passphrase on the device
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PassphraseAck) Reset() {
|
||||
*x = PassphraseAck{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PassphraseAck) String() string {
|
||||
|
|
@ -660,7 +696,7 @@ func (*PassphraseAck) ProtoMessage() {}
|
|||
|
||||
func (x *PassphraseAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -682,42 +718,50 @@ func (x *PassphraseAck) GetPassphrase() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *PassphraseAck) GetState() []byte {
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
func (x *PassphraseAck) GetXState() []byte {
|
||||
if x != nil {
|
||||
return x.State
|
||||
return x.XState
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// *
|
||||
// Response: Device awaits passphrase state
|
||||
// @next PassphraseStateAck
|
||||
type PassphraseStateRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // actual device state
|
||||
func (x *PassphraseAck) GetOnDevice() bool {
|
||||
if x != nil && x.OnDevice != nil {
|
||||
return *x.OnDevice
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *PassphraseStateRequest) Reset() {
|
||||
*x = PassphraseStateRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
// *
|
||||
// Response: Device awaits passphrase state
|
||||
// Deprecated in 2.3.0
|
||||
// @next Deprecated_PassphraseStateAck
|
||||
//
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
type Deprecated_PassphraseStateRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
State []byte `protobuf:"bytes,1,opt,name=state" json:"state,omitempty"` // actual device state
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *Deprecated_PassphraseStateRequest) Reset() {
|
||||
*x = Deprecated_PassphraseStateRequest{}
|
||||
mi := &file_messages_common_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PassphraseStateRequest) String() string {
|
||||
func (x *Deprecated_PassphraseStateRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PassphraseStateRequest) ProtoMessage() {}
|
||||
func (*Deprecated_PassphraseStateRequest) ProtoMessage() {}
|
||||
|
||||
func (x *PassphraseStateRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *Deprecated_PassphraseStateRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -727,12 +771,12 @@ func (x *PassphraseStateRequest) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PassphraseStateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*PassphraseStateRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use Deprecated_PassphraseStateRequest.ProtoReflect.Descriptor instead.
|
||||
func (*Deprecated_PassphraseStateRequest) Descriptor() ([]byte, []int) {
|
||||
return file_messages_common_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *PassphraseStateRequest) GetState() []byte {
|
||||
func (x *Deprecated_PassphraseStateRequest) GetState() []byte {
|
||||
if x != nil {
|
||||
return x.State
|
||||
}
|
||||
|
|
@ -741,31 +785,32 @@ func (x *PassphraseStateRequest) GetState() []byte {
|
|||
|
||||
// *
|
||||
// Request: Send passphrase state back
|
||||
// Deprecated in 2.3.0
|
||||
// @auxend
|
||||
type PassphraseStateAck struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
//
|
||||
// Deprecated: Marked as deprecated in messages-common.proto.
|
||||
type Deprecated_PassphraseStateAck struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *PassphraseStateAck) Reset() {
|
||||
*x = PassphraseStateAck{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
func (x *Deprecated_PassphraseStateAck) Reset() {
|
||||
*x = Deprecated_PassphraseStateAck{}
|
||||
mi := &file_messages_common_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *PassphraseStateAck) String() string {
|
||||
func (x *Deprecated_PassphraseStateAck) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*PassphraseStateAck) ProtoMessage() {}
|
||||
func (*Deprecated_PassphraseStateAck) ProtoMessage() {}
|
||||
|
||||
func (x *PassphraseStateAck) ProtoReflect() protoreflect.Message {
|
||||
func (x *Deprecated_PassphraseStateAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -775,8 +820,8 @@ func (x *PassphraseStateAck) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use PassphraseStateAck.ProtoReflect.Descriptor instead.
|
||||
func (*PassphraseStateAck) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use Deprecated_PassphraseStateAck.ProtoReflect.Descriptor instead.
|
||||
func (*Deprecated_PassphraseStateAck) Descriptor() ([]byte, []int) {
|
||||
return file_messages_common_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
|
|
@ -785,25 +830,22 @@ func (*PassphraseStateAck) Descriptor() ([]byte, []int) {
|
|||
// Used for imports of private key into the device and exporting public key out of device
|
||||
// @embed
|
||||
type HDNodeType struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Depth *uint32 `protobuf:"varint,1,req,name=depth" json:"depth,omitempty"`
|
||||
Fingerprint *uint32 `protobuf:"varint,2,req,name=fingerprint" json:"fingerprint,omitempty"`
|
||||
ChildNum *uint32 `protobuf:"varint,3,req,name=child_num,json=childNum" json:"child_num,omitempty"`
|
||||
ChainCode []byte `protobuf:"bytes,4,req,name=chain_code,json=chainCode" json:"chain_code,omitempty"`
|
||||
PrivateKey []byte `protobuf:"bytes,5,opt,name=private_key,json=privateKey" json:"private_key,omitempty"`
|
||||
PublicKey []byte `protobuf:"bytes,6,opt,name=public_key,json=publicKey" json:"public_key,omitempty"`
|
||||
PublicKey []byte `protobuf:"bytes,6,req,name=public_key,json=publicKey" json:"public_key,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *HDNodeType) Reset() {
|
||||
*x = HDNodeType{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_messages_common_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *HDNodeType) String() string {
|
||||
|
|
@ -814,7 +856,7 @@ func (*HDNodeType) ProtoMessage() {}
|
|||
|
||||
func (x *HDNodeType) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_common_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
|
|
@ -873,137 +915,105 @@ func (x *HDNodeType) GetPublicKey() []byte {
|
|||
|
||||
var File_messages_common_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_messages_common_proto_rawDesc = []byte{
|
||||
0x0a, 0x15, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x6f,
|
||||
0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a,
|
||||
0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d,
|
||||
0x6f, 0x6e, 0x22, 0x23, 0x0a, 0x07, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x18, 0x0a,
|
||||
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
|
||||
0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xd5, 0x03, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c,
|
||||
0x75, 0x72, 0x65, 0x12, 0x42, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x0e, 0x32, 0x2e, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x46, 0x61,
|
||||
0x69, 0x6c, 0x75, 0x72, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70,
|
||||
0x65, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
|
||||
0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
|
||||
0x65, 0x22, 0xeb, 0x02, 0x0a, 0x0b, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x1d, 0x0a, 0x19, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x55, 0x6e, 0x65,
|
||||
0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x10, 0x01,
|
||||
0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x42, 0x75, 0x74, 0x74,
|
||||
0x6f, 0x6e, 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x02, 0x12, 0x15, 0x0a, 0x11,
|
||||
0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x44, 0x61, 0x74, 0x61, 0x45, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x41,
|
||||
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x64, 0x10, 0x04,
|
||||
0x12, 0x17, 0x0a, 0x13, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x45,
|
||||
0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x10, 0x05, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69,
|
||||
0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x65,
|
||||
0x64, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50,
|
||||
0x69, 0x6e, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x46,
|
||||
0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x49, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x53, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x46, 0x61, 0x69,
|
||||
0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x45, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x10, 0x09, 0x12, 0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e,
|
||||
0x6f, 0x74, 0x45, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x46, 0x75, 0x6e, 0x64, 0x73, 0x10, 0x0a, 0x12,
|
||||
0x1a, 0x0a, 0x16, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x4e, 0x6f, 0x74, 0x49, 0x6e,
|
||||
0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x10, 0x0b, 0x12, 0x17, 0x0a, 0x13, 0x46,
|
||||
0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f, 0x50, 0x69, 0x6e, 0x4d, 0x69, 0x73, 0x6d, 0x61, 0x74,
|
||||
0x63, 0x68, 0x10, 0x0c, 0x12, 0x19, 0x0a, 0x15, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x5f,
|
||||
0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x10, 0x63, 0x22,
|
||||
0xe6, 0x04, 0x0a, 0x0d, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x4e, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32,
|
||||
0x3a, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72, 0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73,
|
||||
0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x42, 0x75, 0x74, 0x74,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x63, 0x6f, 0x64,
|
||||
0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf0, 0x03, 0x0a, 0x11, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x42,
|
||||
0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4f, 0x74, 0x68,
|
||||
0x65, 0x72, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x46, 0x65, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x54, 0x68, 0x72,
|
||||
0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x10, 0x02, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
|
||||
0x6d, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74,
|
||||
0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x52, 0x65, 0x73, 0x65, 0x74,
|
||||
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x10, 0x04, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
|
||||
0x6d, 0x57, 0x6f, 0x72, 0x64, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, 0x42, 0x75, 0x74, 0x74, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x57, 0x69, 0x70, 0x65, 0x44, 0x65, 0x76,
|
||||
0x69, 0x63, 0x65, 0x10, 0x06, 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x43, 0x61,
|
||||
0x6c, 0x6c, 0x10, 0x07, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x53, 0x69, 0x67, 0x6e, 0x54, 0x78, 0x10, 0x08, 0x12, 0x1f,
|
||||
0x0a, 0x1b, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f,
|
||||
0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x10, 0x09, 0x12,
|
||||
0x19, 0x0a, 0x15, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x0a, 0x12, 0x1b, 0x0a, 0x17, 0x42, 0x75,
|
||||
0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x4b, 0x65, 0x79, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x75, 0x74, 0x74, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69,
|
||||
0x63, 0x57, 0x6f, 0x72, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0x0c, 0x12, 0x1f, 0x0a, 0x1b,
|
||||
0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x4d, 0x6e,
|
||||
0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x10, 0x0d, 0x12, 0x20, 0x0a,
|
||||
0x1c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x50,
|
||||
0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x0e, 0x12,
|
||||
0x27, 0x0a, 0x23, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x5f, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x44, 0x65, 0x72, 0x69, 0x76, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x50, 0x61, 0x74, 0x68, 0x10, 0x0f, 0x22, 0x0b, 0x0a, 0x09, 0x42, 0x75, 0x74, 0x74,
|
||||
0x6f, 0x6e, 0x41, 0x63, 0x6b, 0x22, 0xe9, 0x01, 0x0a, 0x10, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74,
|
||||
0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x54, 0x0a, 0x04, 0x74, 0x79,
|
||||
0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x40, 0x2e, 0x68, 0x77, 0x2e, 0x74, 0x72,
|
||||
0x65, 0x7a, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x22, 0x7f, 0x0a, 0x14, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x50, 0x69, 0x6e, 0x4d,
|
||||
0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65,
|
||||
0x5f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x10, 0x01, 0x12, 0x21, 0x0a, 0x1d, 0x50, 0x69,
|
||||
0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79,
|
||||
0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x46, 0x69, 0x72, 0x73, 0x74, 0x10, 0x02, 0x12, 0x22, 0x0a,
|
||||
0x1e, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x54, 0x79, 0x70, 0x65, 0x5f, 0x4e, 0x65, 0x77, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x10,
|
||||
0x03, 0x22, 0x20, 0x0a, 0x0c, 0x50, 0x69, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x41, 0x63,
|
||||
0x6b, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x03,
|
||||
0x70, 0x69, 0x6e, 0x22, 0x30, 0x0a, 0x11, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x6f, 0x6e, 0x5f, 0x64,
|
||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6f, 0x6e, 0x44,
|
||||
0x65, 0x76, 0x69, 0x63, 0x65, 0x22, 0x45, 0x0a, 0x0d, 0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72,
|
||||
0x61, 0x73, 0x65, 0x41, 0x63, 0x6b, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x61, 0x73, 0x73, 0x70, 0x68,
|
||||
0x72, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x73, 0x73,
|
||||
0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x2e, 0x0a, 0x16,
|
||||
0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x14, 0x0a, 0x12,
|
||||
0x50, 0x61, 0x73, 0x73, 0x70, 0x68, 0x72, 0x61, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x41,
|
||||
0x63, 0x6b, 0x22, 0xc0, 0x01, 0x0a, 0x0a, 0x48, 0x44, 0x4e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70,
|
||||
0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0d,
|
||||
0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x20, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65,
|
||||
0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x0b, 0x66, 0x69,
|
||||
0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x69,
|
||||
0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x03, 0x20, 0x02, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x68,
|
||||
0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f,
|
||||
0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x02, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65,
|
||||
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x76,
|
||||
0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
|
||||
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x67, 0x6f, 0x2d,
|
||||
0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
|
||||
0x73, 0x2f, 0x75, 0x73, 0x62, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x74, 0x72, 0x65, 0x7a,
|
||||
0x6f, 0x72,
|
||||
}
|
||||
const file_messages_common_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x15messages-common.proto\x12\x19hw.trezor.messages.common\x1a\roptions.proto\"%\n" +
|
||||
"\aSuccess\x12\x1a\n" +
|
||||
"\amessage\x18\x01 \x01(\t:\x00R\amessage\"\xfa\x04\n" +
|
||||
"\aFailure\x12B\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2..hw.trezor.messages.common.Failure.FailureTypeR\x04code\x12\x18\n" +
|
||||
"\amessage\x18\x02 \x01(\tR\amessage\"\x90\x04\n" +
|
||||
"\vFailureType\x12\x1d\n" +
|
||||
"\x19Failure_UnexpectedMessage\x10\x01\x12\x1a\n" +
|
||||
"\x16Failure_ButtonExpected\x10\x02\x12\x15\n" +
|
||||
"\x11Failure_DataError\x10\x03\x12\x1b\n" +
|
||||
"\x17Failure_ActionCancelled\x10\x04\x12\x17\n" +
|
||||
"\x13Failure_PinExpected\x10\x05\x12\x18\n" +
|
||||
"\x14Failure_PinCancelled\x10\x06\x12\x16\n" +
|
||||
"\x12Failure_PinInvalid\x10\a\x12\x1c\n" +
|
||||
"\x18Failure_InvalidSignature\x10\b\x12\x18\n" +
|
||||
"\x14Failure_ProcessError\x10\t\x12\x1a\n" +
|
||||
"\x16Failure_NotEnoughFunds\x10\n" +
|
||||
"\x12\x1a\n" +
|
||||
"\x16Failure_NotInitialized\x10\v\x12\x17\n" +
|
||||
"\x13Failure_PinMismatch\x10\f\x12\x1c\n" +
|
||||
"\x18Failure_WipeCodeMismatch\x10\r\x12\x1a\n" +
|
||||
"\x16Failure_InvalidSession\x10\x0e\x12\x10\n" +
|
||||
"\fFailure_Busy\x10\x0f\x12!\n" +
|
||||
"\x1dFailure_ThpUnallocatedSession\x10\x10\x12\x1b\n" +
|
||||
"\x17Failure_InvalidProtocol\x10\x11\x12\x17\n" +
|
||||
"\x13Failure_BufferError\x10\x12\x12\x19\n" +
|
||||
"\x15Failure_FirmwareError\x10c\"\xab\x06\n" +
|
||||
"\rButtonRequest\x12N\n" +
|
||||
"\x04code\x18\x01 \x01(\x0e2:.hw.trezor.messages.common.ButtonRequest.ButtonRequestTypeR\x04code\x12\x14\n" +
|
||||
"\x05pages\x18\x02 \x01(\rR\x05pages\x12\x12\n" +
|
||||
"\x04name\x18\x04 \x01(\tR\x04name\"\x99\x05\n" +
|
||||
"\x11ButtonRequestType\x12\x17\n" +
|
||||
"\x13ButtonRequest_Other\x10\x01\x12\"\n" +
|
||||
"\x1eButtonRequest_FeeOverThreshold\x10\x02\x12\x1f\n" +
|
||||
"\x1bButtonRequest_ConfirmOutput\x10\x03\x12\x1d\n" +
|
||||
"\x19ButtonRequest_ResetDevice\x10\x04\x12\x1d\n" +
|
||||
"\x19ButtonRequest_ConfirmWord\x10\x05\x12\x1c\n" +
|
||||
"\x18ButtonRequest_WipeDevice\x10\x06\x12\x1d\n" +
|
||||
"\x19ButtonRequest_ProtectCall\x10\a\x12\x18\n" +
|
||||
"\x14ButtonRequest_SignTx\x10\b\x12\x1f\n" +
|
||||
"\x1bButtonRequest_FirmwareCheck\x10\t\x12\x19\n" +
|
||||
"\x15ButtonRequest_Address\x10\n" +
|
||||
"\x12\x1b\n" +
|
||||
"\x17ButtonRequest_PublicKey\x10\v\x12#\n" +
|
||||
"\x1fButtonRequest_MnemonicWordCount\x10\f\x12\x1f\n" +
|
||||
"\x1bButtonRequest_MnemonicInput\x10\r\x120\n" +
|
||||
"(_Deprecated_ButtonRequest_PassphraseType\x10\x0e\x1a\x02\b\x01\x12'\n" +
|
||||
"#ButtonRequest_UnknownDerivationPath\x10\x0f\x12\"\n" +
|
||||
"\x1eButtonRequest_RecoveryHomepage\x10\x10\x12\x19\n" +
|
||||
"\x15ButtonRequest_Success\x10\x11\x12\x19\n" +
|
||||
"\x15ButtonRequest_Warning\x10\x12\x12!\n" +
|
||||
"\x1dButtonRequest_PassphraseEntry\x10\x13\x12\x1a\n" +
|
||||
"\x16ButtonRequest_PinEntry\x10\x14J\x04\b\x03\x10\x04\"\v\n" +
|
||||
"\tButtonAck\"\xbb\x02\n" +
|
||||
"\x10PinMatrixRequest\x12T\n" +
|
||||
"\x04type\x18\x01 \x01(\x0e2@.hw.trezor.messages.common.PinMatrixRequest.PinMatrixRequestTypeR\x04type\"\xd0\x01\n" +
|
||||
"\x14PinMatrixRequestType\x12 \n" +
|
||||
"\x1cPinMatrixRequestType_Current\x10\x01\x12!\n" +
|
||||
"\x1dPinMatrixRequestType_NewFirst\x10\x02\x12\"\n" +
|
||||
"\x1ePinMatrixRequestType_NewSecond\x10\x03\x12&\n" +
|
||||
"\"PinMatrixRequestType_WipeCodeFirst\x10\x04\x12'\n" +
|
||||
"#PinMatrixRequestType_WipeCodeSecond\x10\x05\" \n" +
|
||||
"\fPinMatrixAck\x12\x10\n" +
|
||||
"\x03pin\x18\x01 \x02(\tR\x03pin\"5\n" +
|
||||
"\x11PassphraseRequest\x12 \n" +
|
||||
"\n" +
|
||||
"_on_device\x18\x01 \x01(\bB\x02\x18\x01R\bOnDevice\"g\n" +
|
||||
"\rPassphraseAck\x12\x1e\n" +
|
||||
"\n" +
|
||||
"passphrase\x18\x01 \x01(\tR\n" +
|
||||
"passphrase\x12\x19\n" +
|
||||
"\x06_state\x18\x02 \x01(\fB\x02\x18\x01R\x05State\x12\x1b\n" +
|
||||
"\ton_device\x18\x03 \x01(\bR\bonDevice\"=\n" +
|
||||
"!Deprecated_PassphraseStateRequest\x12\x14\n" +
|
||||
"\x05state\x18\x01 \x01(\fR\x05state:\x02\x18\x01\"#\n" +
|
||||
"\x1dDeprecated_PassphraseStateAck:\x02\x18\x01\"\xc0\x01\n" +
|
||||
"\n" +
|
||||
"HDNodeType\x12\x14\n" +
|
||||
"\x05depth\x18\x01 \x02(\rR\x05depth\x12 \n" +
|
||||
"\vfingerprint\x18\x02 \x02(\rR\vfingerprint\x12\x1b\n" +
|
||||
"\tchild_num\x18\x03 \x02(\rR\bchildNum\x12\x1d\n" +
|
||||
"\n" +
|
||||
"chain_code\x18\x04 \x02(\fR\tchainCode\x12\x1f\n" +
|
||||
"\vprivate_key\x18\x05 \x01(\fR\n" +
|
||||
"privateKey\x12\x1d\n" +
|
||||
"\n" +
|
||||
"public_key\x18\x06 \x02(\fR\tpublicKeyBy\x80\xa6\x1d\x01\n" +
|
||||
"#com.satoshilabs.trezor.lib.protobufB\x13TrezorMessageCommonZ9github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
||||
|
||||
var (
|
||||
file_messages_common_proto_rawDescOnce sync.Once
|
||||
file_messages_common_proto_rawDescData = file_messages_common_proto_rawDesc
|
||||
file_messages_common_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_messages_common_proto_rawDescGZIP() []byte {
|
||||
file_messages_common_proto_rawDescOnce.Do(func() {
|
||||
file_messages_common_proto_rawDescData = protoimpl.X.CompressGZIP(file_messages_common_proto_rawDescData)
|
||||
file_messages_common_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_messages_common_proto_rawDesc), len(file_messages_common_proto_rawDesc)))
|
||||
})
|
||||
return file_messages_common_proto_rawDescData
|
||||
}
|
||||
|
|
@ -1022,8 +1032,8 @@ var file_messages_common_proto_goTypes = []any{
|
|||
(*PinMatrixAck)(nil), // 8: hw.trezor.messages.common.PinMatrixAck
|
||||
(*PassphraseRequest)(nil), // 9: hw.trezor.messages.common.PassphraseRequest
|
||||
(*PassphraseAck)(nil), // 10: hw.trezor.messages.common.PassphraseAck
|
||||
(*PassphraseStateRequest)(nil), // 11: hw.trezor.messages.common.PassphraseStateRequest
|
||||
(*PassphraseStateAck)(nil), // 12: hw.trezor.messages.common.PassphraseStateAck
|
||||
(*Deprecated_PassphraseStateRequest)(nil), // 11: hw.trezor.messages.common.Deprecated_PassphraseStateRequest
|
||||
(*Deprecated_PassphraseStateAck)(nil), // 12: hw.trezor.messages.common.Deprecated_PassphraseStateAck
|
||||
(*HDNodeType)(nil), // 13: hw.trezor.messages.common.HDNodeType
|
||||
}
|
||||
var file_messages_common_proto_depIdxs = []int32{
|
||||
|
|
@ -1042,145 +1052,12 @@ func file_messages_common_proto_init() {
|
|||
if File_messages_common_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_messages_common_proto_msgTypes[0].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Success); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[1].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*Failure); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[2].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*ButtonRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[3].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*ButtonAck); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[4].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PinMatrixRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[5].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PinMatrixAck); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[6].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PassphraseRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[7].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PassphraseAck); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[8].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PassphraseStateRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[9].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*PassphraseStateAck); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_messages_common_proto_msgTypes[10].Exporter = func(v any, i int) any {
|
||||
switch v := v.(*HDNodeType); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
file_options_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_messages_common_proto_rawDesc,
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_common_proto_rawDesc), len(file_messages_common_proto_rawDesc)),
|
||||
NumEnums: 3,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
|
|
@ -1192,7 +1069,6 @@ func file_messages_common_proto_init() {
|
|||
MessageInfos: file_messages_common_proto_msgTypes,
|
||||
}.Build()
|
||||
File_messages_common_proto = out.File
|
||||
file_messages_common_proto_rawDesc = nil
|
||||
file_messages_common_proto_goTypes = nil
|
||||
file_messages_common_proto_depIdxs = nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,26 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-common.proto
|
||||
// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9.
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages.common;
|
||||
|
||||
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||
|
||||
// Sugar for easier handling in Java
|
||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||
option java_outer_classname = "TrezorMessageCommon";
|
||||
|
||||
import "options.proto";
|
||||
|
||||
option (include_in_bitcoin_only) = true;
|
||||
|
||||
/**
|
||||
* Response: Success of the previous request
|
||||
* @end
|
||||
*/
|
||||
message Success {
|
||||
optional string message = 1; // human readable description of action or request-specific payload
|
||||
optional string message = 1 [default=""]; // human readable description of action or request-specific payload
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -35,6 +43,12 @@ message Failure {
|
|||
Failure_NotEnoughFunds = 10;
|
||||
Failure_NotInitialized = 11;
|
||||
Failure_PinMismatch = 12;
|
||||
Failure_WipeCodeMismatch = 13;
|
||||
Failure_InvalidSession = 14;
|
||||
Failure_Busy = 15;
|
||||
Failure_ThpUnallocatedSession = 16;
|
||||
Failure_InvalidProtocol = 17;
|
||||
Failure_BufferError = 18;
|
||||
Failure_FirmwareError = 99;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,8 +59,14 @@ message Failure {
|
|||
* @next ButtonAck
|
||||
*/
|
||||
message ButtonRequest {
|
||||
optional ButtonRequestType code = 1;
|
||||
optional string data = 2;
|
||||
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
|
||||
*/
|
||||
|
|
@ -64,8 +84,13 @@ message ButtonRequest {
|
|||
ButtonRequest_PublicKey = 11;
|
||||
ButtonRequest_MnemonicWordCount = 12;
|
||||
ButtonRequest_MnemonicInput = 13;
|
||||
ButtonRequest_PassphraseType = 14;
|
||||
_Deprecated_ButtonRequest_PassphraseType = 14 [deprecated=true];
|
||||
ButtonRequest_UnknownDerivationPath = 15;
|
||||
ButtonRequest_RecoveryHomepage = 16;
|
||||
ButtonRequest_Success = 17;
|
||||
ButtonRequest_Warning = 18;
|
||||
ButtonRequest_PassphraseEntry = 19;
|
||||
ButtonRequest_PinEntry = 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +115,8 @@ message PinMatrixRequest {
|
|||
PinMatrixRequestType_Current = 1;
|
||||
PinMatrixRequestType_NewFirst = 2;
|
||||
PinMatrixRequestType_NewSecond = 3;
|
||||
PinMatrixRequestType_WipeCodeFirst = 4;
|
||||
PinMatrixRequestType_WipeCodeSecond = 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,31 +134,36 @@ message PinMatrixAck {
|
|||
* @next PassphraseAck
|
||||
*/
|
||||
message PassphraseRequest {
|
||||
optional bool on_device = 1; // passphrase is being entered on the device
|
||||
optional bool _on_device = 1 [deprecated=true]; // <2.3.0
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Send passphrase back
|
||||
* @next PassphraseStateRequest
|
||||
* @auxend
|
||||
*/
|
||||
message PassphraseAck {
|
||||
optional string passphrase = 1;
|
||||
optional bytes state = 2; // expected device state
|
||||
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
|
||||
* @next PassphraseStateAck
|
||||
* Deprecated in 2.3.0
|
||||
* @next Deprecated_PassphraseStateAck
|
||||
*/
|
||||
message PassphraseStateRequest {
|
||||
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 PassphraseStateAck {
|
||||
message Deprecated_PassphraseStateAck {
|
||||
option deprecated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -145,5 +177,5 @@ message HDNodeType {
|
|||
required uint32 child_num = 3;
|
||||
required bytes chain_code = 4;
|
||||
optional bytes private_key = 5;
|
||||
optional bytes public_key = 6;
|
||||
required bytes public_key = 6;
|
||||
}
|
||||
608
accounts/usbwallet/trezor/messages-ethereum-eip712.pb.go
Normal file
608
accounts/usbwallet/trezor/messages-ethereum-eip712.pb.go
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum-eip712.proto
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v4.25.3
|
||||
// source: messages-ethereum-eip712.proto
|
||||
|
||||
package trezor
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type EthereumTypedDataStructAck_EthereumDataType int32
|
||||
|
||||
const (
|
||||
EthereumTypedDataStructAck_UINT EthereumTypedDataStructAck_EthereumDataType = 1
|
||||
EthereumTypedDataStructAck_INT EthereumTypedDataStructAck_EthereumDataType = 2
|
||||
EthereumTypedDataStructAck_BYTES EthereumTypedDataStructAck_EthereumDataType = 3
|
||||
EthereumTypedDataStructAck_STRING EthereumTypedDataStructAck_EthereumDataType = 4
|
||||
EthereumTypedDataStructAck_BOOL EthereumTypedDataStructAck_EthereumDataType = 5
|
||||
EthereumTypedDataStructAck_ADDRESS EthereumTypedDataStructAck_EthereumDataType = 6
|
||||
EthereumTypedDataStructAck_ARRAY EthereumTypedDataStructAck_EthereumDataType = 7
|
||||
EthereumTypedDataStructAck_STRUCT EthereumTypedDataStructAck_EthereumDataType = 8
|
||||
)
|
||||
|
||||
// Enum value maps for EthereumTypedDataStructAck_EthereumDataType.
|
||||
var (
|
||||
EthereumTypedDataStructAck_EthereumDataType_name = map[int32]string{
|
||||
1: "UINT",
|
||||
2: "INT",
|
||||
3: "BYTES",
|
||||
4: "STRING",
|
||||
5: "BOOL",
|
||||
6: "ADDRESS",
|
||||
7: "ARRAY",
|
||||
8: "STRUCT",
|
||||
}
|
||||
EthereumTypedDataStructAck_EthereumDataType_value = map[string]int32{
|
||||
"UINT": 1,
|
||||
"INT": 2,
|
||||
"BYTES": 3,
|
||||
"STRING": 4,
|
||||
"BOOL": 5,
|
||||
"ADDRESS": 6,
|
||||
"ARRAY": 7,
|
||||
"STRUCT": 8,
|
||||
}
|
||||
)
|
||||
|
||||
func (x EthereumTypedDataStructAck_EthereumDataType) Enum() *EthereumTypedDataStructAck_EthereumDataType {
|
||||
p := new(EthereumTypedDataStructAck_EthereumDataType)
|
||||
*p = x
|
||||
return p
|
||||
}
|
||||
|
||||
func (x EthereumTypedDataStructAck_EthereumDataType) String() string {
|
||||
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
|
||||
}
|
||||
|
||||
func (EthereumTypedDataStructAck_EthereumDataType) Descriptor() protoreflect.EnumDescriptor {
|
||||
return file_messages_ethereum_eip712_proto_enumTypes[0].Descriptor()
|
||||
}
|
||||
|
||||
func (EthereumTypedDataStructAck_EthereumDataType) Type() protoreflect.EnumType {
|
||||
return &file_messages_ethereum_eip712_proto_enumTypes[0]
|
||||
}
|
||||
|
||||
func (x EthereumTypedDataStructAck_EthereumDataType) Number() protoreflect.EnumNumber {
|
||||
return protoreflect.EnumNumber(x)
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (x *EthereumTypedDataStructAck_EthereumDataType) UnmarshalJSON(b []byte) error {
|
||||
num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*x = EthereumTypedDataStructAck_EthereumDataType(num)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataStructAck_EthereumDataType.Descriptor instead.
|
||||
func (EthereumTypedDataStructAck_EthereumDataType) EnumDescriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{2, 0}
|
||||
}
|
||||
|
||||
// *
|
||||
// Request: Ask device to sign typed data
|
||||
// @start
|
||||
// @next EthereumTypedDataStructRequest
|
||||
// @next EthereumTypedDataValueRequest
|
||||
// @next EthereumTypedDataSignature
|
||||
// @next Failure
|
||||
type EthereumSignTypedData struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
AddressN []uint32 `protobuf:"varint,1,rep,name=address_n,json=addressN" json:"address_n,omitempty"` // BIP-32 path to derive the key from master node
|
||||
PrimaryType *string `protobuf:"bytes,2,req,name=primary_type,json=primaryType" json:"primary_type,omitempty"` // name of the root message struct
|
||||
MetamaskV4Compat *bool `protobuf:"varint,3,opt,name=metamask_v4_compat,json=metamaskV4Compat,def=1" json:"metamask_v4_compat,omitempty"` // use MetaMask v4 (see https://github.com/MetaMask/eth-sig-util/issues/106)
|
||||
Definitions *EthereumDefinitions `protobuf:"bytes,4,opt,name=definitions" json:"definitions,omitempty"` // network and/or token definitions
|
||||
ShowMessageHash []byte `protobuf:"bytes,5,opt,name=show_message_hash,json=showMessageHash" json:"show_message_hash,omitempty"` // hash of the typed data to be signed (if set, user will be asked to confirm before signing)
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
// Default values for EthereumSignTypedData fields.
|
||||
const (
|
||||
Default_EthereumSignTypedData_MetamaskV4Compat = bool(true)
|
||||
)
|
||||
|
||||
func (x *EthereumSignTypedData) Reset() {
|
||||
*x = EthereumSignTypedData{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumSignTypedData) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumSignTypedData) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumSignTypedData.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumSignTypedData) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) GetAddressN() []uint32 {
|
||||
if x != nil {
|
||||
return x.AddressN
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) GetPrimaryType() string {
|
||||
if x != nil && x.PrimaryType != nil {
|
||||
return *x.PrimaryType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) GetMetamaskV4Compat() bool {
|
||||
if x != nil && x.MetamaskV4Compat != nil {
|
||||
return *x.MetamaskV4Compat
|
||||
}
|
||||
return Default_EthereumSignTypedData_MetamaskV4Compat
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) GetDefinitions() *EthereumDefinitions {
|
||||
if x != nil {
|
||||
return x.Definitions
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EthereumSignTypedData) GetShowMessageHash() []byte {
|
||||
if x != nil {
|
||||
return x.ShowMessageHash
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// *
|
||||
// Response: Device asks for type information about a struct.
|
||||
// @next EthereumTypedDataStructAck
|
||||
type EthereumTypedDataStructRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"` // name of the requested struct
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructRequest) Reset() {
|
||||
*x = EthereumTypedDataStructRequest{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataStructRequest) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataStructRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataStructRequest.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataStructRequest) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructRequest) GetName() string {
|
||||
if x != nil && x.Name != nil {
|
||||
return *x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// *
|
||||
// Request: Type information about a struct.
|
||||
// @next EthereumTypedDataStructRequest
|
||||
type EthereumTypedDataStructAck struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Members []*EthereumTypedDataStructAck_EthereumStructMember `protobuf:"bytes,1,rep,name=members" json:"members,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck) Reset() {
|
||||
*x = EthereumTypedDataStructAck{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataStructAck) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataStructAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[2]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataStructAck.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataStructAck) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck) GetMembers() []*EthereumTypedDataStructAck_EthereumStructMember {
|
||||
if x != nil {
|
||||
return x.Members
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// *
|
||||
// Response: Device asks for data at the specific member path.
|
||||
// @next EthereumTypedDataValueAck
|
||||
type EthereumTypedDataValueRequest struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
MemberPath []uint32 `protobuf:"varint,1,rep,name=member_path,json=memberPath" json:"member_path,omitempty"` // member path requested by device
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueRequest) Reset() {
|
||||
*x = EthereumTypedDataValueRequest{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataValueRequest) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataValueRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[3]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataValueRequest.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataValueRequest) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueRequest) GetMemberPath() []uint32 {
|
||||
if x != nil {
|
||||
return x.MemberPath
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// *
|
||||
// Request: Single value of a specific atomic field.
|
||||
// @next EthereumTypedDataValueRequest
|
||||
type EthereumTypedDataValueAck struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Value []byte `protobuf:"bytes,1,req,name=value" json:"value,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueAck) Reset() {
|
||||
*x = EthereumTypedDataValueAck{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueAck) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataValueAck) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataValueAck) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[4]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataValueAck.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataValueAck) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataValueAck) GetValue() []byte {
|
||||
if x != nil {
|
||||
return x.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type EthereumTypedDataStructAck_EthereumStructMember struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Type *EthereumTypedDataStructAck_EthereumFieldType `protobuf:"bytes,1,req,name=type" json:"type,omitempty"`
|
||||
Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumStructMember) Reset() {
|
||||
*x = EthereumTypedDataStructAck_EthereumStructMember{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumStructMember) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataStructAck_EthereumStructMember) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumStructMember) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[5]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataStructAck_EthereumStructMember.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataStructAck_EthereumStructMember) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{2, 0}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumStructMember) GetType() *EthereumTypedDataStructAck_EthereumFieldType {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumStructMember) GetName() string {
|
||||
if x != nil && x.Name != nil {
|
||||
return *x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type EthereumTypedDataStructAck_EthereumFieldType struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
DataType *EthereumTypedDataStructAck_EthereumDataType `protobuf:"varint,1,req,name=data_type,json=dataType,enum=hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck_EthereumDataType" json:"data_type,omitempty"`
|
||||
Size *uint32 `protobuf:"varint,2,opt,name=size" json:"size,omitempty"` // for integer types: size in bytes (uint8 has size 1, uint256 has size 32)
|
||||
// for bytes types: size in bytes, or unset for dynamic
|
||||
// for arrays: size in elements, or unset for dynamic
|
||||
// for structs: number of members
|
||||
// for string, bool and address: unset
|
||||
EntryType *EthereumTypedDataStructAck_EthereumFieldType `protobuf:"bytes,3,opt,name=entry_type,json=entryType" json:"entry_type,omitempty"` // for array types, type of single entry
|
||||
StructName *string `protobuf:"bytes,4,opt,name=struct_name,json=structName" json:"struct_name,omitempty"` // for structs: its name
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) Reset() {
|
||||
*x = EthereumTypedDataStructAck_EthereumFieldType{}
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*EthereumTypedDataStructAck_EthereumFieldType) ProtoMessage() {}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_messages_ethereum_eip712_proto_msgTypes[6]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use EthereumTypedDataStructAck_EthereumFieldType.ProtoReflect.Descriptor instead.
|
||||
func (*EthereumTypedDataStructAck_EthereumFieldType) Descriptor() ([]byte, []int) {
|
||||
return file_messages_ethereum_eip712_proto_rawDescGZIP(), []int{2, 1}
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) GetDataType() EthereumTypedDataStructAck_EthereumDataType {
|
||||
if x != nil && x.DataType != nil {
|
||||
return *x.DataType
|
||||
}
|
||||
return EthereumTypedDataStructAck_UINT
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) GetSize() uint32 {
|
||||
if x != nil && x.Size != nil {
|
||||
return *x.Size
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) GetEntryType() *EthereumTypedDataStructAck_EthereumFieldType {
|
||||
if x != nil {
|
||||
return x.EntryType
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *EthereumTypedDataStructAck_EthereumFieldType) GetStructName() string {
|
||||
if x != nil && x.StructName != nil {
|
||||
return *x.StructName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_messages_ethereum_eip712_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_messages_ethereum_eip712_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x1emessages-ethereum-eip712.proto\x12\"hw.trezor.messages.ethereum_eip712\x1a\x17messages-ethereum.proto\"\x8b\x02\n" +
|
||||
"\x15EthereumSignTypedData\x12\x1b\n" +
|
||||
"\taddress_n\x18\x01 \x03(\rR\baddressN\x12!\n" +
|
||||
"\fprimary_type\x18\x02 \x02(\tR\vprimaryType\x122\n" +
|
||||
"\x12metamask_v4_compat\x18\x03 \x01(\b:\x04trueR\x10metamaskV4Compat\x12R\n" +
|
||||
"\vdefinitions\x18\x04 \x01(\v20.hw.trezor.messages.ethereum.EthereumDefinitionsR\vdefinitions\x12*\n" +
|
||||
"\x11show_message_hash\x18\x05 \x01(\fR\x0fshowMessageHash\"4\n" +
|
||||
"\x1eEthereumTypedDataStructRequest\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x02(\tR\x04name\"\xb4\x05\n" +
|
||||
"\x1aEthereumTypedDataStructAck\x12m\n" +
|
||||
"\amembers\x18\x01 \x03(\v2S.hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumStructMemberR\amembers\x1a\x90\x01\n" +
|
||||
"\x14EthereumStructMember\x12d\n" +
|
||||
"\x04type\x18\x01 \x02(\v2P.hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldTypeR\x04type\x12\x12\n" +
|
||||
"\x04name\x18\x02 \x02(\tR\x04name\x1a\xa7\x02\n" +
|
||||
"\x11EthereumFieldType\x12l\n" +
|
||||
"\tdata_type\x18\x01 \x02(\x0e2O.hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumDataTypeR\bdataType\x12\x12\n" +
|
||||
"\x04size\x18\x02 \x01(\rR\x04size\x12o\n" +
|
||||
"\n" +
|
||||
"entry_type\x18\x03 \x01(\v2P.hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldTypeR\tentryType\x12\x1f\n" +
|
||||
"\vstruct_name\x18\x04 \x01(\tR\n" +
|
||||
"structName\"j\n" +
|
||||
"\x10EthereumDataType\x12\b\n" +
|
||||
"\x04UINT\x10\x01\x12\a\n" +
|
||||
"\x03INT\x10\x02\x12\t\n" +
|
||||
"\x05BYTES\x10\x03\x12\n" +
|
||||
"\n" +
|
||||
"\x06STRING\x10\x04\x12\b\n" +
|
||||
"\x04BOOL\x10\x05\x12\v\n" +
|
||||
"\aADDRESS\x10\x06\x12\t\n" +
|
||||
"\x05ARRAY\x10\a\x12\n" +
|
||||
"\n" +
|
||||
"\x06STRUCT\x10\b\"@\n" +
|
||||
"\x1dEthereumTypedDataValueRequest\x12\x1f\n" +
|
||||
"\vmember_path\x18\x01 \x03(\rR\n" +
|
||||
"memberPath\"1\n" +
|
||||
"\x19EthereumTypedDataValueAck\x12\x14\n" +
|
||||
"\x05value\x18\x01 \x02(\fR\x05valueB}\n" +
|
||||
"#com.satoshilabs.trezor.lib.protobufB\x1bTrezorMessageEthereumEIP712Z9github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
||||
|
||||
var (
|
||||
file_messages_ethereum_eip712_proto_rawDescOnce sync.Once
|
||||
file_messages_ethereum_eip712_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_messages_ethereum_eip712_proto_rawDescGZIP() []byte {
|
||||
file_messages_ethereum_eip712_proto_rawDescOnce.Do(func() {
|
||||
file_messages_ethereum_eip712_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_messages_ethereum_eip712_proto_rawDesc), len(file_messages_ethereum_eip712_proto_rawDesc)))
|
||||
})
|
||||
return file_messages_ethereum_eip712_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_messages_ethereum_eip712_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_messages_ethereum_eip712_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
|
||||
var file_messages_ethereum_eip712_proto_goTypes = []any{
|
||||
(EthereumTypedDataStructAck_EthereumDataType)(0), // 0: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumDataType
|
||||
(*EthereumSignTypedData)(nil), // 1: hw.trezor.messages.ethereum_eip712.EthereumSignTypedData
|
||||
(*EthereumTypedDataStructRequest)(nil), // 2: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructRequest
|
||||
(*EthereumTypedDataStructAck)(nil), // 3: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck
|
||||
(*EthereumTypedDataValueRequest)(nil), // 4: hw.trezor.messages.ethereum_eip712.EthereumTypedDataValueRequest
|
||||
(*EthereumTypedDataValueAck)(nil), // 5: hw.trezor.messages.ethereum_eip712.EthereumTypedDataValueAck
|
||||
(*EthereumTypedDataStructAck_EthereumStructMember)(nil), // 6: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumStructMember
|
||||
(*EthereumTypedDataStructAck_EthereumFieldType)(nil), // 7: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldType
|
||||
(*EthereumDefinitions)(nil), // 8: hw.trezor.messages.ethereum.EthereumDefinitions
|
||||
}
|
||||
var file_messages_ethereum_eip712_proto_depIdxs = []int32{
|
||||
8, // 0: hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.definitions:type_name -> hw.trezor.messages.ethereum.EthereumDefinitions
|
||||
6, // 1: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.members:type_name -> hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumStructMember
|
||||
7, // 2: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumStructMember.type:type_name -> hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldType
|
||||
0, // 3: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldType.data_type:type_name -> hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumDataType
|
||||
7, // 4: hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldType.entry_type:type_name -> hw.trezor.messages.ethereum_eip712.EthereumTypedDataStructAck.EthereumFieldType
|
||||
5, // [5:5] is the sub-list for method output_type
|
||||
5, // [5:5] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
5, // [5:5] is the sub-list for extension extendee
|
||||
0, // [0:5] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_messages_ethereum_eip712_proto_init() }
|
||||
func file_messages_ethereum_eip712_proto_init() {
|
||||
if File_messages_ethereum_eip712_proto != nil {
|
||||
return
|
||||
}
|
||||
file_messages_ethereum_proto_init()
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_messages_ethereum_eip712_proto_rawDesc), len(file_messages_ethereum_eip712_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 7,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_messages_ethereum_eip712_proto_goTypes,
|
||||
DependencyIndexes: file_messages_ethereum_eip712_proto_depIdxs,
|
||||
EnumInfos: file_messages_ethereum_eip712_proto_enumTypes,
|
||||
MessageInfos: file_messages_ethereum_eip712_proto_msgTypes,
|
||||
}.Build()
|
||||
File_messages_ethereum_eip712_proto = out.File
|
||||
file_messages_ethereum_eip712_proto_goTypes = nil
|
||||
file_messages_ethereum_eip712_proto_depIdxs = nil
|
||||
}
|
||||
99
accounts/usbwallet/trezor/messages-ethereum-eip712.proto
Normal file
99
accounts/usbwallet/trezor/messages-ethereum-eip712.proto
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum-eip712.proto
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages.ethereum_eip712;
|
||||
|
||||
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||
|
||||
// Sugar for easier handling in Java
|
||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||
option java_outer_classname = "TrezorMessageEthereumEIP712";
|
||||
|
||||
import "messages-ethereum.proto";
|
||||
|
||||
|
||||
// Separated from messages-ethereum.proto as it is not implemented on T1 side
|
||||
// and defining all the messages and fields could be even impossible as recursive
|
||||
// messages are used here
|
||||
|
||||
|
||||
/**
|
||||
* Request: Ask device to sign typed data
|
||||
* @start
|
||||
* @next EthereumTypedDataStructRequest
|
||||
* @next EthereumTypedDataValueRequest
|
||||
* @next EthereumTypedDataSignature
|
||||
* @next Failure
|
||||
*/
|
||||
message EthereumSignTypedData {
|
||||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
|
||||
required string primary_type = 2; // name of the root message struct
|
||||
optional bool metamask_v4_compat = 3 [default=true]; // use MetaMask v4 (see https://github.com/MetaMask/eth-sig-util/issues/106)
|
||||
optional ethereum.EthereumDefinitions definitions = 4; // network and/or token definitions
|
||||
optional bytes show_message_hash = 5; // hash of the typed data to be signed (if set, user will be asked to confirm before signing)
|
||||
}
|
||||
|
||||
/**
|
||||
* Response: Device asks for type information about a struct.
|
||||
* @next EthereumTypedDataStructAck
|
||||
*/
|
||||
message EthereumTypedDataStructRequest {
|
||||
required string name = 1; // name of the requested struct
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Type information about a struct.
|
||||
* @next EthereumTypedDataStructRequest
|
||||
*/
|
||||
message EthereumTypedDataStructAck {
|
||||
repeated EthereumStructMember members = 1;
|
||||
|
||||
message EthereumStructMember {
|
||||
required EthereumFieldType type = 1;
|
||||
required string name = 2;
|
||||
}
|
||||
|
||||
message EthereumFieldType {
|
||||
required EthereumDataType data_type = 1;
|
||||
optional uint32 size = 2; // for integer types: size in bytes (uint8 has size 1, uint256 has size 32)
|
||||
// for bytes types: size in bytes, or unset for dynamic
|
||||
// for arrays: size in elements, or unset for dynamic
|
||||
// for structs: number of members
|
||||
// for string, bool and address: unset
|
||||
optional EthereumFieldType entry_type = 3; // for array types, type of single entry
|
||||
optional string struct_name = 4; // for structs: its name
|
||||
}
|
||||
|
||||
enum EthereumDataType {
|
||||
UINT = 1;
|
||||
INT = 2;
|
||||
BYTES = 3;
|
||||
STRING = 4;
|
||||
BOOL = 5;
|
||||
ADDRESS = 6;
|
||||
ARRAY = 7;
|
||||
STRUCT = 8;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Response: Device asks for data at the specific member path.
|
||||
* @next EthereumTypedDataValueAck
|
||||
*/
|
||||
message EthereumTypedDataValueRequest {
|
||||
repeated uint32 member_path = 1; // member path requested by device
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Single value of a specific atomic field.
|
||||
* @next EthereumTypedDataValueRequest
|
||||
*/
|
||||
message EthereumTypedDataValueAck {
|
||||
required bytes value = 1;
|
||||
// * atomic types: value of the member.
|
||||
// Length must match the `size` of the corresponding field type, unless the size is dynamic.
|
||||
// * array types: number of elements, encoded as uint16.
|
||||
// * struct types: undefined, Trezor will not query a struct field.
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-ethereum.proto
|
||||
// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9.
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages.ethereum;
|
||||
|
|
@ -13,7 +13,6 @@ option java_outer_classname = "TrezorMessageEthereum";
|
|||
|
||||
import "messages-common.proto";
|
||||
|
||||
|
||||
/**
|
||||
* Request: Ask device for public key corresponding to address_n path
|
||||
* @start
|
||||
|
|
@ -30,8 +29,8 @@ message EthereumGetPublicKey {
|
|||
* @end
|
||||
*/
|
||||
message EthereumPublicKey {
|
||||
optional hw.trezor.messages.common.HDNodeType node = 1; // BIP32 public node
|
||||
optional string xpub = 2; // serialized form of public node
|
||||
required hw.trezor.messages.common.HDNodeType node = 1; // BIP32 public node
|
||||
required string xpub = 2; // serialized form of public node
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -43,6 +42,8 @@ message EthereumPublicKey {
|
|||
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
|
||||
optional bytes encoded_network = 3; // encoded Ethereum network, see external-definitions.md for details
|
||||
optional bool chunkify = 4; // display the address in chunks of 4 characters
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -50,13 +51,14 @@ message EthereumGetAddress {
|
|||
* @end
|
||||
*/
|
||||
message EthereumAddress {
|
||||
optional bytes addressBin = 1; // Ethereum address as 20 bytes (legacy firmwares)
|
||||
optional string addressHex = 2; // Ethereum address as hex string (newer firmwares)
|
||||
optional bytes _old_address = 1 [deprecated=true]; // trezor <1.8.0, <2.1.0 - raw bytes of Ethereum address
|
||||
optional string address = 2; // Ethereum address as hex-encoded string
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* gas_price, gas_limit and chain_id must be provided and non-zero.
|
||||
* All other fields are optional and default to value `0` if missing.
|
||||
* Note: the first at most 1024 bytes of data MUST be transmitted as part of this message.
|
||||
* @start
|
||||
* @next EthereumTxRequest
|
||||
|
|
@ -64,16 +66,45 @@ message EthereumAddress {
|
|||
*/
|
||||
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 toBin = 5; // recipient address (20 bytes, legacy firmware)
|
||||
optional string toHex = 11; // recipient address (hex string, newer firmware)
|
||||
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
|
||||
optional uint32 tx_type = 10; // (only for Wanchain)
|
||||
optional bytes nonce = 2 [default='']; // <=256 bit unsigned big endian
|
||||
required bytes gas_price = 3; // <=256 bit unsigned big endian (in wei)
|
||||
required bytes gas_limit = 4; // <=256 bit unsigned big endian
|
||||
optional string to = 11 [default='']; // recipient address
|
||||
optional bytes value = 6 [default='']; // <=256 bit unsigned big endian (in wei)
|
||||
optional bytes data_initial_chunk = 7 [default='']; // The initial data chunk (<= 1024 bytes)
|
||||
optional uint32 data_length = 8 [default=0]; // Length of transaction payload
|
||||
required uint64 chain_id = 9; // Chain Id for EIP 155
|
||||
optional uint32 tx_type = 10; // Used for Wanchain
|
||||
optional EthereumDefinitions definitions = 12; // network and/or token definitions for tx
|
||||
optional bool chunkify = 13; // display the address in chunks of 4 characters
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Ask device to sign EIP1559 transaction
|
||||
* Note: the first at most 1024 bytes of data MUST be transmitted as part of this message.
|
||||
* @start
|
||||
* @next EthereumTxRequest
|
||||
* @next Failure
|
||||
*/
|
||||
message EthereumSignTxEIP1559 {
|
||||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
|
||||
required bytes nonce = 2; // <=256 bit unsigned big endian
|
||||
required bytes max_gas_fee = 3; // <=256 bit unsigned big endian (in wei)
|
||||
required bytes max_priority_fee = 4; // <=256 bit unsigned big endian (in wei)
|
||||
required bytes gas_limit = 5; // <=256 bit unsigned big endian
|
||||
optional string to = 6 [default='']; // recipient address
|
||||
required bytes value = 7; // <=256 bit unsigned big endian (in wei)
|
||||
optional bytes data_initial_chunk = 8 [default='']; // The initial data chunk (<= 1024 bytes)
|
||||
required uint32 data_length = 9; // Length of transaction payload
|
||||
required uint64 chain_id = 10; // Chain Id for EIP 155
|
||||
repeated EthereumAccessList access_list = 11; // Access List
|
||||
optional EthereumDefinitions definitions = 12; // network and/or token definitions for tx
|
||||
optional bool chunkify = 13; // display the address in chunks of 4 characters
|
||||
|
||||
message EthereumAccessList {
|
||||
required string address = 1;
|
||||
repeated bytes storage_keys = 2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -95,7 +126,7 @@ message EthereumTxRequest {
|
|||
* @next EthereumTxRequest
|
||||
*/
|
||||
message EthereumTxAck {
|
||||
optional bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes)
|
||||
required bytes data_chunk = 1; // Bytes from transaction payload (<= 1024 bytes)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,7 +137,9 @@ message EthereumTxAck {
|
|||
*/
|
||||
message EthereumSignMessage {
|
||||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
|
||||
optional bytes message = 2; // message to be signed
|
||||
required bytes message = 2; // message to be signed
|
||||
optional bytes encoded_network = 3; // encoded Ethereum network, see external-definitions.md for details
|
||||
optional bool chunkify = 4; // display the address in chunks of 4 characters
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -114,9 +147,8 @@ message EthereumSignMessage {
|
|||
* @end
|
||||
*/
|
||||
message EthereumMessageSignature {
|
||||
optional bytes addressBin = 1; // address used to sign the message (20 bytes, legacy firmware)
|
||||
optional bytes signature = 2; // signature of the message
|
||||
optional string addressHex = 3; // address used to sign the message (hex string, newer firmware)
|
||||
required bytes signature = 2; // signature of the message
|
||||
required string address = 3; // address used to sign the message
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -126,8 +158,39 @@ message EthereumMessageSignature {
|
|||
* @next Failure
|
||||
*/
|
||||
message EthereumVerifyMessage {
|
||||
optional bytes addressBin = 1; // address to verify (20 bytes, legacy firmware)
|
||||
optional bytes signature = 2; // signature to verify
|
||||
optional bytes message = 3; // message to verify
|
||||
optional string addressHex = 4; // address to verify (hex string, newer firmware)
|
||||
required bytes signature = 2; // signature to verify
|
||||
required bytes message = 3; // message to verify
|
||||
required string address = 4; // address to verify
|
||||
optional bool chunkify = 5; // display the address in chunks of 4 characters
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Ask device to sign hash of typed data
|
||||
* @start
|
||||
* @next EthereumTypedDataSignature
|
||||
* @next Failure
|
||||
*/
|
||||
message EthereumSignTypedHash {
|
||||
repeated uint32 address_n = 1; // BIP-32 path to derive the key from master node
|
||||
required bytes domain_separator_hash = 2; // Hash of domainSeparator of typed data to be signed
|
||||
optional bytes message_hash = 3; // Hash of the data of typed data to be signed (empty if domain-only data)
|
||||
optional bytes encoded_network = 4; // encoded Ethereum network, see external-definitions.md for details
|
||||
}
|
||||
|
||||
/**
|
||||
* Response: Signed typed data
|
||||
* @end
|
||||
*/
|
||||
message EthereumTypedDataSignature {
|
||||
required bytes signature = 1; // signature of the typed data
|
||||
required string address = 2; // address used to sign the typed data
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains an encoded network and/or token definition. See external-definitions.md for details.
|
||||
* @embed
|
||||
*/
|
||||
message EthereumDefinitions {
|
||||
optional bytes encoded_network = 1; // encoded ethereum network
|
||||
optional bytes encoded_token = 2; // encoded ethereum token
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages-management.proto
|
||||
// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9.
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages.management;
|
||||
|
|
@ -11,7 +11,49 @@ option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
|||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||
option java_outer_classname = "TrezorMessageManagement";
|
||||
|
||||
import "messages-common.proto";
|
||||
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
|
||||
|
|
@ -19,8 +61,9 @@ import "messages-common.proto";
|
|||
* @next Features
|
||||
*/
|
||||
message Initialize {
|
||||
optional bytes state = 1; // assumed device state, clear session if set and different
|
||||
optional bool skip_passphrase = 2; // this session should always assume empty passphrase
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -37,9 +80,9 @@ message GetFeatures {
|
|||
*/
|
||||
message Features {
|
||||
optional string vendor = 1; // name of the manufacturer, e.g. "trezor.io"
|
||||
optional uint32 major_version = 2; // major version of the firmware/bootloader, e.g. 1
|
||||
optional uint32 minor_version = 3; // minor version of the firmware/bootloader, e.g. 0
|
||||
optional uint32 patch_version = 4; // patch version of the firmware/bootloader, e.g. 0
|
||||
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?
|
||||
|
|
@ -50,51 +93,179 @@ message Features {
|
|||
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 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 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 string fw_vendor = 25; // reported firmware vendor if in bootloader mode
|
||||
optional bytes fw_vendor_keys = 26; // reported firmware vendor keys (their hash)
|
||||
// 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.
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: clear session (removes cached PIN, passphrase, etc).
|
||||
* Request: soft-lock the device. Following actions will require PIN. Passphrases remain cached.
|
||||
* @start
|
||||
* @next Success
|
||||
*/
|
||||
message ClearSession {
|
||||
message LockDevice {
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: change language and/or label of the device
|
||||
* 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;
|
||||
optional string language = 1 [deprecated=true];
|
||||
optional string label = 2;
|
||||
optional bool use_passphrase = 3;
|
||||
optional bytes homescreen = 4;
|
||||
optional PassphraseSourceType passphrase_source = 5;
|
||||
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
|
||||
/**
|
||||
* Structure representing passphrase source
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
enum PassphraseSourceType {
|
||||
ASK = 0;
|
||||
DEVICE = 1;
|
||||
HOST = 2;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -104,7 +275,7 @@ message ApplySettings {
|
|||
* @next Failure
|
||||
*/
|
||||
message ApplyFlags {
|
||||
optional uint32 flags = 1; // bitmask, can only set bits, not unset
|
||||
required uint32 flags = 1; // bitmask, can only set bits, not unset
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -117,16 +288,42 @@ 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; // message to send back in Success message
|
||||
optional string message = 1 [default=""]; // 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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -155,6 +352,43 @@ 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 certificates = 1; // A certificate chain starting with the device certificate, followed by intermediate CA certificates, the last of which is signed by Trezor company's root CA.
|
||||
required bytes signature = 2; // A DER-encoded signature of "\0x13AuthenticateDevice:" + length-prefixed challenge that should be verified using the device certificate.
|
||||
}
|
||||
|
||||
/**
|
||||
* Request: Request device to wipe all sensitive data and settings
|
||||
* @start
|
||||
|
|
@ -171,14 +405,15 @@ message WipeDevice {
|
|||
* @next Failure
|
||||
*/
|
||||
message LoadDevice {
|
||||
optional string mnemonic = 1; // seed encoded as BIP-39 mnemonic (12, 18 or 24 words)
|
||||
optional hw.trezor.messages.common.HDNodeType node = 2; // BIP-32 node
|
||||
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='english']; // device language
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -188,15 +423,17 @@ message LoadDevice {
|
|||
* @next Failure
|
||||
*/
|
||||
message ResetDevice {
|
||||
optional bool display_random = 1; // display entropy generated by the device before asking for additional entropy
|
||||
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 [default='english']; // device language
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -205,6 +442,12 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -212,14 +455,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 {
|
||||
optional 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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -229,38 +492,44 @@ message EntropyAck {
|
|||
* @next WordRequest
|
||||
*/
|
||||
message RecoveryDevice {
|
||||
optional uint32 word_count = 1; // number of words in BIP-39 mnemonic
|
||||
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 [default='english']; // device language
|
||||
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
|
||||
// 7 reserved for unused recovery method
|
||||
optional RecoveryDeviceType type = 8; // supported recovery type
|
||||
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 bool dry_run = 10; // perform dry-run recovery workflow (for safe mnemonic validation)
|
||||
optional RecoveryType type = 10 [default=NormalRecovery]; // the type of recovery to perform
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
* @next WordAck
|
||||
*/
|
||||
message WordRequest {
|
||||
optional WordRequestType type = 1;
|
||||
required WordRequestType type = 1;
|
||||
/**
|
||||
* Type of Recovery Word request
|
||||
*/
|
||||
|
|
@ -287,5 +556,137 @@ message WordAck {
|
|||
* @next Success
|
||||
*/
|
||||
message SetU2FCounter {
|
||||
optional uint32 u2f_counter = 1; // counter
|
||||
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;
|
||||
// Length of language blob to be installed before upgrading firmware
|
||||
optional uint32 language_data_length = 3 [default=0];
|
||||
|
||||
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 {
|
||||
option (experimental_message) = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Response: Contains a random nonce
|
||||
* @end
|
||||
*/
|
||||
message Nonce {
|
||||
option (experimental_message) = true;
|
||||
|
||||
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
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,12 +1,12 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/messages.proto
|
||||
// dated 28.05.2019, commit 893fd219d4a01bcffa0cd9cfa631856371ec5aa9.
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages;
|
||||
|
||||
/**
|
||||
* Messages for TREZOR communication
|
||||
* Messages for Trezor communication
|
||||
*/
|
||||
|
||||
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||
|
|
@ -15,100 +15,137 @@ option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
|||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||
option java_outer_classname = "TrezorMessage";
|
||||
|
||||
import "options.proto";
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
option (include_in_bitcoin_only) = true;
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping between TREZOR wire identifier (uint) and a protobuf message
|
||||
* Mapping between Trezor wire identifier (uint) and a protobuf message
|
||||
*/
|
||||
enum MessageType {
|
||||
option (has_bitcoin_only_values) = true;
|
||||
|
||||
// Management
|
||||
MessageType_Initialize = 0 [(wire_in) = true, (wire_tiny) = 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_GetEntropy = 9 [(wire_in) = true];
|
||||
MessageType_Entropy = 10 [(wire_out) = true];
|
||||
MessageType_LoadDevice = 13 [(wire_in) = true];
|
||||
MessageType_ResetDevice = 14 [(wire_in) = true];
|
||||
MessageType_Features = 17 [(wire_out) = true];
|
||||
MessageType_PinMatrixRequest = 18 [(wire_out) = true];
|
||||
MessageType_PinMatrixAck = 19 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_Cancel = 20 [(wire_in) = true, (wire_tiny) = 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, (wire_no_fsm) = true];
|
||||
MessageType_ApplyFlags = 28 [(wire_in) = true];
|
||||
MessageType_BackupDevice = 34 [(wire_in) = true];
|
||||
MessageType_EntropyRequest = 35 [(wire_out) = true];
|
||||
MessageType_EntropyAck = 36 [(wire_in) = true];
|
||||
MessageType_PassphraseRequest = 41 [(wire_out) = true];
|
||||
MessageType_PassphraseAck = 42 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_PassphraseStateRequest = 77 [(wire_out) = true];
|
||||
MessageType_PassphraseStateAck = 78 [(wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_RecoveryDevice = 45 [(wire_in) = true];
|
||||
MessageType_WordRequest = 46 [(wire_out) = true];
|
||||
MessageType_WordAck = 47 [(wire_in) = true];
|
||||
MessageType_GetFeatures = 55 [(wire_in) = true];
|
||||
MessageType_Initialize = 0 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true];
|
||||
MessageType_Ping = 1 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_Success = 2 [(bitcoin_only) = true, (wire_out) = true, (wire_debug_out) = true];
|
||||
MessageType_Failure = 3 [(bitcoin_only) = true, (wire_out) = true, (wire_debug_out) = true];
|
||||
MessageType_ChangePin = 4 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_WipeDevice = 5 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_GetEntropy = 9 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_Entropy = 10 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_LoadDevice = 13 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_ResetDevice = 14 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_SetBusy = 16 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_Features = 17 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_PinMatrixRequest = 18 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_PinMatrixAck = 19 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_Cancel = 20 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true];
|
||||
MessageType_LockDevice = 24 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_ApplySettings = 25 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_ButtonRequest = 26 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_ButtonAck = 27 [(bitcoin_only) = true, (wire_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_ApplyFlags = 28 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_GetNonce = 31 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_Nonce = 33 [(bitcoin_only) = true, (wire_out) = true];
|
||||
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_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];
|
||||
MessageType_WordRequest = 46 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_WordAck = 47 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_GetFeatures = 55 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_SdProtect = 79 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_ChangeWipeCode = 82 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_EndSession = 83 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_DoPreauthorized = 84 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_PreauthorizedRequest = 85 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_CancelAuthorization = 86 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_RebootToBootloader = 87 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_GetFirmwareHash = 88 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_FirmwareHash = 89 [(bitcoin_only) = true, (wire_out) = true];
|
||||
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_out) = true];
|
||||
MessageType_AuthenticityProof = 98 [(bitcoin_only) = true, (wire_in) = 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_SetU2FCounter = 63 [(wire_in) = true];
|
||||
MessageType_GetNextU2FCounter = 80 [(wire_in) = true];
|
||||
MessageType_NextU2FCounter = 81 [(wire_out) = true];
|
||||
|
||||
// Deprecated messages, kept for protobuf compatibility.
|
||||
MessageType_Deprecated_PassphraseStateRequest = 77 [deprecated = true];
|
||||
MessageType_Deprecated_PassphraseStateAck = 78 [deprecated = true];
|
||||
|
||||
// Bootloader
|
||||
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_SelfTest = 32 [(wire_in) = true, (wire_bootloader) = true];
|
||||
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_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 [(wire_in) = true];
|
||||
MessageType_PublicKey = 12 [(wire_out) = true];
|
||||
MessageType_SignTx = 15 [(wire_in) = true];
|
||||
MessageType_TxRequest = 21 [(wire_out) = true];
|
||||
MessageType_TxAck = 22 [(wire_in) = true];
|
||||
MessageType_GetAddress = 29 [(wire_in) = true];
|
||||
MessageType_Address = 30 [(wire_out) = true];
|
||||
MessageType_SignMessage = 38 [(wire_in) = true];
|
||||
MessageType_VerifyMessage = 39 [(wire_in) = true];
|
||||
MessageType_MessageSignature = 40 [(wire_out) = true];
|
||||
MessageType_GetPublicKey = 11 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_PublicKey = 12 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_SignTx = 15 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_TxRequest = 21 [(bitcoin_only) = true, (wire_out) = true];
|
||||
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];
|
||||
MessageType_GetOwnershipId = 43 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_OwnershipId = 44 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_GetOwnershipProof = 49 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_OwnershipProof = 50 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_AuthorizeCoinJoin = 51 [(bitcoin_only) = true, (wire_in) = true];
|
||||
|
||||
// Crypto
|
||||
MessageType_CipherKeyValue = 23 [(wire_in) = true];
|
||||
MessageType_CipheredKeyValue = 48 [(wire_out) = true];
|
||||
MessageType_SignIdentity = 53 [(wire_in) = true];
|
||||
MessageType_SignedIdentity = 54 [(wire_out) = true];
|
||||
MessageType_GetECDHSessionKey = 61 [(wire_in) = true];
|
||||
MessageType_ECDHSessionKey = 62 [(wire_out) = true];
|
||||
MessageType_CosiCommit = 71 [(wire_in) = true];
|
||||
MessageType_CosiCommitment = 72 [(wire_out) = true];
|
||||
MessageType_CosiSign = 73 [(wire_in) = true];
|
||||
MessageType_CosiSignature = 74 [(wire_out) = true];
|
||||
MessageType_CipherKeyValue = 23 [(bitcoin_only) = true, (wire_in) = true];
|
||||
MessageType_CipheredKeyValue = 48 [(bitcoin_only) = true, (wire_out) = true];
|
||||
MessageType_SignIdentity = 53 [(bitcoin_only) = true, (wire_in) = true];
|
||||
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];
|
||||
// dropped: CosiCommit, CosiCommitment, CosiSign, CosiSignature
|
||||
reserved 71 to 74;
|
||||
|
||||
// Debug
|
||||
MessageType_DebugLinkDecision = 100 [(wire_debug_in) = true, (wire_tiny) = true, (wire_no_fsm) = true];
|
||||
MessageType_DebugLinkGetState = 101 [(wire_debug_in) = true, (wire_tiny) = 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];
|
||||
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];
|
||||
MessageType_DebugLinkLog = 104 [(bitcoin_only) = true, (wire_debug_out) = true];
|
||||
MessageType_DebugLinkMemoryRead = 110 [(bitcoin_only) = true, (wire_debug_in) = true];
|
||||
MessageType_DebugLinkMemory = 111 [(bitcoin_only) = true, (wire_debug_out) = true];
|
||||
MessageType_DebugLinkMemoryWrite = 112 [(bitcoin_only) = true, (wire_debug_in) = true];
|
||||
MessageType_DebugLinkFlashErase = 113 [(bitcoin_only) = true, (wire_debug_in) = true];
|
||||
MessageType_DebugLinkLayout = 9001 [(bitcoin_only) = true, (wire_debug_out) = true];
|
||||
MessageType_DebugLinkReseedRandom = 9002 [(bitcoin_only) = true, (wire_debug_in) = true];
|
||||
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];
|
||||
|
||||
// Ethereum
|
||||
MessageType_EthereumGetPublicKey = 450 [(wire_in) = true];
|
||||
|
|
@ -116,11 +153,19 @@ enum MessageType {
|
|||
MessageType_EthereumGetAddress = 56 [(wire_in) = true];
|
||||
MessageType_EthereumAddress = 57 [(wire_out) = true];
|
||||
MessageType_EthereumSignTx = 58 [(wire_in) = true];
|
||||
MessageType_EthereumSignTxEIP1559 = 452 [(wire_in) = true];
|
||||
MessageType_EthereumTxRequest = 59 [(wire_out) = true];
|
||||
MessageType_EthereumTxAck = 60 [(wire_in) = true];
|
||||
MessageType_EthereumSignMessage = 64 [(wire_in) = true];
|
||||
MessageType_EthereumVerifyMessage = 65 [(wire_in) = true];
|
||||
MessageType_EthereumMessageSignature = 66 [(wire_out) = true];
|
||||
MessageType_EthereumSignTypedData = 464 [(wire_in) = true];
|
||||
MessageType_EthereumTypedDataStructRequest = 465 [(wire_out) = true];
|
||||
MessageType_EthereumTypedDataStructAck = 466 [(wire_in) = true];
|
||||
MessageType_EthereumTypedDataValueRequest = 467 [(wire_out) = true];
|
||||
MessageType_EthereumTypedDataValueAck = 468 [(wire_in) = true];
|
||||
MessageType_EthereumTypedDataSignature = 469 [(wire_out) = true];
|
||||
MessageType_EthereumSignTypedHash = 470 [(wire_in) = true];
|
||||
|
||||
// NEM
|
||||
MessageType_NEMGetAddress = 67 [(wire_in) = true];
|
||||
|
|
@ -131,6 +176,7 @@ enum MessageType {
|
|||
MessageType_NEMDecryptedMessage = 76 [(wire_out) = true];
|
||||
|
||||
// Lisk
|
||||
/*
|
||||
MessageType_LiskGetAddress = 114 [(wire_in) = true];
|
||||
MessageType_LiskAddress = 115 [(wire_out) = true];
|
||||
MessageType_LiskSignTx = 116 [(wire_in) = true];
|
||||
|
|
@ -140,6 +186,8 @@ enum MessageType {
|
|||
MessageType_LiskVerifyMessage = 120 [(wire_in) = true];
|
||||
MessageType_LiskGetPublicKey = 121 [(wire_in) = true];
|
||||
MessageType_LiskPublicKey = 122 [(wire_out) = true];
|
||||
*/
|
||||
reserved 114 to 122;
|
||||
|
||||
// Tezos
|
||||
MessageType_TezosGetAddress = 150 [(wire_in) = true];
|
||||
|
|
@ -156,48 +204,56 @@ enum MessageType {
|
|||
MessageType_StellarAddress = 208 [(wire_out) = true];
|
||||
MessageType_StellarCreateAccountOp = 210 [(wire_in) = true];
|
||||
MessageType_StellarPaymentOp = 211 [(wire_in) = true];
|
||||
MessageType_StellarPathPaymentOp = 212 [(wire_in) = true];
|
||||
MessageType_StellarManageOfferOp = 213 [(wire_in) = true];
|
||||
MessageType_StellarCreatePassiveOfferOp = 214 [(wire_in) = true];
|
||||
MessageType_StellarPathPaymentStrictReceiveOp = 212 [(wire_in) = true];
|
||||
MessageType_StellarManageSellOfferOp = 213 [(wire_in) = true];
|
||||
MessageType_StellarCreatePassiveSellOfferOp = 214 [(wire_in) = true];
|
||||
MessageType_StellarSetOptionsOp = 215 [(wire_in) = true];
|
||||
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];
|
||||
MessageType_StellarSignedTx = 230 [(wire_out) = true];
|
||||
|
||||
// TRON
|
||||
MessageType_TronGetAddress = 250 [(wire_in) = true];
|
||||
MessageType_TronAddress = 251 [(wire_out) = true];
|
||||
MessageType_TronSignTx = 252 [(wire_in) = true];
|
||||
MessageType_TronSignedTx = 253 [(wire_out) = true];
|
||||
|
||||
// Cardano
|
||||
// dropped Sign/VerifyMessage ids 300-302
|
||||
MessageType_CardanoSignTx = 303 [(wire_in) = true];
|
||||
MessageType_CardanoTxRequest = 304 [(wire_out) = true];
|
||||
// dropped TxRequest/TxAck ids 304 and 309 (shelley update)
|
||||
// dropped SignTx/SignedTx/SignedTxChunk/SignedTxChunkAck ids 303, 310, 311 and 312
|
||||
reserved 300 to 304, 309 to 312;
|
||||
MessageType_CardanoGetPublicKey = 305 [(wire_in) = true];
|
||||
MessageType_CardanoPublicKey = 306 [(wire_out) = true];
|
||||
MessageType_CardanoGetAddress = 307 [(wire_in) = true];
|
||||
MessageType_CardanoAddress = 308 [(wire_out) = true];
|
||||
MessageType_CardanoTxAck = 309 [(wire_in) = true];
|
||||
MessageType_CardanoSignedTx = 310 [(wire_out) = true];
|
||||
|
||||
// Ontology
|
||||
MessageType_OntologyGetAddress = 350 [(wire_in) = true];
|
||||
MessageType_OntologyAddress = 351 [(wire_out) = true];
|
||||
MessageType_OntologyGetPublicKey = 352 [(wire_in) = true];
|
||||
MessageType_OntologyPublicKey = 353 [(wire_out) = true];
|
||||
MessageType_OntologySignTransfer = 354 [(wire_in) = true];
|
||||
MessageType_OntologySignedTransfer = 355 [(wire_out) = true];
|
||||
MessageType_OntologySignWithdrawOng = 356 [(wire_in) = true];
|
||||
MessageType_OntologySignedWithdrawOng = 357 [(wire_out) = true];
|
||||
MessageType_OntologySignOntIdRegister = 358 [(wire_in) = true];
|
||||
MessageType_OntologySignedOntIdRegister = 359 [(wire_out) = true];
|
||||
MessageType_OntologySignOntIdAddAttributes = 360 [(wire_in) = true];
|
||||
MessageType_OntologySignedOntIdAddAttributes = 361 [(wire_out) = true];
|
||||
MessageType_CardanoTxItemAck = 313 [(wire_out) = true];
|
||||
MessageType_CardanoTxAuxiliaryDataSupplement = 314 [(wire_out) = true];
|
||||
MessageType_CardanoTxWitnessRequest = 315 [(wire_in) = true];
|
||||
MessageType_CardanoTxWitnessResponse = 316 [(wire_out) = true];
|
||||
MessageType_CardanoTxHostAck = 317 [(wire_in) = true];
|
||||
MessageType_CardanoTxBodyHash = 318 [(wire_out) = true];
|
||||
MessageType_CardanoSignTxFinished = 319 [(wire_out) = true];
|
||||
MessageType_CardanoSignTxInit = 320 [(wire_in) = true];
|
||||
MessageType_CardanoTxInput = 321 [(wire_in) = true];
|
||||
MessageType_CardanoTxOutput = 322 [(wire_in) = true];
|
||||
MessageType_CardanoAssetGroup = 323 [(wire_in) = true];
|
||||
MessageType_CardanoToken = 324 [(wire_in) = true];
|
||||
MessageType_CardanoTxCertificate = 325 [(wire_in) = true];
|
||||
MessageType_CardanoTxWithdrawal = 326 [(wire_in) = true];
|
||||
MessageType_CardanoTxAuxiliaryData = 327 [(wire_in) = true];
|
||||
MessageType_CardanoPoolOwner = 328 [(wire_in) = true];
|
||||
MessageType_CardanoPoolRelayParameters = 329 [(wire_in) = true];
|
||||
MessageType_CardanoGetNativeScriptHash = 330 [(wire_in) = true];
|
||||
MessageType_CardanoNativeScriptHash = 331 [(wire_out) = true];
|
||||
MessageType_CardanoTxMint = 332 [(wire_in) = true];
|
||||
MessageType_CardanoTxCollateralInput = 333 [(wire_in) = true];
|
||||
MessageType_CardanoTxRequiredSigner = 334 [(wire_in) = true];
|
||||
MessageType_CardanoTxInlineDatumChunk = 335 [(wire_in) = true];
|
||||
MessageType_CardanoTxReferenceScriptChunk = 336 [(wire_in) = true];
|
||||
MessageType_CardanoTxReferenceInput = 337 [(wire_in) = true];
|
||||
|
||||
// Ripple
|
||||
MessageType_RippleGetAddress = 400 [(wire_in) = true];
|
||||
|
|
@ -210,8 +266,6 @@ enum MessageType {
|
|||
MessageType_MoneroTransactionInitAck = 502 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionSetInputRequest = 503 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionSetInputAck = 504 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionInputsPermutationRequest = 505 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionInputsPermutationAck = 506 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionInputViniRequest = 507 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionInputViniAck = 508 [(wire_out) = true];
|
||||
MessageType_MoneroTransactionAllInputsSetRequest = 509 [(wire_out) = true];
|
||||
|
|
@ -253,15 +307,56 @@ 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];
|
||||
|
||||
// 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];
|
||||
|
||||
// THP
|
||||
MessageType_ThpCreateNewSession = 1000 [(bitcoin_only) = true, (wire_in) = true];
|
||||
reserved 1001 to 1005; // never appeared in a release, reserved for future use
|
||||
MessageType_ThpPairingRequest = 1006 [(bitcoin_only) = true];
|
||||
MessageType_ThpPairingRequestApproved = 1007 [(bitcoin_only) = true];
|
||||
MessageType_ThpSelectMethod = 1008 [(bitcoin_only) = true];
|
||||
MessageType_ThpPairingPreparationsFinished = 1009 [(bitcoin_only) = true];
|
||||
MessageType_ThpCredentialRequest = 1010 [(bitcoin_only) = true];
|
||||
MessageType_ThpCredentialResponse = 1011 [(bitcoin_only) = true];
|
||||
MessageType_ThpEndRequest = 1012 [(bitcoin_only) = true];
|
||||
MessageType_ThpEndResponse = 1013 [(bitcoin_only) = true];
|
||||
reserved 1014 to 1015;
|
||||
MessageType_ThpCodeEntryCommitment = 1016 [(bitcoin_only) = true];
|
||||
MessageType_ThpCodeEntryChallenge = 1017 [(bitcoin_only) = true];
|
||||
MessageType_ThpCodeEntryCpaceTrezor = 1018 [(bitcoin_only) = true];
|
||||
MessageType_ThpCodeEntryCpaceHostTag = 1019 [(bitcoin_only) = true];
|
||||
MessageType_ThpCodeEntrySecret = 1020 [(bitcoin_only) = true];
|
||||
reserved 1021 to 1023;
|
||||
MessageType_ThpQrCodeTag = 1024 [(bitcoin_only) = true];
|
||||
MessageType_ThpQrCodeSecret = 1025 [(bitcoin_only) = true];
|
||||
reserved 1026 to 1031;
|
||||
MessageType_ThpNfcTagHost = 1032 [(bitcoin_only) = true];
|
||||
MessageType_ThpNfcTagTrezor = 1033 [(bitcoin_only) = true];
|
||||
|
||||
// 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];
|
||||
|
||||
// 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];
|
||||
}
|
||||
264
accounts/usbwallet/trezor/options.pb.go
Normal file
264
accounts/usbwallet/trezor/options.pb.go
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/options.proto
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v4.25.3
|
||||
// source: options.proto
|
||||
|
||||
package trezor
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
descriptorpb "google.golang.org/protobuf/types/descriptorpb"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
var file_options_proto_extTypes = []protoimpl.ExtensionInfo{
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50002,
|
||||
Name: "hw.trezor.messages.wire_in",
|
||||
Tag: "varint,50002,opt,name=wire_in",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50003,
|
||||
Name: "hw.trezor.messages.wire_out",
|
||||
Tag: "varint,50003,opt,name=wire_out",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50004,
|
||||
Name: "hw.trezor.messages.wire_debug_in",
|
||||
Tag: "varint,50004,opt,name=wire_debug_in",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50005,
|
||||
Name: "hw.trezor.messages.wire_debug_out",
|
||||
Tag: "varint,50005,opt,name=wire_debug_out",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50006,
|
||||
Name: "hw.trezor.messages.wire_tiny",
|
||||
Tag: "varint,50006,opt,name=wire_tiny",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50007,
|
||||
Name: "hw.trezor.messages.wire_bootloader",
|
||||
Tag: "varint,50007,opt,name=wire_bootloader",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 50008,
|
||||
Name: "hw.trezor.messages.wire_no_fsm",
|
||||
Tag: "varint,50008,opt,name=wire_no_fsm",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumValueOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 60000,
|
||||
Name: "hw.trezor.messages.bitcoin_only",
|
||||
Tag: "varint,60000,opt,name=bitcoin_only",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.EnumOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 51001,
|
||||
Name: "hw.trezor.messages.has_bitcoin_only_values",
|
||||
Tag: "varint,51001,opt,name=has_bitcoin_only_values",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MessageOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 52001,
|
||||
Name: "hw.trezor.messages.experimental_message",
|
||||
Tag: "varint,52001,opt,name=experimental_message",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MessageOptions)(nil),
|
||||
ExtensionType: (*uint32)(nil),
|
||||
Field: 52002,
|
||||
Name: "hw.trezor.messages.wire_type",
|
||||
Tag: "varint,52002,opt,name=wire_type",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.MessageOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 52003,
|
||||
Name: "hw.trezor.messages.internal_only",
|
||||
Tag: "varint,52003,opt,name=internal_only",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.FieldOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 53001,
|
||||
Name: "hw.trezor.messages.experimental_field",
|
||||
Tag: "varint,53001,opt,name=experimental_field",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
{
|
||||
ExtendedType: (*descriptorpb.FileOptions)(nil),
|
||||
ExtensionType: (*bool)(nil),
|
||||
Field: 60000,
|
||||
Name: "hw.trezor.messages.include_in_bitcoin_only",
|
||||
Tag: "varint,60000,opt,name=include_in_bitcoin_only",
|
||||
Filename: "options.proto",
|
||||
},
|
||||
}
|
||||
|
||||
// Extension fields to descriptorpb.EnumValueOptions.
|
||||
var (
|
||||
// optional bool wire_in = 50002;
|
||||
E_WireIn = &file_options_proto_extTypes[0] // message can be transmitted via wire from PC to Trezor
|
||||
// optional bool wire_out = 50003;
|
||||
E_WireOut = &file_options_proto_extTypes[1] // message can be transmitted via wire from Trezor to PC
|
||||
// optional bool wire_debug_in = 50004;
|
||||
E_WireDebugIn = &file_options_proto_extTypes[2] // message can be transmitted via debug wire from PC to Trezor
|
||||
// optional bool wire_debug_out = 50005;
|
||||
E_WireDebugOut = &file_options_proto_extTypes[3] // message can be transmitted via debug wire from Trezor to PC
|
||||
// optional bool wire_tiny = 50006;
|
||||
E_WireTiny = &file_options_proto_extTypes[4] // message is handled by Trezor when the USB stack is in tiny mode
|
||||
// optional bool wire_bootloader = 50007;
|
||||
E_WireBootloader = &file_options_proto_extTypes[5] // message is only handled by Trezor Bootloader
|
||||
// optional bool wire_no_fsm = 50008;
|
||||
E_WireNoFsm = &file_options_proto_extTypes[6] // message is not handled by Trezor unless the USB stack is in tiny mode
|
||||
// optional bool bitcoin_only = 60000;
|
||||
E_BitcoinOnly = &file_options_proto_extTypes[7] // enum value is available on BITCOIN_ONLY build
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.EnumOptions.
|
||||
var (
|
||||
// optional bool has_bitcoin_only_values = 51001;
|
||||
E_HasBitcoinOnlyValues = &file_options_proto_extTypes[8] // indicate that some values should be excluded on BITCOIN_ONLY builds
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.MessageOptions.
|
||||
var (
|
||||
// optional bool experimental_message = 52001;
|
||||
E_ExperimentalMessage = &file_options_proto_extTypes[9] // 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;
|
||||
E_WireType = &file_options_proto_extTypes[10] // override wire type specified in the MessageType enum
|
||||
// optional bool internal_only = 52003;
|
||||
E_InternalOnly = &file_options_proto_extTypes[11] // indicate that a message is intended for internal use only and should not be transmitted via the wire
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.FieldOptions.
|
||||
var (
|
||||
// optional bool experimental_field = 53001;
|
||||
E_ExperimentalField = &file_options_proto_extTypes[12] // indicate that a field is intended for development and beta testing only
|
||||
)
|
||||
|
||||
// Extension fields to descriptorpb.FileOptions.
|
||||
var (
|
||||
// optional bool include_in_bitcoin_only = 60000;
|
||||
E_IncludeInBitcoinOnly = &file_options_proto_extTypes[13] // definitions are available on BITCOIN_ONLY build
|
||||
)
|
||||
|
||||
var File_options_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_options_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\roptions.proto\x12\x12hw.trezor.messages\x1a google/protobuf/descriptor.proto:<\n" +
|
||||
"\awire_in\x12!.google.protobuf.EnumValueOptions\x18҆\x03 \x01(\bR\x06wireIn:>\n" +
|
||||
"\bwire_out\x12!.google.protobuf.EnumValueOptions\x18ӆ\x03 \x01(\bR\awireOut:G\n" +
|
||||
"\rwire_debug_in\x12!.google.protobuf.EnumValueOptions\x18Ԇ\x03 \x01(\bR\vwireDebugIn:I\n" +
|
||||
"\x0ewire_debug_out\x12!.google.protobuf.EnumValueOptions\x18Ն\x03 \x01(\bR\fwireDebugOut:@\n" +
|
||||
"\twire_tiny\x12!.google.protobuf.EnumValueOptions\x18ֆ\x03 \x01(\bR\bwireTiny:L\n" +
|
||||
"\x0fwire_bootloader\x12!.google.protobuf.EnumValueOptions\x18׆\x03 \x01(\bR\x0ewireBootloader:C\n" +
|
||||
"\vwire_no_fsm\x12!.google.protobuf.EnumValueOptions\x18؆\x03 \x01(\bR\twireNoFsm:F\n" +
|
||||
"\fbitcoin_only\x12!.google.protobuf.EnumValueOptions\x18\xe0\xd4\x03 \x01(\bR\vbitcoinOnly:U\n" +
|
||||
"\x17has_bitcoin_only_values\x12\x1c.google.protobuf.EnumOptions\x18\xb9\x8e\x03 \x01(\bR\x14hasBitcoinOnlyValues:T\n" +
|
||||
"\x14experimental_message\x12\x1f.google.protobuf.MessageOptions\x18\xa1\x96\x03 \x01(\bR\x13experimentalMessage:>\n" +
|
||||
"\twire_type\x12\x1f.google.protobuf.MessageOptions\x18\xa2\x96\x03 \x01(\rR\bwireType:F\n" +
|
||||
"\rinternal_only\x12\x1f.google.protobuf.MessageOptions\x18\xa3\x96\x03 \x01(\bR\finternalOnly:N\n" +
|
||||
"\x12experimental_field\x12\x1d.google.protobuf.FieldOptions\x18\x89\x9e\x03 \x01(\bR\x11experimentalField:U\n" +
|
||||
"\x17include_in_bitcoin_only\x12\x1c.google.protobuf.FileOptions\x18\xe0\xd4\x03 \x01(\bR\x14includeInBitcoinOnlyBo\n" +
|
||||
"#com.satoshilabs.trezor.lib.protobufB\rTrezorOptionsZ9github.com/ethereum/go-ethereum/accounts/usbwallet/trezor"
|
||||
|
||||
var file_options_proto_goTypes = []any{
|
||||
(*descriptorpb.EnumValueOptions)(nil), // 0: google.protobuf.EnumValueOptions
|
||||
(*descriptorpb.EnumOptions)(nil), // 1: google.protobuf.EnumOptions
|
||||
(*descriptorpb.MessageOptions)(nil), // 2: google.protobuf.MessageOptions
|
||||
(*descriptorpb.FieldOptions)(nil), // 3: google.protobuf.FieldOptions
|
||||
(*descriptorpb.FileOptions)(nil), // 4: google.protobuf.FileOptions
|
||||
}
|
||||
var file_options_proto_depIdxs = []int32{
|
||||
0, // 0: hw.trezor.messages.wire_in:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 1: hw.trezor.messages.wire_out:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 2: hw.trezor.messages.wire_debug_in:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 3: hw.trezor.messages.wire_debug_out:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 4: hw.trezor.messages.wire_tiny:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 5: hw.trezor.messages.wire_bootloader:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 6: hw.trezor.messages.wire_no_fsm:extendee -> google.protobuf.EnumValueOptions
|
||||
0, // 7: hw.trezor.messages.bitcoin_only:extendee -> google.protobuf.EnumValueOptions
|
||||
1, // 8: hw.trezor.messages.has_bitcoin_only_values:extendee -> google.protobuf.EnumOptions
|
||||
2, // 9: hw.trezor.messages.experimental_message:extendee -> google.protobuf.MessageOptions
|
||||
2, // 10: hw.trezor.messages.wire_type:extendee -> google.protobuf.MessageOptions
|
||||
2, // 11: hw.trezor.messages.internal_only:extendee -> google.protobuf.MessageOptions
|
||||
3, // 12: hw.trezor.messages.experimental_field:extendee -> google.protobuf.FieldOptions
|
||||
4, // 13: hw.trezor.messages.include_in_bitcoin_only:extendee -> google.protobuf.FileOptions
|
||||
14, // [14:14] is the sub-list for method output_type
|
||||
14, // [14:14] is the sub-list for method input_type
|
||||
14, // [14:14] is the sub-list for extension type_name
|
||||
0, // [0:14] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_options_proto_init() }
|
||||
func file_options_proto_init() {
|
||||
if File_options_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_options_proto_rawDesc), len(file_options_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumExtensions: 14,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_options_proto_goTypes,
|
||||
DependencyIndexes: file_options_proto_depIdxs,
|
||||
ExtensionInfos: file_options_proto_extTypes,
|
||||
}.Build()
|
||||
File_options_proto = out.File
|
||||
file_options_proto_goTypes = nil
|
||||
file_options_proto_depIdxs = nil
|
||||
}
|
||||
72
accounts/usbwallet/trezor/options.proto
Normal file
72
accounts/usbwallet/trezor/options.proto
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
// This file originates from the SatoshiLabs Trezor `common` repository at:
|
||||
// https://github.com/trezor/trezor-common/blob/master/protob/options.proto
|
||||
// dated 30.06.2025, commit 421b45d4677f2499234692b0f54010bc45b3ae5f.
|
||||
|
||||
syntax = "proto2";
|
||||
package hw.trezor.messages;
|
||||
|
||||
option go_package = "github.com/ethereum/go-ethereum/accounts/usbwallet/trezor";
|
||||
|
||||
// Sugar for easier handling in Java
|
||||
option java_package = "com.satoshilabs.trezor.lib.protobuf";
|
||||
option java_outer_classname = "TrezorOptions";
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
// - Grab the latest Go plugin `go get -u google.golang.org/protobuf/cmd/protoc-gen-go`
|
||||
// - Vendor in the latest Go plugin `govendor fetch google.golang.org/protobuf/...`
|
||||
|
||||
//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. messages.proto messages-common.proto messages-management.proto messages-ethereum.proto
|
||||
//go:generate protoc -I/usr/local/include:. --go_out=paths=source_relative:. options.proto messages.proto messages-common.proto messages-management.proto messages-ethereum.proto messages-ethereum-eip712.proto
|
||||
|
||||
// Package trezor contains the wire protocol.
|
||||
package trezor
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package usbwallet
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
|
@ -31,7 +32,8 @@ import (
|
|||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/karalabe/hid"
|
||||
"github.com/ethereum/go-ethereum/signer/core/apitypes"
|
||||
"github.com/karalabe/usb"
|
||||
)
|
||||
|
||||
// Maximum time between wallet health checks to detect USB unplugs.
|
||||
|
|
@ -68,7 +70,17 @@ type driver interface {
|
|||
// or deny the transaction.
|
||||
SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error)
|
||||
|
||||
SignTypedMessage(path accounts.DerivationPath, messageHash []byte, domainHash []byte) ([]byte, error)
|
||||
// SignText sends a message to sign to the USB device and waits for the user to confirm
|
||||
// or deny the signature.
|
||||
SignText(path accounts.DerivationPath, text []byte) ([]byte, error)
|
||||
|
||||
// SignTypedHash sends a typed message to sign to the USB device and waits for the user to confirm
|
||||
// or deny the signature.
|
||||
SignTypedHash(path accounts.DerivationPath, messageHash []byte, domainHash []byte) ([]byte, error)
|
||||
|
||||
// SignedTypedData sends a typed data struct to sign to the USB device and waits for the user to confirm
|
||||
// or deny the signature.
|
||||
SignedTypedData(path accounts.DerivationPath, data apitypes.TypedData) ([]byte, error)
|
||||
}
|
||||
|
||||
// wallet represents the common functionality shared by all USB hardware
|
||||
|
|
@ -79,8 +91,8 @@ type wallet struct {
|
|||
driver driver // Hardware implementation of the low level device operations
|
||||
url *accounts.URL // Textual URL uniquely identifying this wallet
|
||||
|
||||
info hid.DeviceInfo // Known USB device infos about the wallet
|
||||
device hid.Device // USB device advertising itself as a hardware wallet
|
||||
info usb.DeviceInfo // Known USB device infos about the wallet
|
||||
device usb.Device // USB device advertising itself as a hardware wallet
|
||||
|
||||
accounts []accounts.Account // List of derive accounts pinned on the hardware wallet
|
||||
paths map[common.Address]accounts.DerivationPath // Known derivation paths for signing operations
|
||||
|
|
@ -530,45 +542,29 @@ func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error)
|
|||
|
||||
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||
func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||
// Unless we are doing 712 signing, simply dispatch to signHash
|
||||
if !(mimeType == accounts.MimetypeTypedData && len(data) == 66 && data[0] == 0x19 && data[1] == 0x01) {
|
||||
return w.signHash(account, crypto.Keccak256(data))
|
||||
}
|
||||
|
||||
// dispatch to 712 signing if the mimetype is TypedData and the format matches
|
||||
w.stateLock.RLock() // Comms have own mutex, this is for the state fields
|
||||
defer w.stateLock.RUnlock()
|
||||
|
||||
// If the wallet is closed, abort
|
||||
if w.device == nil {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
}
|
||||
// Make sure the requested account is contained within
|
||||
path, ok := w.paths[account.Address]
|
||||
if !ok {
|
||||
return nil, accounts.ErrUnknownAccount
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
<-w.commsLock
|
||||
defer func() { w.commsLock <- struct{}{} }()
|
||||
|
||||
// Ensure the device isn't screwed with while user confirmation is pending
|
||||
// TODO(karalabe): remove if hotplug lands on Windows
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend++
|
||||
w.hub.commsLock.Unlock()
|
||||
|
||||
defer func() {
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend--
|
||||
w.hub.commsLock.Unlock()
|
||||
}()
|
||||
// Sign the transaction
|
||||
signature, err := w.driver.SignTypedMessage(path, data[2:34], data[34:66])
|
||||
path, done, err := w.lockAndDerivePath(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return signature, nil
|
||||
defer done()
|
||||
|
||||
if mimeType == accounts.MimetypeTypedData {
|
||||
// If the data is exactly 66 bytes and starts with the 0x19 0x01 prefix, treat
|
||||
// it as the raw EIP-712 hash pair (domain and message) to sign.
|
||||
if len(data) == 66 && data[0] == 0x19 && data[1] == 0x01 {
|
||||
return w.driver.SignTypedHash(path, data[2:34], data[34:66])
|
||||
}
|
||||
// Otherwise attempt to parse the data as a JSON encoded EIP-712 struct
|
||||
// and sign it as such.
|
||||
var typedData apitypes.TypedData
|
||||
if err := json.Unmarshal(data, &typedData); err != nil {
|
||||
return nil, fmt.Errorf("invalid typed data: %w", err)
|
||||
}
|
||||
return w.driver.SignedTypedData(path, typedData)
|
||||
}
|
||||
|
||||
// If we're not doing 712 signing, simply dispatch to signHash
|
||||
return w.signHash(account, crypto.Keccak256(data))
|
||||
}
|
||||
|
||||
// SignDataWithPassphrase implements accounts.Wallet, attempting to sign the given
|
||||
|
|
@ -578,8 +574,21 @@ func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mi
|
|||
return w.SignData(account, mimeType, data)
|
||||
}
|
||||
|
||||
// SignText implements accounts.Wallet, signing the text as an EIP-712 personal
|
||||
// message.
|
||||
func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||
return w.signHash(account, accounts.TextHash(text))
|
||||
path, done, err := w.lockAndDerivePath(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer done()
|
||||
|
||||
// Sign the transaction
|
||||
signature, err := w.driver.SignText(path, text)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return signature, nil
|
||||
}
|
||||
|
||||
// SignTx implements accounts.Wallet. It sends the transaction over to the Ledger
|
||||
|
|
@ -590,33 +599,12 @@ func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error)
|
|||
// too old to sign EIP-155 transactions, but such is requested nonetheless, an error
|
||||
// will be returned opposed to silently signing in Homestead mode.
|
||||
func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
|
||||
w.stateLock.RLock() // Comms have own mutex, this is for the state fields
|
||||
defer w.stateLock.RUnlock()
|
||||
|
||||
// If the wallet is closed, abort
|
||||
if w.device == nil {
|
||||
return nil, accounts.ErrWalletClosed
|
||||
path, done, err := w.lockAndDerivePath(account)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Make sure the requested account is contained within
|
||||
path, ok := w.paths[account.Address]
|
||||
if !ok {
|
||||
return nil, accounts.ErrUnknownAccount
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
<-w.commsLock
|
||||
defer func() { w.commsLock <- struct{}{} }()
|
||||
defer done()
|
||||
|
||||
// Ensure the device isn't screwed with while user confirmation is pending
|
||||
// TODO(karalabe): remove if hotplug lands on Windows
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend++
|
||||
w.hub.commsLock.Unlock()
|
||||
|
||||
defer func() {
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend--
|
||||
w.hub.commsLock.Unlock()
|
||||
}()
|
||||
// Sign the transaction and verify the sender to avoid hardware fault surprises
|
||||
sender, signed, err := w.driver.SignTx(path, tx, chainID)
|
||||
if err != nil {
|
||||
|
|
@ -628,11 +616,10 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID
|
|||
return signed, nil
|
||||
}
|
||||
|
||||
// SignTextWithPassphrase implements accounts.Wallet, however signing arbitrary
|
||||
// data is not supported for Ledger wallets, so this method will always return
|
||||
// an error.
|
||||
// SignTextWithPassphrase implements accounts.Wallet, signing the text as an EIP-712
|
||||
// personal message.
|
||||
func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {
|
||||
return w.SignText(account, accounts.TextHash(text))
|
||||
return w.SignText(account, text)
|
||||
}
|
||||
|
||||
// SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given
|
||||
|
|
@ -641,3 +628,38 @@ func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase str
|
|||
func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
|
||||
return w.SignTx(account, tx, chainID)
|
||||
}
|
||||
|
||||
func (w *wallet) lockAndDerivePath(account accounts.Account) (accounts.DerivationPath, func(), error) {
|
||||
w.stateLock.RLock() // Comms have own mutex, this is for the state fields
|
||||
|
||||
// If the wallet is closed, abort
|
||||
if w.device == nil {
|
||||
w.stateLock.RUnlock()
|
||||
return nil, nil, accounts.ErrWalletClosed
|
||||
}
|
||||
// Make sure the requested account is contained within
|
||||
path, ok := w.paths[account.Address]
|
||||
if !ok {
|
||||
w.stateLock.RUnlock()
|
||||
return nil, nil, accounts.ErrUnknownAccount
|
||||
}
|
||||
// All infos gathered and metadata checks out, request signing
|
||||
<-w.commsLock
|
||||
|
||||
// Ensure the device isn't screwed with while user confirmation is pending
|
||||
// TODO(karalabe): remove if hotplug lands on Windows
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend++
|
||||
w.hub.commsLock.Unlock()
|
||||
|
||||
done := func() {
|
||||
w.stateLock.RUnlock()
|
||||
w.commsLock <- struct{}{}
|
||||
|
||||
w.hub.commsLock.Lock()
|
||||
w.hub.commsPend--
|
||||
w.hub.commsLock.Unlock()
|
||||
}
|
||||
|
||||
return path, done, nil
|
||||
}
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -45,7 +45,7 @@ require (
|
|||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c
|
||||
github.com/jackpal/go-nat-pmp v1.0.2
|
||||
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267
|
||||
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52
|
||||
github.com/karalabe/usb v0.0.3-0.20231219215548-8627268f6b0a
|
||||
github.com/kylelemons/godebug v1.1.0
|
||||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-isatty v0.0.20
|
||||
|
|
@ -56,6 +56,7 @@ require (
|
|||
github.com/protolambda/bls12-381-util v0.1.0
|
||||
github.com/protolambda/zrnt v0.34.1
|
||||
github.com/protolambda/ztyp v0.2.2
|
||||
github.com/reserve-protocol/trezor v0.0.0-20190523030725-9e38328dde28
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
|
||||
github.com/status-im/keycard-go v0.2.0
|
||||
|
|
@ -126,6 +127,7 @@ require (
|
|||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/mitchellh/pointerstructure v1.2.0 // indirect
|
||||
github.com/naoina/go-stringutil v0.1.0 // indirect
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e // indirect
|
||||
github.com/opentracing/opentracing-go v1.1.0 // indirect
|
||||
github.com/pion/dtls/v2 v2.2.7 // indirect
|
||||
github.com/pion/logging v0.2.2 // indirect
|
||||
|
|
|
|||
9
go.sum
9
go.sum
|
|
@ -215,8 +215,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
|||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I=
|
||||
github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8=
|
||||
github.com/karalabe/usb v0.0.3-0.20231219215548-8627268f6b0a h1:BGJeMa7efLsbPri2WJxtFOcjDPyjCdNlZWERE11GJAE=
|
||||
github.com/karalabe/usb v0.0.3-0.20231219215548-8627268f6b0a/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4=
|
||||
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
|
|
@ -256,6 +256,7 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
|
|
@ -271,6 +272,8 @@ github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hz
|
|||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e h1:Vbib8wJAaMEF9jusI/kMSYMr/LtRzM7+F9MJgt/nH8k=
|
||||
github.com/nsf/termbox-go v0.0.0-20190325093121-288510b9734e/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
|
||||
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
|
|
@ -324,6 +327,8 @@ github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNy
|
|||
github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
|
||||
github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4=
|
||||
github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs=
|
||||
github.com/reserve-protocol/trezor v0.0.0-20190523030725-9e38328dde28 h1:0XRrYV4bb+Y09cLQKsVE5gQ3HRebPXxY89zx+ZV2Fo0=
|
||||
github.com/reserve-protocol/trezor v0.0.0-20190523030725-9e38328dde28/go.mod h1:Twg3zlQzleALAU+gR5xSK112gdh9YLcQ6owamVh0lbY=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
|
|
|
|||
Loading…
Reference in a new issue