Source code for erc7730.model.calldata.v1.value

"""
Data model for calldata descriptor references to values (a.k.a., binary paths).

These model classes represent the exact same data fields that are serialized into TLV structs.
See documentation in https://github.com/LedgerHQ/app-ethereum for specifications of this protocol
"""

from enum import IntEnum
from typing import Annotated, Literal

from pydantic import Discriminator, Field

from erc7730.common.pydantic import pydantic_enum_by_name
from erc7730.model.base import Model
from erc7730.model.calldata.v1.struct import (
    CalldataDescriptorStructV1,
)
from erc7730.model.resolved.path import ResolvedPath
from erc7730.model.types import HexStr, ScalarType


[docs] @pydantic_enum_by_name class CalldataDescriptorPathElementType(IntEnum): """Type of path element.""" TUPLE = 0x01 """move by {value} slots from current slot""" ARRAY = 0x02 """current slot is array length, added to offset if negative. multiple by item_size and move by result slots""" REF = 0x03 """read value of current slot. apply read value as offset from current slot""" LEAF = 0x04 """current slot is a leaf type, specifying the type of path end""" SLICE = 0x05 """specify slicing to apply to final leaf value as (start, end)"""
[docs] @pydantic_enum_by_name class CalldataDescriptorPathLeafType(IntEnum): """Type of path leaf element.""" ARRAY_LEAF = 0x01 """final offset is start of array encoding""" TUPLE_LEAF = 0x02 """final offset is start of tuple encoding""" STATIC_LEAF = 0x03 """final offset contains static encoded value (typ data on 32 bytes)""" DYNAMIC_LEAF = 0x04 """final offset contains dynamic encoded value (typ length + data)"""
[docs] @pydantic_enum_by_name class CalldataDescriptorTypeFamily(IntEnum): """Type family of a value.""" UINT = 0x01 INT = 0x02 UFIXED = 0x03 FIXED = 0x04 ADDRESS = 0x05 BOOL = 0x06 BYTES = 0x07 STRING = 0x08
[docs] @pydantic_enum_by_name class CalldataDescriptorContainerPathValueV1(IntEnum): """Type of container paths.""" FROM = 0x0 TO = 0x1 VALUE = 0x2
[docs] class CalldataDescriptorPathElementBaseV1(Model): """Descriptor for the PATH_ELEMENT payload."""
[docs] class CalldataDescriptorPathElementTupleV1(CalldataDescriptorPathElementBaseV1): """Descriptor for the PATH_ELEMENT struct of type TUPLE.""" type: Literal["TUPLE"] = Field( default="TUPLE", title="Parameter type", description="Type of the parameter", ) offset: int = Field( title="Index", description="Move by {value} slots from current slot", )
[docs] class CalldataDescriptorPathElementArrayV1(CalldataDescriptorPathElementBaseV1): """Descriptor for the PATH_ELEMENT struct of type ARRAY.""" type: Literal["ARRAY"] = Field( default="ARRAY", title="Parameter type", description="Type of the parameter", ) weight: int = Field( title="Item size", description="Size of each array element in chunks", ) start: int | None = Field( title="Start", description="Start offset in array (inclusive). If not provided, lower bound is array start.", ) end: int | None = Field( title="End", description="End offset in array (exclusive). If not provided, upper bound is array end.", )
[docs] class CalldataDescriptorPathElementRefV1(CalldataDescriptorPathElementBaseV1): """Descriptor for the PATH_ELEMENT struct of type REF.""" type: Literal["REF"] = Field( default="REF", title="Parameter type", description="Type of the parameter", )
[docs] class CalldataDescriptorPathElementLeafV1(CalldataDescriptorPathElementBaseV1): """Descriptor for the PATH_ELEMENT struct of type LEAF.""" type: Literal["LEAF"] = Field( default="LEAF", title="Parameter type", description="Type of the parameter", ) leaf_type: CalldataDescriptorPathLeafType = Field( title="Leaf type", description="Type of the leaf element", )
[docs] class CalldataDescriptorPathElementSliceV1(CalldataDescriptorPathElementBaseV1): """Descriptor for the PATH_ELEMENT struct of type SLICE.""" type: Literal["SLICE"] = Field( default="SLICE", title="Parameter type", description="Type of the parameter", ) start: int | None = Field( title="Start", description="Slice start index (inclusive, unset = start of data)", ) end: int | None = Field( title="End", description="Slice end index (inclusive, unset = end of data)", )
CalldataDescriptorPathElementV1 = Annotated[ CalldataDescriptorPathElementTupleV1 | CalldataDescriptorPathElementArrayV1 | CalldataDescriptorPathElementRefV1 | CalldataDescriptorPathElementLeafV1 | CalldataDescriptorPathElementSliceV1, Field( title="Path element", description="Data path element to reach the target value in the serialized transaction", discriminator="type", ), ]
[docs] class CalldataDescriptorContainerPathV1(CalldataDescriptorStructV1): """Descriptor for the CONTAINER_PATH struct.""" version: Literal[1] = Field( default=1, title="Struct version", description="Version of the CONTAINER_PATH struct", ) type: Literal["CONTAINER"] = Field( default="CONTAINER", title="Path type", description="Type of the path", ) value: CalldataDescriptorContainerPathValueV1 = Field(title="Value", description="Container field")
[docs] class CalldataDescriptorDataPathV1(CalldataDescriptorStructV1): """Descriptor for the DATA_PATH struct.""" version: Literal[1] = Field( default=1, title="Struct version", description="Version of the VALUE struct", ) type: Literal["DATA"] = Field( default="DATA", title="Path type", description="Type of the path", ) elements: list[CalldataDescriptorPathElementV1] = Field( title="Elements", description="Path element to reach the target value", min_length=1, max_length=256, # TODO to be refined )
CalldataDescriptorPathV1 = Annotated[ CalldataDescriptorContainerPathV1 | CalldataDescriptorDataPathV1, Field( title="Path", description="Data or container path to reach the target value in the serialized transaction", discriminator="type", ), ]
[docs] class CalldataDescriptorValueBaseV1(CalldataDescriptorStructV1): """Descriptor for the VALUE struct.""" version: Literal[1] = Field( default=1, title="Struct version", description="Version of the VALUE struct", ) type_family: CalldataDescriptorTypeFamily = Field( title="Type family", description="Type family of the value", ) type_size: int | None = Field( default=None, title="Type size", description="Size of the type (in bytes)", ge=0, le=255 )
[docs] class CalldataDescriptorValuePathV1(CalldataDescriptorValueBaseV1): """ A path to the field in the structured data. The path is a JSON path expression that can be used to extract the field value from the structured data. """ type: Literal["path"] = Field( default="path", title="Value Type", description="The value type identifier (discriminator for values discriminated union).", ) abi_path: ResolvedPath | None = Field( default=None, title="Path (source descriptor)", description="Path to reach the target value in the container or serialized transaction", ) binary_path: CalldataDescriptorPathV1 = Field( title="Path (generic parser protocol)", description="Path to reach the target value in the container or serialized transaction", )
[docs] class CalldataDescriptorValueConstantV1(CalldataDescriptorValueBaseV1): """ A constant value. """ type: Literal["constant"] = Field( default="constant", title="Value Type", description="The value type identifier (discriminator for values discriminated union).", ) value: ScalarType = Field( title="Value", description="The constant value.", ) raw: HexStr = Field( title="Raw Value", description="The constant value, serialized and hex encoded.", )
CalldataDescriptorValueV1 = Annotated[ CalldataDescriptorValuePathV1 | CalldataDescriptorValueConstantV1, Discriminator("type"), ]