mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-08 09:58:46 +00:00
feat(legacy): Implement EIP-712 signing
This commit is contained in:
parent
a9a6495c7e
commit
77ab865386
@ -87,12 +87,3 @@ message EthereumTypedDataValueAck {
|
|||||||
// * array types: number of elements, encoded as uint16.
|
// * array types: number of elements, encoded as uint16.
|
||||||
// * struct types: undefined, Trezor will not query a struct field.
|
// * struct types: undefined, Trezor will not query a struct field.
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
}
|
|
||||||
|
@ -149,3 +149,24 @@ message EthereumVerifyMessage {
|
|||||||
required bytes message = 3; // message to verify
|
required bytes message = 3; // message to verify
|
||||||
required string address = 4; // address to verify
|
required string address = 4; // address to verify
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
required bytes message_hash = 3; // Hash of the data of typed data to be signed
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
}
|
||||||
|
@ -191,6 +191,7 @@ enum MessageType {
|
|||||||
MessageType_EthereumTypedDataValueRequest = 467 [(wire_out) = true];
|
MessageType_EthereumTypedDataValueRequest = 467 [(wire_out) = true];
|
||||||
MessageType_EthereumTypedDataValueAck = 468 [(wire_in) = true];
|
MessageType_EthereumTypedDataValueAck = 468 [(wire_in) = true];
|
||||||
MessageType_EthereumTypedDataSignature = 469 [(wire_out) = true];
|
MessageType_EthereumTypedDataSignature = 469 [(wire_out) = true];
|
||||||
|
MessageType_EthereumSignTypedHash = 470 [(wire_in) = true];
|
||||||
|
|
||||||
// NEM
|
// NEM
|
||||||
MessageType_NEMGetAddress = 67 [(wire_in) = true];
|
MessageType_NEMGetAddress = 67 [(wire_in) = true];
|
||||||
|
@ -103,6 +103,7 @@ if not utils.BITCOIN_ONLY:
|
|||||||
EthereumTypedDataValueRequest = 467
|
EthereumTypedDataValueRequest = 467
|
||||||
EthereumTypedDataValueAck = 468
|
EthereumTypedDataValueAck = 468
|
||||||
EthereumTypedDataSignature = 469
|
EthereumTypedDataSignature = 469
|
||||||
|
EthereumSignTypedHash = 470
|
||||||
NEMGetAddress = 67
|
NEMGetAddress = 67
|
||||||
NEMAddress = 68
|
NEMAddress = 68
|
||||||
NEMSignTx = 69
|
NEMSignTx = 69
|
||||||
|
@ -108,6 +108,7 @@ if TYPE_CHECKING:
|
|||||||
EthereumTypedDataValueRequest = 467
|
EthereumTypedDataValueRequest = 467
|
||||||
EthereumTypedDataValueAck = 468
|
EthereumTypedDataValueAck = 468
|
||||||
EthereumTypedDataSignature = 469
|
EthereumTypedDataSignature = 469
|
||||||
|
EthereumSignTypedHash = 470
|
||||||
NEMGetAddress = 67
|
NEMGetAddress = 67
|
||||||
NEMAddress = 68
|
NEMAddress = 68
|
||||||
NEMSignTx = 69
|
NEMSignTx = 69
|
||||||
|
@ -3235,6 +3235,40 @@ if TYPE_CHECKING:
|
|||||||
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumVerifyMessage"]:
|
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumVerifyMessage"]:
|
||||||
return isinstance(msg, cls)
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
|
class EthereumSignTypedHash(protobuf.MessageType):
|
||||||
|
address_n: "list[int]"
|
||||||
|
domain_separator_hash: "bytes"
|
||||||
|
message_hash: "bytes"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
domain_separator_hash: "bytes",
|
||||||
|
message_hash: "bytes",
|
||||||
|
address_n: "list[int] | None" = None,
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumSignTypedHash"]:
|
||||||
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
|
class EthereumTypedDataSignature(protobuf.MessageType):
|
||||||
|
signature: "bytes"
|
||||||
|
address: "str"
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
signature: "bytes",
|
||||||
|
address: "str",
|
||||||
|
) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumTypedDataSignature"]:
|
||||||
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
class EthereumAccessList(protobuf.MessageType):
|
class EthereumAccessList(protobuf.MessageType):
|
||||||
address: "str"
|
address: "str"
|
||||||
storage_keys: "list[bytes]"
|
storage_keys: "list[bytes]"
|
||||||
@ -3325,22 +3359,6 @@ if TYPE_CHECKING:
|
|||||||
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumTypedDataValueAck"]:
|
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumTypedDataValueAck"]:
|
||||||
return isinstance(msg, cls)
|
return isinstance(msg, cls)
|
||||||
|
|
||||||
class EthereumTypedDataSignature(protobuf.MessageType):
|
|
||||||
signature: "bytes"
|
|
||||||
address: "str"
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
signature: "bytes",
|
|
||||||
address: "str",
|
|
||||||
) -> None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_type_of(cls, msg: protobuf.MessageType) -> TypeGuard["EthereumTypedDataSignature"]:
|
|
||||||
return isinstance(msg, cls)
|
|
||||||
|
|
||||||
class EthereumStructMember(protobuf.MessageType):
|
class EthereumStructMember(protobuf.MessageType):
|
||||||
type: "EthereumFieldType"
|
type: "EthereumFieldType"
|
||||||
name: "str"
|
name: "str"
|
||||||
|
1
legacy/firmware/.changelog.d/131.added
Normal file
1
legacy/firmware/.changelog.d/131.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support for blindly signing EIP-712 data.
|
@ -976,6 +976,36 @@ int ethereum_message_verify(const EthereumVerifyMessage *msg) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ethereum_typed_hash(const uint8_t domain_separator_hash[32],
|
||||||
|
const uint8_t message_hash[32],
|
||||||
|
uint8_t hash[32]) {
|
||||||
|
struct SHA3_CTX ctx = {0};
|
||||||
|
sha3_256_Init(&ctx);
|
||||||
|
sha3_Update(&ctx, (const uint8_t *)"\x19\x01", 2);
|
||||||
|
sha3_Update(&ctx, domain_separator_hash, 32);
|
||||||
|
sha3_Update(&ctx, message_hash, 32);
|
||||||
|
keccak_Final(&ctx, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ethereum_typed_hash_sign(const EthereumSignTypedHash *msg,
|
||||||
|
const HDNode *node,
|
||||||
|
EthereumTypedDataSignature *resp) {
|
||||||
|
uint8_t hash[32] = {0};
|
||||||
|
ethereum_typed_hash(msg->domain_separator_hash.bytes, msg->message_hash.bytes,
|
||||||
|
hash);
|
||||||
|
|
||||||
|
uint8_t v = 0;
|
||||||
|
if (ecdsa_sign_digest(&secp256k1, node->private_key, hash,
|
||||||
|
resp->signature.bytes, &v, ethereum_is_canonic) != 0) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_ProcessError, _("Signing failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp->signature.bytes[64] = 27 + v;
|
||||||
|
resp->signature.size = 65;
|
||||||
|
msg_write(MessageType_MessageType_EthereumTypedDataSignature, resp);
|
||||||
|
}
|
||||||
|
|
||||||
bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]) {
|
bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]) {
|
||||||
memzero(pubkeyhash, 20);
|
memzero(pubkeyhash, 20);
|
||||||
size_t len = strlen(address);
|
size_t len = strlen(address);
|
||||||
|
@ -34,6 +34,9 @@ void ethereum_signing_txack(const EthereumTxAck *msg);
|
|||||||
void ethereum_message_sign(const EthereumSignMessage *msg, const HDNode *node,
|
void ethereum_message_sign(const EthereumSignMessage *msg, const HDNode *node,
|
||||||
EthereumMessageSignature *resp);
|
EthereumMessageSignature *resp);
|
||||||
int ethereum_message_verify(const EthereumVerifyMessage *msg);
|
int ethereum_message_verify(const EthereumVerifyMessage *msg);
|
||||||
|
void ethereum_typed_hash_sign(const EthereumSignTypedHash *msg,
|
||||||
|
const HDNode *node,
|
||||||
|
EthereumTypedDataSignature *resp);
|
||||||
bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]);
|
bool ethereum_parse(const char *address, uint8_t pubkeyhash[20]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -104,6 +104,7 @@ void fsm_msgEthereumSignTxEIP1559(const EthereumSignTxEIP1559 *msg);
|
|||||||
void fsm_msgEthereumTxAck(const EthereumTxAck *msg);
|
void fsm_msgEthereumTxAck(const EthereumTxAck *msg);
|
||||||
void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg);
|
void fsm_msgEthereumSignMessage(const EthereumSignMessage *msg);
|
||||||
void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg);
|
void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg);
|
||||||
|
void fsm_msgEthereumSignTypedHash(const EthereumSignTypedHash *msg);
|
||||||
|
|
||||||
// nem
|
// nem
|
||||||
void fsm_msgNEMGetAddress(
|
void fsm_msgNEMGetAddress(
|
||||||
|
@ -212,3 +212,64 @@ void fsm_msgEthereumVerifyMessage(const EthereumVerifyMessage *msg) {
|
|||||||
|
|
||||||
layoutHome();
|
layoutHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fsm_msgEthereumSignTypedHash(const EthereumSignTypedHash *msg) {
|
||||||
|
RESP_INIT(EthereumTypedDataSignature);
|
||||||
|
|
||||||
|
CHECK_INITIALIZED
|
||||||
|
|
||||||
|
CHECK_PIN
|
||||||
|
|
||||||
|
if (msg->domain_separator_hash.size != 32 || msg->message_hash.size != 32) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_DataError, _("Invalid hash length"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutDialogSwipe(&bmp_icon_warning, _("Abort"), _("Continue"), NULL,
|
||||||
|
_("Unable to show"), _("EIP-712 data."), NULL,
|
||||||
|
_("Sign at your own risk."), NULL, NULL);
|
||||||
|
if (!protectButton(ButtonRequestType_ButtonRequest_ProtectCall, false)) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HDNode *node = fsm_getDerivedNode(SECP256K1_NAME, msg->address_n,
|
||||||
|
msg->address_n_count, NULL);
|
||||||
|
if (!node) return;
|
||||||
|
|
||||||
|
uint8_t pubkeyhash[20] = {0};
|
||||||
|
if (!hdnode_get_ethereum_pubkeyhash(node, pubkeyhash)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
resp->address[0] = '0';
|
||||||
|
resp->address[1] = 'x';
|
||||||
|
ethereum_address_checksum(pubkeyhash, resp->address + 2, false, 0);
|
||||||
|
// ethereum_address_checksum adds trailing zero
|
||||||
|
|
||||||
|
layoutVerifyAddress(NULL, resp->address);
|
||||||
|
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
layoutConfirmHash(&bmp_icon_warning, _("EIP-712 domain hash"),
|
||||||
|
msg->domain_separator_hash.bytes, 32);
|
||||||
|
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layoutConfirmHash(&bmp_icon_warning, _("EIP-712 message hash"),
|
||||||
|
msg->message_hash.bytes, 32);
|
||||||
|
if (!protectButton(ButtonRequestType_ButtonRequest_Other, false)) {
|
||||||
|
fsm_sendFailure(FailureType_Failure_ActionCancelled, NULL);
|
||||||
|
layoutHome();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ethereum_typed_hash_sign(msg, node, resp);
|
||||||
|
layoutHome();
|
||||||
|
}
|
||||||
|
@ -1253,3 +1253,22 @@ void layoutConfirmSafetyChecks(SafetyCheckLevel safety_ckeck_level) {
|
|||||||
_("be unsafe?"), NULL);
|
_("be unsafe?"), NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void layoutConfirmHash(const BITMAP *icon, const char *description,
|
||||||
|
const uint8_t *hash, uint32_t len) {
|
||||||
|
const char **str = split_message_hex(hash, len);
|
||||||
|
|
||||||
|
layoutSwipe();
|
||||||
|
oledClear();
|
||||||
|
oledDrawBitmap(0, 0, icon);
|
||||||
|
oledDrawString(20, 0 * 9, description, FONT_STANDARD);
|
||||||
|
oledDrawString(20, 1 * 9, str[0], FONT_FIXED);
|
||||||
|
oledDrawString(20, 2 * 9, str[1], FONT_FIXED);
|
||||||
|
oledDrawString(20, 3 * 9, str[2], FONT_FIXED);
|
||||||
|
oledDrawString(20, 4 * 9, str[3], FONT_FIXED);
|
||||||
|
oledHLine(OLED_HEIGHT - 13);
|
||||||
|
|
||||||
|
layoutButtonNo(_("Cancel"), &bmp_btn_cancel);
|
||||||
|
layoutButtonYes(_("Confirm"), &bmp_btn_confirm);
|
||||||
|
oledRefresh();
|
||||||
|
}
|
||||||
|
@ -110,6 +110,9 @@ void layoutCosiCommitSign(const uint32_t *address_n, size_t address_n_count,
|
|||||||
void layoutConfirmAutoLockDelay(uint32_t delay_ms);
|
void layoutConfirmAutoLockDelay(uint32_t delay_ms);
|
||||||
void layoutConfirmSafetyChecks(SafetyCheckLevel safety_checks_level);
|
void layoutConfirmSafetyChecks(SafetyCheckLevel safety_checks_level);
|
||||||
|
|
||||||
|
void layoutConfirmHash(const BITMAP *icon, const char *description,
|
||||||
|
const uint8_t *hash, uint32_t len);
|
||||||
|
|
||||||
const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen);
|
const char **split_message(const uint8_t *msg, uint32_t len, uint32_t rowlen);
|
||||||
const char **split_message_hex(const uint8_t *msg, uint32_t len);
|
const char **split_message_hex(const uint8_t *msg, uint32_t len);
|
||||||
|
|
||||||
|
@ -6,7 +6,9 @@ SKIPPED_MESSAGES := Binance Cardano DebugMonero Eos Monero Ontology Ripple SdPro
|
|||||||
DebugLinkRecordScreen DebugLinkReseedRandom DebugLinkShowText DebugLinkEraseSdCard DebugLinkWatchLayout \
|
DebugLinkRecordScreen DebugLinkReseedRandom DebugLinkShowText DebugLinkEraseSdCard DebugLinkWatchLayout \
|
||||||
GetOwnershipProof OwnershipProof GetOwnershipId OwnershipId AuthorizeCoinJoin DoPreauthorized \
|
GetOwnershipProof OwnershipProof GetOwnershipId OwnershipId AuthorizeCoinJoin DoPreauthorized \
|
||||||
CancelAuthorization DebugLinkLayout \
|
CancelAuthorization DebugLinkLayout \
|
||||||
TxAckInput TxAckOutput TxAckPrev EthereumSignTypedData EthereumTypedData
|
TxAckInput TxAckOutput TxAckPrev \
|
||||||
|
EthereumSignTypedData EthereumTypedDataStructRequest EthereumTypedDataStructAck \
|
||||||
|
EthereumTypedDataValueRequest EthereumTypedDataValueAck
|
||||||
|
|
||||||
ifeq ($(BITCOIN_ONLY), 1)
|
ifeq ($(BITCOIN_ONLY), 1)
|
||||||
SKIPPED_MESSAGES += Ethereum NEM Stellar
|
SKIPPED_MESSAGES += Ethereum NEM Stellar
|
||||||
|
@ -34,6 +34,13 @@ EthereumVerifyMessage.message max_size:1024
|
|||||||
EthereumMessageSignature.address max_size:43
|
EthereumMessageSignature.address max_size:43
|
||||||
EthereumMessageSignature.signature max_size:65
|
EthereumMessageSignature.signature max_size:65
|
||||||
|
|
||||||
|
EthereumSignTypedHash.address_n max_count:8
|
||||||
|
EthereumSignTypedHash.domain_separator_hash max_size:32
|
||||||
|
EthereumSignTypedHash.message_hash max_size:32
|
||||||
|
|
||||||
|
EthereumTypedDataSignature.address max_size:43
|
||||||
|
EthereumTypedDataSignature.signature max_size:65
|
||||||
|
|
||||||
EthereumGetAddress.address_n max_count:8
|
EthereumGetAddress.address_n max_count:8
|
||||||
EthereumGetPublicKey.address_n max_count:8
|
EthereumGetPublicKey.address_n max_count:8
|
||||||
|
|
||||||
|
1
python/.changelog.d/1970.added
Normal file
1
python/.changelog.d/1970.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add support for blind EIP-712 signing for Trezor One
|
@ -441,3 +441,29 @@ def verify_message(
|
|||||||
"""Verify message signed with Ethereum address."""
|
"""Verify message signed with Ethereum address."""
|
||||||
signature_bytes = ethereum.decode_hex(signature)
|
signature_bytes = ethereum.decode_hex(signature)
|
||||||
return ethereum.verify_message(client, address, signature_bytes, message)
|
return ethereum.verify_message(client, address, signature_bytes, message)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@click.option("-n", "--address", required=True, help=PATH_HELP)
|
||||||
|
@click.argument("domain_hash_hex")
|
||||||
|
@click.argument("message_hash_hex")
|
||||||
|
@with_client
|
||||||
|
def sign_typed_data_hash(
|
||||||
|
client: "TrezorClient", address: str, domain_hash_hex: str, message_hash_hex: str
|
||||||
|
) -> Dict[str, str]:
|
||||||
|
"""
|
||||||
|
Sign hash of typed data (EIP-712) with Ethereum address.
|
||||||
|
|
||||||
|
For T1 backward compatibility.
|
||||||
|
"""
|
||||||
|
address_n = tools.parse_path(address)
|
||||||
|
domain_hash = ethereum.decode_hex(domain_hash_hex)
|
||||||
|
message_hash = ethereum.decode_hex(message_hash_hex)
|
||||||
|
ret = ethereum.sign_typed_data_hash(client, address_n, domain_hash, message_hash)
|
||||||
|
output = {
|
||||||
|
"domain_hash": domain_hash_hex,
|
||||||
|
"message_hash": message_hash_hex,
|
||||||
|
"address": ret.address,
|
||||||
|
"signature": f"0x{ret.signature.hex()}",
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
@ -357,3 +357,16 @@ def verify_message(
|
|||||||
except exceptions.TrezorFailure:
|
except exceptions.TrezorFailure:
|
||||||
return False
|
return False
|
||||||
return isinstance(resp, messages.Success)
|
return isinstance(resp, messages.Success)
|
||||||
|
|
||||||
|
|
||||||
|
@expect(messages.EthereumTypedDataSignature)
|
||||||
|
def sign_typed_data_hash(
|
||||||
|
client: "TrezorClient", n: "Address", domain_hash: bytes, message_hash: bytes
|
||||||
|
) -> "MessageType":
|
||||||
|
return client.call(
|
||||||
|
messages.EthereumSignTypedHash(
|
||||||
|
address_n=n,
|
||||||
|
domain_separator_hash=domain_hash,
|
||||||
|
message_hash=message_hash,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -129,6 +129,7 @@ class MessageType(IntEnum):
|
|||||||
EthereumTypedDataValueRequest = 467
|
EthereumTypedDataValueRequest = 467
|
||||||
EthereumTypedDataValueAck = 468
|
EthereumTypedDataValueAck = 468
|
||||||
EthereumTypedDataSignature = 469
|
EthereumTypedDataSignature = 469
|
||||||
|
EthereumSignTypedHash = 470
|
||||||
NEMGetAddress = 67
|
NEMGetAddress = 67
|
||||||
NEMAddress = 68
|
NEMAddress = 68
|
||||||
NEMSignTx = 69
|
NEMSignTx = 69
|
||||||
@ -4455,23 +4456,6 @@ class EthereumTypedDataValueAck(protobuf.MessageType):
|
|||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
class EthereumTypedDataSignature(protobuf.MessageType):
|
|
||||||
MESSAGE_WIRE_TYPE = 469
|
|
||||||
FIELDS = {
|
|
||||||
1: protobuf.Field("signature", "bytes", repeated=False, required=True),
|
|
||||||
2: protobuf.Field("address", "string", repeated=False, required=True),
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
signature: "bytes",
|
|
||||||
address: "str",
|
|
||||||
) -> None:
|
|
||||||
self.signature = signature
|
|
||||||
self.address = address
|
|
||||||
|
|
||||||
|
|
||||||
class EthereumStructMember(protobuf.MessageType):
|
class EthereumStructMember(protobuf.MessageType):
|
||||||
MESSAGE_WIRE_TYPE = None
|
MESSAGE_WIRE_TYPE = None
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
@ -4756,6 +4740,43 @@ class EthereumVerifyMessage(protobuf.MessageType):
|
|||||||
self.address = address
|
self.address = address
|
||||||
|
|
||||||
|
|
||||||
|
class EthereumSignTypedHash(protobuf.MessageType):
|
||||||
|
MESSAGE_WIRE_TYPE = 470
|
||||||
|
FIELDS = {
|
||||||
|
1: protobuf.Field("address_n", "uint32", repeated=True, required=False),
|
||||||
|
2: protobuf.Field("domain_separator_hash", "bytes", repeated=False, required=True),
|
||||||
|
3: protobuf.Field("message_hash", "bytes", repeated=False, required=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
domain_separator_hash: "bytes",
|
||||||
|
message_hash: "bytes",
|
||||||
|
address_n: Optional[Sequence["int"]] = None,
|
||||||
|
) -> None:
|
||||||
|
self.address_n: Sequence["int"] = address_n if address_n is not None else []
|
||||||
|
self.domain_separator_hash = domain_separator_hash
|
||||||
|
self.message_hash = message_hash
|
||||||
|
|
||||||
|
|
||||||
|
class EthereumTypedDataSignature(protobuf.MessageType):
|
||||||
|
MESSAGE_WIRE_TYPE = 469
|
||||||
|
FIELDS = {
|
||||||
|
1: protobuf.Field("signature", "bytes", repeated=False, required=True),
|
||||||
|
2: protobuf.Field("address", "string", repeated=False, required=True),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
signature: "bytes",
|
||||||
|
address: "str",
|
||||||
|
) -> None:
|
||||||
|
self.signature = signature
|
||||||
|
self.address = address
|
||||||
|
|
||||||
|
|
||||||
class EthereumAccessList(protobuf.MessageType):
|
class EthereumAccessList(protobuf.MessageType):
|
||||||
MESSAGE_WIRE_TYPE = None
|
MESSAGE_WIRE_TYPE = None
|
||||||
FIELDS = {
|
FIELDS = {
|
||||||
|
Loading…
Reference in New Issue
Block a user