Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 39 additions & 11 deletions keepkeylib/erc7730_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,31 @@ def intern_path(steps):
literals.append((9, _u16(len(references)) + b"".join(
_u16(index) for index in references)))
arguments.append((22, 2, len(literals) - 1))
elif kind == 4:
collection = params.get("collectionPath")
if collection is None:
collection = params.get("collection")
collection = descriptor_value(collection)
if isinstance(collection, str) and collection.startswith("0x"):
literals.append((5, _hex_address(collection)))
collection_path = intern_path(
(("literal", len(literals) - 1),))
elif isinstance(collection, str):
collection_path = intern_path(_resolve_path(root, collection))
else:
raise ValueError("nftName requires collection or collectionPath")
arguments.append((3, 1, collection_path))
chain = params.get("chainIdPath", params.get("chainId"))
if chain is not None:
chain = descriptor_value(chain)
if isinstance(chain, int):
literals.append((7, _unsigned_literal(chain)))
arguments.append((11, 2, len(literals) - 1))
elif isinstance(chain, str):
arguments.append((11, 1,
intern_path(_resolve_path(root, chain))))
else:
raise ValueError("invalid nftName chainId")
elif kind == 5:
encoding = params.get("encoding", "timestamp")
arguments.append((9, 3, string_index[encoding]))
Expand Down Expand Up @@ -704,21 +729,24 @@ def intern_path(steps):
value_path, len(literals) - 1))
all_positions = [i for i, step in enumerate(steps)
if step[0] == 2]
if len(all_positions) > 1:
raise ValueError("nested array iteration requires a field group")
if all_positions:
prefix = steps[:all_positions[0]]
array_path = intern_path(prefix)
begin = len(displays)
displays.append([7, array_path, condition, 0])
begins = []
for position in all_positions:
array_path = intern_path(steps[:position + 1])
begin = len(displays)
begins.append(begin)
displays.append([7, array_path, condition, 0])
displays.append([4, string_index[field["label"]],
formatter_index, ABSENT])
end = len(displays)
separator = field.get("separator")
displays.append([8, begin,
string_index[separator] if separator else ABSENT,
ABSENT])
displays[begin][3] = end
for depth, begin in enumerate(reversed(begins)):
end = len(displays)
displays.append([
8, begin,
(string_index[separator]
if separator and depth == len(begins) - 1 else ABSENT),
ABSENT])
displays[begin][3] = end
else:
displays.append([4, string_index[field["label"]],
formatter_index, condition])
Expand Down
25 changes: 25 additions & 0 deletions tests/test_erc7730_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,31 @@ def test_compiles_array_iteration_separator_and_optional_visibility():
subprocess.check_call([validator, output.name])


def test_compiles_recursive_array_iteration_frames():
descriptor = {"display": {"formats": {
"matrix(uint256[][] values)": {
"intent": "Review matrix",
"fields": [{"path": "values.[].[]", "label": "Value",
"format": "raw", "separator": "Next row"}],
}
}}}
compiled = compile_calldata(
descriptor, "matrix(uint256[][] values)", 1,
"0x1111111111111111111111111111111111111111")
display = _sections(compiled)[7]
count = int.from_bytes(display[:2], "big")
instructions = [display[2 + i * 8:10 + i * 8] for i in range(count)]
assert [item[0] for item in instructions] == [1, 7, 7, 4, 8, 8, 10]
assert int.from_bytes(instructions[1][6:8], "big") == 5
assert int.from_bytes(instructions[2][6:8], "big") == 4
validator = os.environ.get("ERC7730_FIRMWARE_VALIDATOR")
if validator:
with tempfile.NamedTemporaryFile() as output:
output.write(compiled)
output.flush()
subprocess.check_call([validator, output.name])


def test_compiles_typed_if_not_in_and_must_match_conditions():
descriptor = {"display": {"formats": {
"guard(uint256 mode,address recipient)": {
Expand Down