EIP712 feeder script ragger support
This commit is contained in:
387
tests/ragger/eip712/InputData.py
Normal file
387
tests/ragger/eip712/InputData.py
Normal file
@@ -0,0 +1,387 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
from enum import IntEnum, auto
|
||||
import hashlib
|
||||
from ecdsa import SigningKey
|
||||
from ecdsa.util import sigencode_der
|
||||
import pdb
|
||||
from ethereum_client import EthereumClient, EIP712FieldType
|
||||
|
||||
# global variables
|
||||
app_client: EthereumClient = None
|
||||
parser = None
|
||||
trans = None
|
||||
filtering_paths = None
|
||||
current_path = list()
|
||||
sig_ctx = {}
|
||||
|
||||
|
||||
class ArrayType(IntEnum):
|
||||
dynamic = 0
|
||||
fixed_size = auto()
|
||||
|
||||
|
||||
|
||||
# From a string typename, extract the type and all the array depth
|
||||
# Input = "uint8[2][][4]" | "bool"
|
||||
# Output = ('uint8', [2, None, 4]) | ('bool', [])
|
||||
def get_array_levels(typename):
|
||||
array_lvls = list()
|
||||
regex = re.compile("(.*)\[([0-9]*)\]$")
|
||||
|
||||
while True:
|
||||
result = regex.search(typename)
|
||||
if not result:
|
||||
break
|
||||
typename = result.group(1)
|
||||
|
||||
level_size = result.group(2)
|
||||
if len(level_size) == 0:
|
||||
level_size = None
|
||||
else:
|
||||
level_size = int(level_size)
|
||||
array_lvls.insert(0, level_size)
|
||||
return (typename, array_lvls)
|
||||
|
||||
|
||||
# From a string typename, extract the type and its size
|
||||
# Input = "uint64" | "string"
|
||||
# Output = ('uint', 64) | ('string', None)
|
||||
def get_typesize(typename):
|
||||
regex = re.compile("^(\w+?)(\d*)$")
|
||||
result = regex.search(typename)
|
||||
typename = result.group(1)
|
||||
typesize = result.group(2)
|
||||
if len(typesize) == 0:
|
||||
typesize = None
|
||||
else:
|
||||
typesize = int(typesize)
|
||||
return (typename, typesize)
|
||||
|
||||
|
||||
|
||||
def parse_int(typesize):
|
||||
return (EIP712FieldType.INT, int(typesize / 8))
|
||||
|
||||
def parse_uint(typesize):
|
||||
return (EIP712FieldType.UINT, int(typesize / 8))
|
||||
|
||||
def parse_address(typesize):
|
||||
return (EIP712FieldType.ADDRESS, None)
|
||||
|
||||
def parse_bool(typesize):
|
||||
return (EIP712FieldType.BOOL, None)
|
||||
|
||||
def parse_string(typesize):
|
||||
return (EIP712FieldType.STRING, None)
|
||||
|
||||
def parse_bytes(typesize):
|
||||
if typesize != None:
|
||||
return (EIP712FieldType.FIX_BYTES, typesize)
|
||||
return (EIP712FieldType.DYN_BYTES, None)
|
||||
|
||||
# set functions for each type
|
||||
parsing_type_functions = {};
|
||||
parsing_type_functions["int"] = parse_int
|
||||
parsing_type_functions["uint"] = parse_uint
|
||||
parsing_type_functions["address"] = parse_address
|
||||
parsing_type_functions["bool"] = parse_bool
|
||||
parsing_type_functions["string"] = parse_string
|
||||
parsing_type_functions["bytes"] = parse_bytes
|
||||
|
||||
|
||||
|
||||
def send_struct_def_field(typename, keyname):
|
||||
type_enum = None
|
||||
|
||||
(typename, array_lvls) = get_array_levels(typename)
|
||||
(typename, typesize) = get_typesize(typename)
|
||||
|
||||
if typename in parsing_type_functions.keys():
|
||||
(type_enum, typesize) = parsing_type_functions[typename](typesize)
|
||||
else:
|
||||
type_enum = EIP712FieldType.CUSTOM
|
||||
typesize = None
|
||||
|
||||
app_client.eip712_send_struct_def_struct_field(type_enum,
|
||||
typename,
|
||||
typesize,
|
||||
array_lvls,
|
||||
keyname)
|
||||
return (typename, type_enum, typesize, array_lvls)
|
||||
|
||||
|
||||
|
||||
def encode_integer(value, typesize):
|
||||
data = bytearray()
|
||||
|
||||
# Some are already represented as integers in the JSON, but most as strings
|
||||
if isinstance(value, str):
|
||||
base = 10
|
||||
if value.startswith("0x"):
|
||||
base = 16
|
||||
value = int(value, base)
|
||||
|
||||
if value == 0:
|
||||
data.append(0)
|
||||
else:
|
||||
if value < 0: # negative number, send it as unsigned
|
||||
mask = 0
|
||||
for i in range(typesize): # make a mask as big as the typesize
|
||||
mask = (mask << 8) | 0xff
|
||||
value &= mask
|
||||
while value > 0:
|
||||
data.append(value & 0xff)
|
||||
value >>= 8
|
||||
data.reverse()
|
||||
return data
|
||||
|
||||
def encode_int(value, typesize):
|
||||
return encode_integer(value, typesize)
|
||||
|
||||
def encode_uint(value, typesize):
|
||||
return encode_integer(value, typesize)
|
||||
|
||||
def encode_hex_string(value, size):
|
||||
data = bytearray()
|
||||
value = value[2:] # skip 0x
|
||||
byte_idx = 0
|
||||
while byte_idx < size:
|
||||
data.append(int(value[(byte_idx * 2):(byte_idx * 2 + 2)], 16))
|
||||
byte_idx += 1
|
||||
return data
|
||||
|
||||
def encode_address(value, typesize):
|
||||
return encode_hex_string(value, 20)
|
||||
|
||||
def encode_bool(value, typesize):
|
||||
return encode_integer(value, typesize)
|
||||
|
||||
def encode_string(value, typesize):
|
||||
data = bytearray()
|
||||
for char in value:
|
||||
data.append(ord(char))
|
||||
return data
|
||||
|
||||
def encode_byte(value, typesize):
|
||||
return bytearray()
|
||||
|
||||
def encode_bytes_fix(value, typesize):
|
||||
return encode_hex_string(value, typesize)
|
||||
|
||||
def encode_bytes_dyn(value, typesize):
|
||||
# length of the value string
|
||||
# - the length of 0x (2)
|
||||
# / by the length of one byte in a hex string (2)
|
||||
return encode_hex_string(value, int((len(value) - 2) / 2))
|
||||
|
||||
# set functions for each type
|
||||
encoding_functions = {}
|
||||
encoding_functions[EIP712FieldType.INT] = encode_int
|
||||
encoding_functions[EIP712FieldType.UINT] = encode_uint
|
||||
encoding_functions[EIP712FieldType.ADDRESS] = encode_address
|
||||
encoding_functions[EIP712FieldType.BOOL] = encode_bool
|
||||
encoding_functions[EIP712FieldType.STRING] = encode_string
|
||||
encoding_functions[EIP712FieldType.FIX_BYTES] = encode_bytes_fix
|
||||
encoding_functions[EIP712FieldType.DYN_BYTES] = encode_bytes_dyn
|
||||
|
||||
|
||||
|
||||
def send_struct_impl_field(value, field):
|
||||
# Something wrong happened if this triggers
|
||||
if isinstance(value, list) or (field["enum"] == EIP712FieldType.CUSTOM):
|
||||
breakpoint()
|
||||
|
||||
data = encoding_functions[field["enum"]](value, field["typesize"])
|
||||
|
||||
|
||||
if False:#args.filtering:
|
||||
path = ".".join(current_path)
|
||||
if path in filtering_paths.keys():
|
||||
send_filtering_field_name(filtering_paths[path])
|
||||
|
||||
app_client.eip712_send_struct_impl_struct_field(data)
|
||||
|
||||
|
||||
|
||||
def evaluate_field(structs, data, field, lvls_left, new_level = True):
|
||||
array_lvls = field["array_lvls"]
|
||||
|
||||
if new_level:
|
||||
current_path.append(field["name"])
|
||||
if len(array_lvls) > 0 and lvls_left > 0:
|
||||
app_client.eip712_send_struct_impl_array(len(data))
|
||||
idx = 0
|
||||
for subdata in data:
|
||||
current_path.append("[]")
|
||||
if not evaluate_field(structs, subdata, field, lvls_left - 1, False):
|
||||
return False
|
||||
current_path.pop()
|
||||
idx += 1
|
||||
if array_lvls[lvls_left - 1] != None:
|
||||
if array_lvls[lvls_left - 1] != idx:
|
||||
print("Mismatch in array size! Got %d, expected %d\n" %
|
||||
(idx, array_lvls[lvls_left - 1]),
|
||||
file=sys.stderr)
|
||||
return False
|
||||
else:
|
||||
if field["enum"] == EIP712FieldType.CUSTOM:
|
||||
if not send_struct_impl(structs, data, field["type"]):
|
||||
return False
|
||||
else:
|
||||
send_struct_impl_field(data, field)
|
||||
if new_level:
|
||||
current_path.pop()
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def send_struct_impl(structs, data, structname):
|
||||
# Check if it is a struct we don't known
|
||||
if structname not in structs.keys():
|
||||
return False
|
||||
|
||||
struct = structs[structname]
|
||||
for f in struct:
|
||||
if not evaluate_field(structs, data[f["name"]], f, len(f["array_lvls"])):
|
||||
return False
|
||||
return True
|
||||
|
||||
def send_sign():
|
||||
bip32path = bytearray.fromhex("8000002c8000003c800000000000000000000000")
|
||||
path_len = bytearray()
|
||||
path_len.append(int(len(bip32path) / 4))
|
||||
#send_apdu(INS_SIGN, 0x00, P2_VERS_NEW, path_len + bip32path)
|
||||
print("send_apdu(INS_SIGN, 0x00, P2_VERS_NEW, path_len + bip32path)")
|
||||
|
||||
def send_filtering_activate():
|
||||
#send_apdu(INS_FILTERING, P1_ACTIVATE, 0x00, bytearray())
|
||||
print("send_apdu(INS_FILTERING, P1_ACTIVATE, 0x00, bytearray())")
|
||||
|
||||
def send_filtering_info(p1, display_name, sig):
|
||||
payload = bytearray()
|
||||
payload.append(len(display_name))
|
||||
for char in display_name:
|
||||
payload.append(ord(char))
|
||||
payload.append(len(sig))
|
||||
payload += sig
|
||||
#send_apdu(INS_FILTERING, p1, 0x00, payload)
|
||||
print("send_apdu(INS_FILTERING, p1, 0x00, payload)")
|
||||
|
||||
# ledgerjs doesn't actually sign anything, and instead uses already pre-computed signatures
|
||||
def send_filtering_contract_name(display_name):
|
||||
global sig_ctx
|
||||
|
||||
msg = bytearray()
|
||||
msg += sig_ctx["chainid"]
|
||||
msg += sig_ctx["caddr"]
|
||||
msg += sig_ctx["schema_hash"]
|
||||
for char in display_name:
|
||||
msg.append(ord(char))
|
||||
|
||||
sig = sig_ctx["key"].sign_deterministic(msg, sigencode=sigencode_der)
|
||||
send_filtering_info(P1_CONTRACT_NAME, display_name, sig)
|
||||
|
||||
# ledgerjs doesn't actually sign anything, and instead uses already pre-computed signatures
|
||||
def send_filtering_field_name(display_name):
|
||||
global sig_ctx
|
||||
|
||||
path_str = ".".join(current_path)
|
||||
|
||||
msg = bytearray()
|
||||
msg += sig_ctx["chainid"]
|
||||
msg += sig_ctx["caddr"]
|
||||
msg += sig_ctx["schema_hash"]
|
||||
for char in path_str:
|
||||
msg.append(ord(char))
|
||||
for char in display_name:
|
||||
msg.append(ord(char))
|
||||
sig = sig_ctx["key"].sign_deterministic(msg, sigencode=sigencode_der)
|
||||
send_filtering_info(P1_FIELD_NAME, display_name, sig)
|
||||
|
||||
def read_filtering_file(domain, message):
|
||||
data_json = None
|
||||
with open("%s-filter.json" % (args.JSON_FILE)) as data:
|
||||
data_json = json.load(data)
|
||||
return data_json
|
||||
|
||||
def prepare_filtering(filtr_data, message):
|
||||
global filtering_paths
|
||||
|
||||
if "fields" in filtr_data:
|
||||
filtering_paths = filtr_data["fields"]
|
||||
else:
|
||||
filtering_paths = {}
|
||||
|
||||
def init_signature_context(types, domain):
|
||||
global sig_ctx
|
||||
|
||||
with open(args.keypath, "r") as priv_file:
|
||||
sig_ctx["key"] = SigningKey.from_pem(priv_file.read(), hashlib.sha256)
|
||||
caddr = domain["verifyingContract"]
|
||||
if caddr.startswith("0x"):
|
||||
caddr = caddr[2:]
|
||||
sig_ctx["caddr"] = bytearray.fromhex(caddr)
|
||||
chainid = domain["chainId"]
|
||||
sig_ctx["chainid"] = bytearray()
|
||||
for i in range(8):
|
||||
sig_ctx["chainid"].append(chainid & (0xff << (i * 8)))
|
||||
sig_ctx["chainid"].reverse()
|
||||
schema_str = json.dumps(types).replace(" ","")
|
||||
schema_hash = hashlib.sha224(schema_str.encode())
|
||||
sig_ctx["schema_hash"] = bytearray.fromhex(schema_hash.hexdigest())
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
def process_file(aclient: EthereumClient, input_file_path: str, filtering = False) -> bool:
|
||||
global sig_ctx
|
||||
global app_client
|
||||
|
||||
app_client = aclient
|
||||
with open(input_file_path, "r") as data:
|
||||
data_json = json.load(data)
|
||||
domain_typename = "EIP712Domain"
|
||||
message_typename = data_json["primaryType"]
|
||||
types = data_json["types"]
|
||||
domain = data_json["domain"]
|
||||
message = data_json["message"]
|
||||
|
||||
if filtering:
|
||||
if not init_signature_context(types, domain):
|
||||
return False
|
||||
filtr = read_filtering_file(domain, message)
|
||||
|
||||
# send types definition
|
||||
for key in types.keys():
|
||||
app_client.eip712_send_struct_def_struct_name(key)
|
||||
for f in types[key]:
|
||||
(f["type"], f["enum"], f["typesize"], f["array_lvls"]) = \
|
||||
send_struct_def_field(f["type"], f["name"])
|
||||
|
||||
if filtering:
|
||||
send_filtering_activate()
|
||||
prepare_filtering(filtr, message)
|
||||
|
||||
# send domain implementation
|
||||
app_client.eip712_send_struct_impl_root_struct(domain_typename)
|
||||
if not send_struct_impl(types, domain, domain_typename):
|
||||
return False
|
||||
|
||||
if filtering:
|
||||
if filtr and "name" in filtr:
|
||||
send_filtering_contract_name(filtr["name"])
|
||||
else:
|
||||
send_filtering_contract_name(sig_ctx["domain"]["name"])
|
||||
|
||||
# send message implementation
|
||||
app_client.eip712_send_struct_impl_root_struct(message_typename)
|
||||
if not send_struct_impl(types, message, message_typename):
|
||||
return False
|
||||
|
||||
# sign
|
||||
send_sign()
|
||||
return True
|
||||
0
tests/ragger/eip712/__init__.py
Normal file
0
tests/ragger/eip712/__init__.py
Normal file
44
tests/ragger/eip712/input_files/00-simple_mail-test.json
Normal file
44
tests/ragger/eip712/input_files/00-simple_mail-test.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "Hello, Bob!",
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallets": [
|
||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
|
||||
]
|
||||
},
|
||||
"to": {
|
||||
"name": "Bob",
|
||||
"wallets": [
|
||||
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
|
||||
"0xB0B0b0b0b0b0B000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "Person" },
|
||||
{ "name": "contents", "type": "string" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallets", "type": "address[]" }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 1337,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "Hello, Bob!",
|
||||
"from": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"to": [
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
|
||||
"0xb1a22cc48f6784f629a994917cd6474923630c48"
|
||||
],
|
||||
"id": 7
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "address" },
|
||||
{ "name": "to", "type": "address[]" },
|
||||
{ "name": "contents", "type": "string" }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "Hello, Bob!",
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallets": [
|
||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
|
||||
]
|
||||
},
|
||||
"to": [
|
||||
{
|
||||
"name": "Alice",
|
||||
"wallets": [
|
||||
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
||||
"0xB0B0b0b0b0b0B000000000000000000000000000"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Bob",
|
||||
"wallets": [
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Group": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "members", "type": "Person[]" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "Person[]" },
|
||||
{ "name": "contents", "type": "string" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallets", "type": "address[]" }
|
||||
]
|
||||
}
|
||||
}
|
||||
50
tests/ragger/eip712/input_files/03-long_string-test.json
Normal file
50
tests/ragger/eip712/input_files/03-long_string-test.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "Hello, Bob! 012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012312345678012345678012345678012345678012344444444444444444444123456780123456780123456780123456780123456780123456780123456789999999999999999999999999999990123456789",
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallets": [
|
||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
|
||||
]
|
||||
},
|
||||
"to": [
|
||||
{
|
||||
"name": "Bob",
|
||||
"wallets": [
|
||||
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
|
||||
"0xB0B0b0b0b0b0B000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Group": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "members", "type": "Person[]" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "Person[]" },
|
||||
{ "name": "contents", "type": "string" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallets", "type": "address[]" }
|
||||
]
|
||||
}
|
||||
}
|
||||
50
tests/ragger/eip712/input_files/04-long_bytes-test.json
Normal file
50
tests/ragger/eip712/input_files/04-long_bytes-test.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "0x1123456789123456789123453678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678912345678991234567892345678991234567892345678991234567892345678991234567892345678991234567892345678912345678923456789",
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallets": [
|
||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
|
||||
]
|
||||
},
|
||||
"to": [
|
||||
{
|
||||
"name": "Bob",
|
||||
"wallets": [
|
||||
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57",
|
||||
"0xB0B0b0b0b0b0B000000000000000000000000000"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Group": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "members", "type": "Person[]" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "Person[]" },
|
||||
{ "name": "contents", "type": "bytes" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallets", "type": "address[]" }
|
||||
]
|
||||
}
|
||||
}
|
||||
45
tests/ragger/eip712/input_files/05-signed_ints-test.json
Normal file
45
tests/ragger/eip712/input_files/05-signed_ints-test.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"neg256" : "-256",
|
||||
"pos256" : "256",
|
||||
"neg128" : "-128",
|
||||
"pos128" : "128",
|
||||
"neg64" : "-64",
|
||||
"pos64" : "64",
|
||||
"neg32" : "-32",
|
||||
"pos32" : "32",
|
||||
"neg16" : "-16",
|
||||
"pos16" : "16",
|
||||
"neg8" : "-8",
|
||||
"pos8" : "8"
|
||||
},
|
||||
"primaryType": "Test",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Test": [
|
||||
{ "name": "neg256", "type": "int256" },
|
||||
{ "name": "pos256", "type": "int256" },
|
||||
{ "name": "neg128", "type": "int128" },
|
||||
{ "name": "pos128", "type": "int128" },
|
||||
{ "name": "neg64", "type": "int64" },
|
||||
{ "name": "pos64", "type": "int64" },
|
||||
{ "name": "neg32", "type": "int32" },
|
||||
{ "name": "pos32", "type": "int32" },
|
||||
{ "name": "neg16", "type": "int16" },
|
||||
{ "name": "pos16", "type": "int16" },
|
||||
{ "name": "neg8", "type": "int8" },
|
||||
{ "name": "pos8", "type": "int8" }
|
||||
]
|
||||
}
|
||||
}
|
||||
25
tests/ragger/eip712/input_files/06-boolean-test.json
Normal file
25
tests/ragger/eip712/input_files/06-boolean-test.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"Bueno" : true,
|
||||
"NoBueno": false
|
||||
},
|
||||
"primaryType": "Test",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Test": [
|
||||
{ "name": "Bueno", "type": "bool" },
|
||||
{ "name": "NoBueno", "type": "bool" }
|
||||
]
|
||||
}
|
||||
}
|
||||
23
tests/ragger/eip712/input_files/07-fixed_bytes-test.json
Normal file
23
tests/ragger/eip712/input_files/07-fixed_bytes-test.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"val" : "0x973bb640"
|
||||
},
|
||||
"primaryType": "Test",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Test": [
|
||||
{ "name": "val", "type": "bytes4" }
|
||||
]
|
||||
}
|
||||
}
|
||||
153
tests/ragger/eip712/input_files/08-opensea-test.json
Normal file
153
tests/ragger/eip712/input_files/08-opensea-test.json
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"domain" : {
|
||||
"chainId" : 1,
|
||||
"name" : "Wyvern Exchange Contract",
|
||||
"verifyingContract" : "0x7f268357a8c2552623316e2562d90e642bb538e5",
|
||||
"version" : "2.3"
|
||||
},
|
||||
"message" : {
|
||||
"basePrice" : "2000000000000000000",
|
||||
"calldata" : "0x96809f90000000000000000000000000112f0732e59e7600768dfc35ba744b89f2356cd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000495f947276749ce646f68ac8c248420045cb7b5ebdf2657ffc1fadfd73cf0a8cde95d50b62d3df8c0000000000000700000000320000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000",
|
||||
"exchange" : "0x7f268357a8c2552623316e2562d90e642bb538e5",
|
||||
"expirationTime" : "1646089435",
|
||||
"extra" : "0",
|
||||
"feeMethod" : 1,
|
||||
"feeRecipient" : "0x5b3256965e7c3cf26e11fcaf296dfc8807c01073",
|
||||
"howToCall" : 1,
|
||||
"listingTime" : "1645484541",
|
||||
"maker" : "0x112f0732e59e7600768dfc35ba744b89f2356cd8",
|
||||
"makerProtocolFee" : "0",
|
||||
"makerRelayerFee" : "1250",
|
||||
"nonce" : 0,
|
||||
"paymentToken" : "0x0000000000000000000000000000000000000000",
|
||||
"replacementPattern" : "0x000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"saleKind" : 0,
|
||||
"salt" : "21014297276898013168171430966355369260039074692095359200549020767078729356431",
|
||||
"side" : 1,
|
||||
"staticExtradata" : "0x",
|
||||
"staticTarget" : "0x0000000000000000000000000000000000000000",
|
||||
"taker" : "0x0000000000000000000000000000000000000000",
|
||||
"takerProtocolFee" : "0",
|
||||
"takerRelayerFee" : "0",
|
||||
"target" : "0xbaf2127b49fc93cbca6269fade0f7f31df4c88a7"
|
||||
},
|
||||
"primaryType" : "Order",
|
||||
"types" : {
|
||||
"EIP712Domain" : [
|
||||
{
|
||||
"name" : "name",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "version",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "chainId",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "verifyingContract",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"Order" : [
|
||||
{
|
||||
"name" : "exchange",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "maker",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "taker",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "makerRelayerFee",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "takerRelayerFee",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "makerProtocolFee",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "takerProtocolFee",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "feeRecipient",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "feeMethod",
|
||||
"type" : "uint8"
|
||||
},
|
||||
{
|
||||
"name" : "side",
|
||||
"type" : "uint8"
|
||||
},
|
||||
{
|
||||
"name" : "saleKind",
|
||||
"type" : "uint8"
|
||||
},
|
||||
{
|
||||
"name" : "target",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "howToCall",
|
||||
"type" : "uint8"
|
||||
},
|
||||
{
|
||||
"name" : "calldata",
|
||||
"type" : "bytes"
|
||||
},
|
||||
{
|
||||
"name" : "replacementPattern",
|
||||
"type" : "bytes"
|
||||
},
|
||||
{
|
||||
"name" : "staticTarget",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "staticExtradata",
|
||||
"type" : "bytes"
|
||||
},
|
||||
{
|
||||
"name" : "paymentToken",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "basePrice",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "extra",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "listingTime",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "expirationTime",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "salt",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "nonce",
|
||||
"type" : "uint256"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
110
tests/ragger/eip712/input_files/09-rarible-test.json
Normal file
110
tests/ragger/eip712/input_files/09-rarible-test.json
Normal file
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"domain" : {
|
||||
"chainId" : 1,
|
||||
"name" : "Exchange",
|
||||
"verifyingContract" : "0x9757f2d2b135150bbeb65308d4a91804107cd8d6",
|
||||
"version" : "2"
|
||||
},
|
||||
"message" : {
|
||||
"data" : "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001cf0df2a5a20cd61d68d4489eebbf85b8d39e18a00000000000000000000000000000000000000000000000000000000000000fa",
|
||||
"dataType" : "0x23d235ef",
|
||||
"end" : 0,
|
||||
"makeAsset" : {
|
||||
"assetType" : {
|
||||
"assetClass" : "0x973bb640",
|
||||
"data" : "0x000000000000000000000000495f947276749ce646f68ac8c248420045cb7b5ebdf2657ffc1fadfd73cf0a8cde95d50b62d3df8c000000000000070000000032"
|
||||
},
|
||||
"value" : "1"
|
||||
},
|
||||
"maker" : "0x112f0732e59e7600768dfc35ba744b89f2356cd8",
|
||||
"salt" : "0xdbf0f98bc1746711579dcce549a4cc4e866fb71bf2e185bfefbb7d32f325972e",
|
||||
"start" : 0,
|
||||
"takeAsset" : {
|
||||
"assetType" : {
|
||||
"assetClass" : "0xaaaebeba",
|
||||
"data" : "0x"
|
||||
},
|
||||
"value" : "2000000000000000000"
|
||||
},
|
||||
"taker" : "0x0000000000000000000000000000000000000000"
|
||||
},
|
||||
"primaryType" : "Order",
|
||||
"types" : {
|
||||
"Asset" : [
|
||||
{
|
||||
"name" : "assetType",
|
||||
"type" : "AssetType"
|
||||
},
|
||||
{
|
||||
"name" : "value",
|
||||
"type" : "uint256"
|
||||
}
|
||||
],
|
||||
"AssetType" : [
|
||||
{
|
||||
"name" : "assetClass",
|
||||
"type" : "bytes4"
|
||||
},
|
||||
{
|
||||
"name" : "data",
|
||||
"type" : "bytes"
|
||||
}
|
||||
],
|
||||
"EIP712Domain" : [
|
||||
{
|
||||
"name" : "name",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "version",
|
||||
"type" : "string"
|
||||
},
|
||||
{
|
||||
"name" : "chainId",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "verifyingContract",
|
||||
"type" : "address"
|
||||
}
|
||||
],
|
||||
"Order" : [
|
||||
{
|
||||
"name" : "maker",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "makeAsset",
|
||||
"type" : "Asset"
|
||||
},
|
||||
{
|
||||
"name" : "taker",
|
||||
"type" : "address"
|
||||
},
|
||||
{
|
||||
"name" : "takeAsset",
|
||||
"type" : "Asset"
|
||||
},
|
||||
{
|
||||
"name" : "salt",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "start",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "end",
|
||||
"type" : "uint256"
|
||||
},
|
||||
{
|
||||
"name" : "dataType",
|
||||
"type" : "bytes4"
|
||||
},
|
||||
{
|
||||
"name" : "data",
|
||||
"type" : "bytes"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "name"
|
||||
}
|
||||
],
|
||||
"LDPSigningRequest": [
|
||||
{
|
||||
"type": "string[3][]",
|
||||
"name": "document"
|
||||
},
|
||||
{
|
||||
"type": "string[][4]",
|
||||
"name": "proof"
|
||||
},
|
||||
{
|
||||
"type": "uint8[][][][]",
|
||||
"name": "depthy"
|
||||
}
|
||||
]
|
||||
},
|
||||
"primaryType": "LDPSigningRequest",
|
||||
"domain": {
|
||||
"name": "Eip712Method2021"
|
||||
},
|
||||
"message": {
|
||||
"depthy": [
|
||||
[
|
||||
[
|
||||
[
|
||||
"1",
|
||||
"2"
|
||||
],
|
||||
[
|
||||
"3"
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
"document": [
|
||||
[
|
||||
"<did:key:z6MkgFneaaMjN6zybqLNXgt4YfmVx2XZhzPdDyk4ZK81daHZ>",
|
||||
"<https://www.w3.org/TR/owl-ref/#sameAs-def>",
|
||||
"\"did:ethr:0xf7398bacf610bb4e3b567811279fcb3c41919f89\""
|
||||
],
|
||||
[
|
||||
"<urn:uuid:14ab6047-bf2d-4fde-9564-51dead126ffb>",
|
||||
"<https://www.w3.org/2018/credentials#credentialSubject>",
|
||||
"<did:key:z6MkgFneaaMjN6zybqLNXgt4YfmVx2XZhzPdDyk4ZK81daHZ>"
|
||||
],
|
||||
[
|
||||
"<urn:uuid:14ab6047-bf2d-4fde-9564-51dead126ffb>",
|
||||
"<https://www.w3.org/2018/credentials#issuanceDate>",
|
||||
"\"2021-03-04T21:08:22.615Z\"^^<http://www.w3.org/2001/XMLSchema#dateTime>"
|
||||
],
|
||||
[
|
||||
"<urn:uuid:14ab6047-bf2d-4fde-9564-51dead126ffb>",
|
||||
"<https://www.w3.org/2018/credentials#issuer>",
|
||||
"<did:ethr:0xf7398bacf610bb4e3b567811279fcb3c41919f89>"
|
||||
],
|
||||
[
|
||||
"<urn:uuid:14ab6047-bf2d-4fde-9564-51dead126ffb>",
|
||||
"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>",
|
||||
"<https://www.w3.org/2018/credentials#VerifiableCredential>"
|
||||
]
|
||||
],
|
||||
"proof": [
|
||||
[
|
||||
"_:c14n0",
|
||||
"<http://purl.org/dc/terms/created>",
|
||||
"\"2021-03-04T21:08:22.616Z\"^^<http://www.w3.org/2001/XMLSchema#dateTime>"
|
||||
],
|
||||
[
|
||||
"_:c14n0",
|
||||
"<https://w3id.org/security#proofPurpose>",
|
||||
"<https://w3id.org/security#assertionMethod>"
|
||||
],
|
||||
[
|
||||
"_:c14n0",
|
||||
"<https://w3id.org/security#verificationMethod>",
|
||||
"<did:ethr:0xf7398bacf610bb4e3b567811279fcb3c41919f89#Eip712Method2021>"
|
||||
],
|
||||
[
|
||||
"_:c14n0",
|
||||
"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>",
|
||||
"<https://w3id.org/security#Eip712Signature2021>"
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
78
tests/ragger/eip712/input_files/11-complex_structs-test.json
Normal file
78
tests/ragger/eip712/input_files/11-complex_structs-test.json
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"domain": {
|
||||
"chainId": 5,
|
||||
"name": "Ether Mail",
|
||||
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
|
||||
"version": "1"
|
||||
},
|
||||
"message": {
|
||||
"contents": "Hello, Bob!",
|
||||
"from": {
|
||||
"name": "Cow",
|
||||
"wallets": [
|
||||
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
|
||||
"0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
|
||||
]
|
||||
},
|
||||
"to": {
|
||||
"name": "test list",
|
||||
"members": [
|
||||
{
|
||||
"name": "Bob",
|
||||
"wallets": [
|
||||
"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
|
||||
"0xB0B0b0b0b0b0B000000000000000000000000000"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Alice",
|
||||
"wallets": [
|
||||
"0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"attach": {
|
||||
"list": [
|
||||
{
|
||||
"name": "first",
|
||||
"size": "100"
|
||||
},
|
||||
{
|
||||
"name": "second",
|
||||
"size": "3400"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"primaryType": "Mail",
|
||||
"types": {
|
||||
"EIP712Domain": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "version", "type": "string" },
|
||||
{ "name": "chainId", "type": "uint256" },
|
||||
{ "name": "verifyingContract", "type": "address" }
|
||||
],
|
||||
"Attachment": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "size", "type": "uint16" }
|
||||
],
|
||||
"Attachments": [
|
||||
{ "name": "list", "type": "Attachment[]" }
|
||||
],
|
||||
"MailingList": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "members", "type": "Person[]" }
|
||||
],
|
||||
"Mail": [
|
||||
{ "name": "from", "type": "Person" },
|
||||
{ "name": "to", "type": "MailingList" },
|
||||
{ "name": "contents", "type": "string" },
|
||||
{ "name": "attach", "type": "Attachments" }
|
||||
],
|
||||
"Person": [
|
||||
{ "name": "name", "type": "string" },
|
||||
{ "name": "wallets", "type": "address[]" }
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -20,14 +20,14 @@ class P2Type(IntEnum):
|
||||
LEGACY_IMPLEM = 0x00
|
||||
NEW_IMPLEM = 0x01,
|
||||
|
||||
class EIP712FieldType:
|
||||
class EIP712FieldType(IntEnum):
|
||||
CUSTOM = 0,
|
||||
INT = auto(),
|
||||
UINT = auto(),
|
||||
ADDRESS = auto(),
|
||||
BOOL = auto(),
|
||||
STRING = auto(),
|
||||
FIXED_BYTES = auto(),
|
||||
INT = auto()
|
||||
UINT = auto()
|
||||
ADDRESS = auto()
|
||||
BOOL = auto()
|
||||
STRING = auto()
|
||||
FIX_BYTES = auto()
|
||||
DYN_BYTES = auto()
|
||||
|
||||
|
||||
@@ -66,14 +66,14 @@ class EthereumClientCmdBuilder:
|
||||
data = bytearray()
|
||||
typedesc = 0
|
||||
typedesc |= (len(array_levels) > 0) << 7
|
||||
typedesc |= (type_size > 0) << 6
|
||||
typedesc |= (type_size != None) << 6
|
||||
typedesc |= field_type
|
||||
data.append(typedesc)
|
||||
if field_type == EIP712FieldType.CUSTOM:
|
||||
data.append(len(type_name))
|
||||
for char in type_name:
|
||||
data.append(ord(char))
|
||||
if type_size > 0:
|
||||
if type_size != None:
|
||||
data.append(type_size)
|
||||
if len(array_levels) > 0:
|
||||
data.append(len(array_levels))
|
||||
@@ -107,12 +107,17 @@ class EthereumClientCmdBuilder:
|
||||
data)
|
||||
|
||||
def eip712_send_struct_impl_struct_field(self, data: bytearray) -> Iterator[bytes]:
|
||||
while len(data > 0):
|
||||
# Add a 16-bit integer with the data's byte length (network byte order)
|
||||
data_w_length = bytearray()
|
||||
data_w_length.append((len(data) & 0xff00) >> 8)
|
||||
data_w_length.append(len(data) & 0x00ff)
|
||||
data_w_length += data
|
||||
while len(data_w_length) > 0:
|
||||
yield self._serialize(InsType.EIP712_SEND_STRUCT_IMPL,
|
||||
P1Type.COMPLETE_SEND,
|
||||
P2Type.STRUCT_FIELD,
|
||||
data[:0xff])
|
||||
data = data[0xff:]
|
||||
data_w_length[:0xff])
|
||||
data_w_length = data_w_length[0xff:]
|
||||
|
||||
def _format_bip32(self, bip32, data = bytearray()) -> bytearray:
|
||||
data.append(len(bip32))
|
||||
@@ -195,17 +200,14 @@ class EthereumClient:
|
||||
return self._recv()
|
||||
|
||||
def eip712_send_struct_impl_array(self, size: int):
|
||||
send._send(self._cmd_builder.eip712_send_struct_impl_array(size))
|
||||
self._send(self._cmd_builder.eip712_send_struct_impl_array(size))
|
||||
return self._recv()
|
||||
|
||||
def eip712_send_struct_impl_struct_field(self, raw_value: bytes):
|
||||
ret = None
|
||||
for apdu in self._cmd_builder.eip712_send_struct_impl_struct_field(
|
||||
InsType.EIP712_SEND_STRUCT_IMPL,
|
||||
P1Type.COMPLETE_SEND,
|
||||
P2Type.STRUCT_FIELD,
|
||||
data[:0xff]):
|
||||
for apdu in self._cmd_builder.eip712_send_struct_impl_struct_field(raw_value):
|
||||
self._send(apdu)
|
||||
# TODO: Do clicks
|
||||
ret = self._recv()
|
||||
return ret
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import fnmatch
|
||||
from ethereum_client import EthereumClient
|
||||
from eip712 import InputData
|
||||
|
||||
def test_eip712_legacy(app_client: EthereumClient):
|
||||
bip32 = [
|
||||
@@ -20,3 +21,15 @@ def test_eip712_legacy(app_client: EthereumClient):
|
||||
assert v == bytes.fromhex("1c")
|
||||
assert r == bytes.fromhex("ea66f747173762715751c889fea8722acac3fc35db2c226d37a2e58815398f64")
|
||||
assert s == bytes.fromhex("52d8ba9153de9255da220ffd36762c0b027701a3b5110f0a765f94b16a9dfb55")
|
||||
|
||||
|
||||
def test_eip712_new(app_client: EthereumClient):
|
||||
if app_client._client.firmware.device == "nanos": # not supported
|
||||
return
|
||||
|
||||
# Loop through JSON files
|
||||
for file in os.scandir("./eip712/input_files"):
|
||||
if fnmatch.fnmatch(file, "*-test.json"):
|
||||
print(file.path)
|
||||
InputData.process_file(app_client, file.path, False)
|
||||
assert 1 == 1
|
||||
|
||||
Reference in New Issue
Block a user