Source code for erc7730.lint.v2.path_schemas
"""
Utilities for computing schema paths from v2 resolved display formats.
These functions extract the set of data paths referenced by a v2 resolved format, which can then be compared against
ABI-derived paths for validation.
"""
from typing import assert_never
from erc7730.model.paths import ContainerPath, DataPath, DescriptorPath
from erc7730.model.paths.path_schemas import FormatPaths, data_path_to_schema_path
from erc7730.model.resolved.display import ResolvedValue, ResolvedValuePath
from erc7730.model.resolved.v2.display import (
ResolvedAddressNameParameters,
ResolvedCallDataParameters,
ResolvedDateParameters,
ResolvedEnumParameters,
ResolvedField,
ResolvedFieldDescription,
ResolvedFieldGroup,
ResolvedFormat,
ResolvedInteroperableAddressNameParameters,
ResolvedNftNameParameters,
ResolvedTokenAmountParameters,
ResolvedTokenTickerParameters,
ResolvedUnitParameters,
)
[docs]
def compute_format_schema_paths(fmt: ResolvedFormat) -> FormatPaths:
"""
Compute the sets of schema paths referred in a v2 ERC7730 Format section.
:param fmt: resolved v2 $.display.format section
:return: schema paths used by field formats
"""
data_paths: set[DataPath] = set()
container_paths: set[ContainerPath] = set()
def add_path(path: DescriptorPath | DataPath | ContainerPath | None) -> None:
if path is None:
return
match path:
case ContainerPath():
container_paths.add(path)
case DataPath():
data_paths.add(data_path_to_schema_path(path))
case DescriptorPath():
pass # descriptor paths are not schema paths
def add_value(value: ResolvedValue | None) -> None:
if isinstance(value, ResolvedValuePath):
add_path(value.path)
def append_field(field: ResolvedField) -> None:
match field:
case ResolvedFieldDescription():
# Add the field's own path
if field.path is not None:
add_path(field.path)
# Add paths from parameters
match field.params:
case None:
pass
case ResolvedAddressNameParameters():
pass
case ResolvedInteroperableAddressNameParameters():
pass
case ResolvedCallDataParameters():
add_value(field.params.callee)
add_value(field.params.selector)
add_value(field.params.amount)
add_value(field.params.spender)
case ResolvedTokenAmountParameters():
if isinstance(field.params.token, ResolvedValuePath):
add_path(field.params.token.path)
add_path(field.params.chainIdPath)
case ResolvedTokenTickerParameters():
add_path(field.params.chainIdPath)
case ResolvedNftNameParameters():
add_value(field.params.collection)
case ResolvedDateParameters():
pass
case ResolvedUnitParameters():
pass
case ResolvedEnumParameters():
pass
case _:
assert_never(field.params)
case ResolvedFieldGroup():
for sub_field in field.fields:
append_field(sub_field)
case _:
assert_never(field)
for field in fmt.fields:
append_field(field)
return FormatPaths(data_paths=data_paths, container_paths=container_paths)