mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-29 09:58:47 +00:00
feat(core): support displaying EIP-712 message hash during signing
This commit is contained in:
parent
11bad835f1
commit
70ccc36ae4
@ -26,6 +26,7 @@ message EthereumSignTypedData {
|
|||||||
required string primary_type = 2; // name of the root message struct
|
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 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 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
1
core/.changelog.d/5344.added
Normal file
1
core/.changelog.d/5344.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add support for displaying the message hash when signing Ethereum EIP-712 typed data.
|
@ -1105,6 +1105,7 @@ static void _librust_qstrs(void) {
|
|||||||
MP_QSTR_ethereum__title_all_input_data_template;
|
MP_QSTR_ethereum__title_all_input_data_template;
|
||||||
MP_QSTR_ethereum__title_confirm_domain;
|
MP_QSTR_ethereum__title_confirm_domain;
|
||||||
MP_QSTR_ethereum__title_confirm_message;
|
MP_QSTR_ethereum__title_confirm_message;
|
||||||
|
MP_QSTR_ethereum__title_confirm_message_hash;
|
||||||
MP_QSTR_ethereum__title_confirm_struct;
|
MP_QSTR_ethereum__title_confirm_struct;
|
||||||
MP_QSTR_ethereum__title_confirm_typed_data;
|
MP_QSTR_ethereum__title_confirm_typed_data;
|
||||||
MP_QSTR_ethereum__title_input_data;
|
MP_QSTR_ethereum__title_input_data;
|
||||||
|
@ -1450,6 +1450,8 @@ pub enum TranslatedString {
|
|||||||
address__title_provider_address = 1053, // "Provider address"
|
address__title_provider_address = 1053, // "Provider address"
|
||||||
address__title_refund_address = 1054, // "Refund address"
|
address__title_refund_address = 1054, // "Refund address"
|
||||||
words__assets = 1055, // "Assets"
|
words__assets = 1055, // "Assets"
|
||||||
|
#[cfg(feature = "universal_fw")]
|
||||||
|
ethereum__title_confirm_message_hash = 1056, // "Confirm message hash"
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TranslatedString {
|
impl TranslatedString {
|
||||||
@ -3212,6 +3214,8 @@ impl TranslatedString {
|
|||||||
(Self::address__title_provider_address, "Provider address"),
|
(Self::address__title_provider_address, "Provider address"),
|
||||||
(Self::address__title_refund_address, "Refund address"),
|
(Self::address__title_refund_address, "Refund address"),
|
||||||
(Self::words__assets, "Assets"),
|
(Self::words__assets, "Assets"),
|
||||||
|
#[cfg(feature = "universal_fw")]
|
||||||
|
(Self::ethereum__title_confirm_message_hash, "Confirm message hash"),
|
||||||
];
|
];
|
||||||
|
|
||||||
#[cfg(feature = "micropython")]
|
#[cfg(feature = "micropython")]
|
||||||
@ -3738,6 +3742,8 @@ impl TranslatedString {
|
|||||||
#[cfg(feature = "universal_fw")]
|
#[cfg(feature = "universal_fw")]
|
||||||
(Qstr::MP_QSTR_ethereum__title_confirm_message, Self::ethereum__title_confirm_message),
|
(Qstr::MP_QSTR_ethereum__title_confirm_message, Self::ethereum__title_confirm_message),
|
||||||
#[cfg(feature = "universal_fw")]
|
#[cfg(feature = "universal_fw")]
|
||||||
|
(Qstr::MP_QSTR_ethereum__title_confirm_message_hash, Self::ethereum__title_confirm_message_hash),
|
||||||
|
#[cfg(feature = "universal_fw")]
|
||||||
(Qstr::MP_QSTR_ethereum__title_confirm_struct, Self::ethereum__title_confirm_struct),
|
(Qstr::MP_QSTR_ethereum__title_confirm_struct, Self::ethereum__title_confirm_struct),
|
||||||
#[cfg(feature = "universal_fw")]
|
#[cfg(feature = "universal_fw")]
|
||||||
(Qstr::MP_QSTR_ethereum__title_confirm_typed_data, Self::ethereum__title_confirm_typed_data),
|
(Qstr::MP_QSTR_ethereum__title_confirm_typed_data, Self::ethereum__title_confirm_typed_data),
|
||||||
|
@ -330,6 +330,7 @@ class TR:
|
|||||||
ethereum__title_all_input_data_template: str = "All input data ({0} bytes)"
|
ethereum__title_all_input_data_template: str = "All input data ({0} bytes)"
|
||||||
ethereum__title_confirm_domain: str = "Confirm domain"
|
ethereum__title_confirm_domain: str = "Confirm domain"
|
||||||
ethereum__title_confirm_message: str = "Confirm message"
|
ethereum__title_confirm_message: str = "Confirm message"
|
||||||
|
ethereum__title_confirm_message_hash: str = "Confirm message hash"
|
||||||
ethereum__title_confirm_struct: str = "Confirm struct"
|
ethereum__title_confirm_struct: str = "Confirm struct"
|
||||||
ethereum__title_confirm_typed_data: str = "Confirm typed data"
|
ethereum__title_confirm_typed_data: str = "Confirm typed data"
|
||||||
ethereum__title_input_data: str = "Input data"
|
ethereum__title_input_data: str = "Input data"
|
||||||
|
@ -305,6 +305,24 @@ def require_confirm_other_data(data: bytes, data_total: int) -> Awaitable[None]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def confirm_message_hash(message_hash: bytes) -> None:
|
||||||
|
from ubinascii import hexlify
|
||||||
|
|
||||||
|
from trezor.ui.layouts import confirm_value
|
||||||
|
|
||||||
|
message_hash_hex = "0x" + hexlify(message_hash).decode()
|
||||||
|
|
||||||
|
await confirm_value(
|
||||||
|
TR.ethereum__title_confirm_message_hash,
|
||||||
|
message_hash_hex,
|
||||||
|
"",
|
||||||
|
"confirm_message_hash",
|
||||||
|
verb=TR.buttons__confirm,
|
||||||
|
br_code=ButtonRequestType.SignTx,
|
||||||
|
cancel=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def confirm_typed_data_final() -> None:
|
async def confirm_typed_data_final() -> None:
|
||||||
from trezor.ui.layouts import confirm_action
|
from trezor.ui.layouts import confirm_action
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ async def sign_typed_data(
|
|||||||
await require_confirm_address(address_bytes)
|
await require_confirm_address(address_bytes)
|
||||||
|
|
||||||
data_hash = await _generate_typed_data_hash(
|
data_hash = await _generate_typed_data_hash(
|
||||||
msg.primary_type, msg.metamask_v4_compat
|
msg.primary_type, msg.metamask_v4_compat, msg.show_message_hash
|
||||||
)
|
)
|
||||||
|
|
||||||
signature = secp256k1.sign(
|
signature = secp256k1.sign(
|
||||||
@ -59,7 +59,9 @@ async def sign_typed_data(
|
|||||||
|
|
||||||
|
|
||||||
async def _generate_typed_data_hash(
|
async def _generate_typed_data_hash(
|
||||||
primary_type: str, metamask_v4_compat: bool = True
|
primary_type: str,
|
||||||
|
metamask_v4_compat: bool = True,
|
||||||
|
show_message_hash: bytes | None = None,
|
||||||
) -> bytes:
|
) -> bytes:
|
||||||
"""
|
"""
|
||||||
Generate typed data hash according to EIP-712 specification
|
Generate typed data hash according to EIP-712 specification
|
||||||
@ -71,6 +73,7 @@ async def _generate_typed_data_hash(
|
|||||||
|
|
||||||
from .layout import (
|
from .layout import (
|
||||||
confirm_empty_typed_message,
|
confirm_empty_typed_message,
|
||||||
|
confirm_message_hash,
|
||||||
confirm_typed_data_final,
|
confirm_typed_data_final,
|
||||||
should_show_domain,
|
should_show_domain,
|
||||||
)
|
)
|
||||||
@ -110,6 +113,11 @@ async def _generate_typed_data_hash(
|
|||||||
[primary_type],
|
[primary_type],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if show_message_hash is not None:
|
||||||
|
if message_hash != show_message_hash:
|
||||||
|
raise DataError("Message hash mismatch")
|
||||||
|
await confirm_message_hash(message_hash)
|
||||||
|
|
||||||
await confirm_typed_data_final()
|
await confirm_typed_data_final()
|
||||||
|
|
||||||
return keccak256(b"\x19\x01" + domain_separator + message_hash)
|
return keccak256(b"\x19\x01" + domain_separator + message_hash)
|
||||||
|
2
core/src/trezor/messages.py
generated
2
core/src/trezor/messages.py
generated
@ -3877,6 +3877,7 @@ if TYPE_CHECKING:
|
|||||||
primary_type: "str"
|
primary_type: "str"
|
||||||
metamask_v4_compat: "bool"
|
metamask_v4_compat: "bool"
|
||||||
definitions: "EthereumDefinitions | None"
|
definitions: "EthereumDefinitions | None"
|
||||||
|
show_message_hash: "bytes | None"
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -3885,6 +3886,7 @@ if TYPE_CHECKING:
|
|||||||
address_n: "list[int] | None" = None,
|
address_n: "list[int] | None" = None,
|
||||||
metamask_v4_compat: "bool | None" = None,
|
metamask_v4_compat: "bool | None" = None,
|
||||||
definitions: "EthereumDefinitions | None" = None,
|
definitions: "EthereumDefinitions | None" = None,
|
||||||
|
show_message_hash: "bytes | None" = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -371,6 +371,7 @@
|
|||||||
"ethereum__title_all_input_data_template": "All input data ({0} bytes)",
|
"ethereum__title_all_input_data_template": "All input data ({0} bytes)",
|
||||||
"ethereum__title_confirm_domain": "Confirm domain",
|
"ethereum__title_confirm_domain": "Confirm domain",
|
||||||
"ethereum__title_confirm_message": "Confirm message",
|
"ethereum__title_confirm_message": "Confirm message",
|
||||||
|
"ethereum__title_confirm_message_hash": "Confirm message hash",
|
||||||
"ethereum__title_confirm_struct": "Confirm struct",
|
"ethereum__title_confirm_struct": "Confirm struct",
|
||||||
"ethereum__title_confirm_typed_data": "Confirm typed data",
|
"ethereum__title_confirm_typed_data": "Confirm typed data",
|
||||||
"ethereum__title_input_data": "Input data",
|
"ethereum__title_input_data": "Input data",
|
||||||
|
@ -1054,5 +1054,6 @@
|
|||||||
"1052": "words__swap",
|
"1052": "words__swap",
|
||||||
"1053": "address__title_provider_address",
|
"1053": "address__title_provider_address",
|
||||||
"1054": "address__title_refund_address",
|
"1054": "address__title_refund_address",
|
||||||
"1055": "words__assets"
|
"1055": "words__assets",
|
||||||
|
"1056": "ethereum__title_confirm_message_hash"
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"current": {
|
"current": {
|
||||||
"merkle_root": "e2482ef9c1fe4243754ccd9898b3c05ab854d59bf5b9afae67630262bdc47d4e",
|
"merkle_root": "aa1b72313fa6ff028138ae1e6f26362107ffa41f4d745aa4170036a15b6d7a6f",
|
||||||
"datetime": "2025-07-14T09:23:54.196279+00:00",
|
"datetime": "2025-07-17T02:01:07.922808+00:00",
|
||||||
"commit": "265104d00d8ddbc47753055021ae67fffa67423f"
|
"commit": "6cc9c629414e9cf8bc66b22580555c098e0fb3eb"
|
||||||
},
|
},
|
||||||
"history": [
|
"history": [
|
||||||
{
|
{
|
||||||
|
3
python/src/trezorlib/messages.py
generated
3
python/src/trezorlib/messages.py
generated
@ -5293,6 +5293,7 @@ class EthereumSignTypedData(protobuf.MessageType):
|
|||||||
2: protobuf.Field("primary_type", "string", repeated=False, required=True),
|
2: protobuf.Field("primary_type", "string", repeated=False, required=True),
|
||||||
3: protobuf.Field("metamask_v4_compat", "bool", repeated=False, required=False, default=True),
|
3: protobuf.Field("metamask_v4_compat", "bool", repeated=False, required=False, default=True),
|
||||||
4: protobuf.Field("definitions", "EthereumDefinitions", repeated=False, required=False, default=None),
|
4: protobuf.Field("definitions", "EthereumDefinitions", repeated=False, required=False, default=None),
|
||||||
|
5: protobuf.Field("show_message_hash", "bytes", repeated=False, required=False, default=None),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@ -5302,11 +5303,13 @@ class EthereumSignTypedData(protobuf.MessageType):
|
|||||||
address_n: Optional[Sequence["int"]] = None,
|
address_n: Optional[Sequence["int"]] = None,
|
||||||
metamask_v4_compat: Optional["bool"] = True,
|
metamask_v4_compat: Optional["bool"] = True,
|
||||||
definitions: Optional["EthereumDefinitions"] = None,
|
definitions: Optional["EthereumDefinitions"] = None,
|
||||||
|
show_message_hash: Optional["bytes"] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.address_n: Sequence["int"] = address_n if address_n is not None else []
|
self.address_n: Sequence["int"] = address_n if address_n is not None else []
|
||||||
self.primary_type = primary_type
|
self.primary_type = primary_type
|
||||||
self.metamask_v4_compat = metamask_v4_compat
|
self.metamask_v4_compat = metamask_v4_compat
|
||||||
self.definitions = definitions
|
self.definitions = definitions
|
||||||
|
self.show_message_hash = show_message_hash
|
||||||
|
|
||||||
|
|
||||||
class EthereumTypedDataStructRequest(protobuf.MessageType):
|
class EthereumTypedDataStructRequest(protobuf.MessageType):
|
||||||
|
@ -36,6 +36,8 @@ pub struct EthereumSignTypedData {
|
|||||||
pub metamask_v4_compat: ::std::option::Option<bool>,
|
pub metamask_v4_compat: ::std::option::Option<bool>,
|
||||||
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.definitions)
|
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.definitions)
|
||||||
pub definitions: ::protobuf::MessageField<super::messages_ethereum::EthereumDefinitions>,
|
pub definitions: ::protobuf::MessageField<super::messages_ethereum::EthereumDefinitions>,
|
||||||
|
// @@protoc_insertion_point(field:hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.show_message_hash)
|
||||||
|
pub show_message_hash: ::std::option::Option<::std::vec::Vec<u8>>,
|
||||||
// special fields
|
// special fields
|
||||||
// @@protoc_insertion_point(special_field:hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.special_fields)
|
// @@protoc_insertion_point(special_field:hw.trezor.messages.ethereum_eip712.EthereumSignTypedData.special_fields)
|
||||||
pub special_fields: ::protobuf::SpecialFields,
|
pub special_fields: ::protobuf::SpecialFields,
|
||||||
@ -107,8 +109,44 @@ impl EthereumSignTypedData {
|
|||||||
self.metamask_v4_compat = ::std::option::Option::Some(v);
|
self.metamask_v4_compat = ::std::option::Option::Some(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optional bytes show_message_hash = 5;
|
||||||
|
|
||||||
|
pub fn show_message_hash(&self) -> &[u8] {
|
||||||
|
match self.show_message_hash.as_ref() {
|
||||||
|
Some(v) => v,
|
||||||
|
None => &[],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_show_message_hash(&mut self) {
|
||||||
|
self.show_message_hash = ::std::option::Option::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_show_message_hash(&self) -> bool {
|
||||||
|
self.show_message_hash.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Param is passed by value, moved
|
||||||
|
pub fn set_show_message_hash(&mut self, v: ::std::vec::Vec<u8>) {
|
||||||
|
self.show_message_hash = ::std::option::Option::Some(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable pointer to the field.
|
||||||
|
// If field is not initialized, it is initialized with default value first.
|
||||||
|
pub fn mut_show_message_hash(&mut self) -> &mut ::std::vec::Vec<u8> {
|
||||||
|
if self.show_message_hash.is_none() {
|
||||||
|
self.show_message_hash = ::std::option::Option::Some(::std::vec::Vec::new());
|
||||||
|
}
|
||||||
|
self.show_message_hash.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take field
|
||||||
|
pub fn take_show_message_hash(&mut self) -> ::std::vec::Vec<u8> {
|
||||||
|
self.show_message_hash.take().unwrap_or_else(|| ::std::vec::Vec::new())
|
||||||
|
}
|
||||||
|
|
||||||
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData {
|
||||||
let mut fields = ::std::vec::Vec::with_capacity(4);
|
let mut fields = ::std::vec::Vec::with_capacity(5);
|
||||||
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
let mut oneofs = ::std::vec::Vec::with_capacity(0);
|
||||||
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
|
fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>(
|
||||||
"address_n",
|
"address_n",
|
||||||
@ -130,6 +168,11 @@ impl EthereumSignTypedData {
|
|||||||
|m: &EthereumSignTypedData| { &m.definitions },
|
|m: &EthereumSignTypedData| { &m.definitions },
|
||||||
|m: &mut EthereumSignTypedData| { &mut m.definitions },
|
|m: &mut EthereumSignTypedData| { &mut m.definitions },
|
||||||
));
|
));
|
||||||
|
fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>(
|
||||||
|
"show_message_hash",
|
||||||
|
|m: &EthereumSignTypedData| { &m.show_message_hash },
|
||||||
|
|m: &mut EthereumSignTypedData| { &mut m.show_message_hash },
|
||||||
|
));
|
||||||
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<EthereumSignTypedData>(
|
::protobuf::reflect::GeneratedMessageDescriptorData::new_2::<EthereumSignTypedData>(
|
||||||
"EthereumSignTypedData",
|
"EthereumSignTypedData",
|
||||||
fields,
|
fields,
|
||||||
@ -171,6 +214,9 @@ impl ::protobuf::Message for EthereumSignTypedData {
|
|||||||
34 => {
|
34 => {
|
||||||
::protobuf::rt::read_singular_message_into_field(is, &mut self.definitions)?;
|
::protobuf::rt::read_singular_message_into_field(is, &mut self.definitions)?;
|
||||||
},
|
},
|
||||||
|
42 => {
|
||||||
|
self.show_message_hash = ::std::option::Option::Some(is.read_bytes()?);
|
||||||
|
},
|
||||||
tag => {
|
tag => {
|
||||||
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?;
|
||||||
},
|
},
|
||||||
@ -196,6 +242,9 @@ impl ::protobuf::Message for EthereumSignTypedData {
|
|||||||
let len = v.compute_size();
|
let len = v.compute_size();
|
||||||
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
|
my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len;
|
||||||
}
|
}
|
||||||
|
if let Some(v) = self.show_message_hash.as_ref() {
|
||||||
|
my_size += ::protobuf::rt::bytes_size(5, &v);
|
||||||
|
}
|
||||||
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields());
|
||||||
self.special_fields.cached_size().set(my_size as u32);
|
self.special_fields.cached_size().set(my_size as u32);
|
||||||
my_size
|
my_size
|
||||||
@ -214,6 +263,9 @@ impl ::protobuf::Message for EthereumSignTypedData {
|
|||||||
if let Some(v) = self.definitions.as_ref() {
|
if let Some(v) = self.definitions.as_ref() {
|
||||||
::protobuf::rt::write_message_field_with_cached_size(4, v, os)?;
|
::protobuf::rt::write_message_field_with_cached_size(4, v, os)?;
|
||||||
}
|
}
|
||||||
|
if let Some(v) = self.show_message_hash.as_ref() {
|
||||||
|
os.write_bytes(5, v)?;
|
||||||
|
}
|
||||||
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
os.write_unknown_fields(self.special_fields.unknown_fields())?;
|
||||||
::std::result::Result::Ok(())
|
::std::result::Result::Ok(())
|
||||||
}
|
}
|
||||||
@ -235,6 +287,7 @@ impl ::protobuf::Message for EthereumSignTypedData {
|
|||||||
self.primary_type = ::std::option::Option::None;
|
self.primary_type = ::std::option::Option::None;
|
||||||
self.metamask_v4_compat = ::std::option::Option::None;
|
self.metamask_v4_compat = ::std::option::Option::None;
|
||||||
self.definitions.clear();
|
self.definitions.clear();
|
||||||
|
self.show_message_hash = ::std::option::Option::None;
|
||||||
self.special_fields.clear();
|
self.special_fields.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +297,7 @@ impl ::protobuf::Message for EthereumSignTypedData {
|
|||||||
primary_type: ::std::option::Option::None,
|
primary_type: ::std::option::Option::None,
|
||||||
metamask_v4_compat: ::std::option::Option::None,
|
metamask_v4_compat: ::std::option::Option::None,
|
||||||
definitions: ::protobuf::MessageField::none(),
|
definitions: ::protobuf::MessageField::none(),
|
||||||
|
show_message_hash: ::std::option::Option::None,
|
||||||
special_fields: ::protobuf::SpecialFields::new(),
|
special_fields: ::protobuf::SpecialFields::new(),
|
||||||
};
|
};
|
||||||
&instance
|
&instance
|
||||||
@ -1399,12 +1453,13 @@ impl ::protobuf::reflect::ProtobufValue for EthereumTypedDataValueAck {
|
|||||||
|
|
||||||
static file_descriptor_proto_data: &'static [u8] = b"\
|
static file_descriptor_proto_data: &'static [u8] = b"\
|
||||||
\n\x1emessages-ethereum-eip712.proto\x12\"hw.trezor.messages.ethereum_ei\
|
\n\x1emessages-ethereum-eip712.proto\x12\"hw.trezor.messages.ethereum_ei\
|
||||||
p712\x1a\x17messages-ethereum.proto\"\xdf\x01\n\x15EthereumSignTypedData\
|
p712\x1a\x17messages-ethereum.proto\"\x8b\x02\n\x15EthereumSignTypedData\
|
||||||
\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12!\n\x0cprimary_\
|
\x12\x1b\n\taddress_n\x18\x01\x20\x03(\rR\x08addressN\x12!\n\x0cprimary_\
|
||||||
type\x18\x02\x20\x02(\tR\x0bprimaryType\x122\n\x12metamask_v4_compat\x18\
|
type\x18\x02\x20\x02(\tR\x0bprimaryType\x122\n\x12metamask_v4_compat\x18\
|
||||||
\x03\x20\x01(\x08:\x04trueR\x10metamaskV4Compat\x12R\n\x0bdefinitions\
|
\x03\x20\x01(\x08:\x04trueR\x10metamaskV4Compat\x12R\n\x0bdefinitions\
|
||||||
\x18\x04\x20\x01(\x0b20.hw.trezor.messages.ethereum.EthereumDefinitionsR\
|
\x18\x04\x20\x01(\x0b20.hw.trezor.messages.ethereum.EthereumDefinitionsR\
|
||||||
\x0bdefinitions\"4\n\x1eEthereumTypedDataStructRequest\x12\x12\n\x04name\
|
\x0bdefinitions\x12*\n\x11show_message_hash\x18\x05\x20\x01(\x0cR\x0fsho\
|
||||||
|
wMessageHash\"4\n\x1eEthereumTypedDataStructRequest\x12\x12\n\x04name\
|
||||||
\x18\x01\x20\x02(\tR\x04name\"\xb4\x05\n\x1aEthereumTypedDataStructAck\
|
\x18\x01\x20\x02(\tR\x04name\"\xb4\x05\n\x1aEthereumTypedDataStructAck\
|
||||||
\x12m\n\x07members\x18\x01\x20\x03(\x0b2S.hw.trezor.messages.ethereum_ei\
|
\x12m\n\x07members\x18\x01\x20\x03(\x0b2S.hw.trezor.messages.ethereum_ei\
|
||||||
p712.EthereumTypedDataStructAck.EthereumStructMemberR\x07members\x1a\x90\
|
p712.EthereumTypedDataStructAck.EthereumStructMemberR\x07members\x1a\x90\
|
||||||
|
Loading…
Reference in New Issue
Block a user