Skip to content

Commit

Permalink
new schema
Browse files Browse the repository at this point in the history
  • Loading branch information
ClaireGuerreGiordano committed Sep 20, 2024
1 parent 5d77cd5 commit dd09ea5
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 148 deletions.
125 changes: 41 additions & 84 deletions src/erc7730/mapper/mapper.py
Original file line number Diff line number Diff line change
@@ -1,68 +1,48 @@
# type: ignore
# ruff: noqa
from pydantic import AnyUrl
from erc7730.common.pydantic import model_from_json_bytes
from erc7730.model.context import EIP712JsonSchema, EIP712Context, EIP712, Domain, EIP712Domain
from erc7730.model.erc7730_descriptor import ERC7730Descriptor, EIP712Context
from erc7730.model.display import (
Display,
Reference,
Field,
StructFormats,
FieldFormat,
Fields,
Format,
DateParameters,
DateEncoding,
TokenAmountParameters,
)
from eip712 import (
EIP712DAppDescriptor,
EIP712ContractDescriptor,
EIP712Mapper,
EIP712MessageDescriptor,
EIP712Field,
EIP712Format,
)
import requests
# from pydantic import AnyUrl
# from erc7730.common.pydantic import model_from_json_bytes
# from erc7730.model.context import EIP712JsonSchema, EIP712Context, EIP712, Domain, EIP712Domain
# from erc7730.model.erc7730_descriptor import ERC7730Descriptor, EIP712Context
# from erc7730.model.display import Display, Reference, Field, StructFormats, FieldFormat, Fields, Format, DateParameters, DateEncoding, TokenAmountParameters
# from eip712 import EIP712DAppDescriptor, EIP712ContractDescriptor, EIP712Mapper, EIP712MessageDescriptor, EIP712Field, EIP712Format
# import requests

from erc7730.model.metadata import Metadata
# from erc7730.model.metadata import Metadata


def to_eip712_mapper(erc7730: ERC7730Descriptor) -> EIP712DAppDescriptor | list[Exception]:
"""def to_eip712_mapper(erc7730: ERC7730Descriptor) -> EIP712DAppDescriptor|list[Exception]:
exceptions = list[Exception]()
context = erc7730.context
if context is not None and isinstance(context, EIP712Context):
if (context is not None and isinstance(context, EIP712Context)):
domain = context.eip712.domain
if domain is None:
exceptions.append(Exception(f"no domain defined for {context.eip712}")) # type: ignore
if (domain is None):
exceptions.append(Exception(f"no domain defined for {context.eip712}")) # type: ignore
else:
if domain.chainId is None:
exceptions.append(Exception(f"chain id is None for {domain}")) # type: ignore
elif domain.verifyingContract is None:
exceptions.append(Exception(f"verifying contract is None for {domain}")) # type: ignore
if (domain.chainId is None):
exceptions.append(Exception(f"chain id is None for {domain}")) # type: ignore
elif (domain.verifyingContract is None):
exceptions.append(Exception(f"verifying contract is None for {domain}")) # type: ignore
else:
schema = dict[str, str]()
schs = context.eip712.schemas
if schs is not None:
for item in schs:
sch = None
if isinstance(item, EIP712JsonSchema):
if (isinstance(item, EIP712JsonSchema)):
sch = item
else:
try:
response = requests.get(item.__str__())
sch = model_from_json_bytes(response.content, model=EIP712JsonSchema)
sch = model_from_json_bytes(response.content, model = EIP712JsonSchema)
except Exception as e:
exceptions.append(e) # type: ignore
exceptions.append(e) # type: ignore
if sch is not None:
for key in sch.types:
for d in sch.types[key]:
schema[key + "." + d.name] = d.type
for d in sch.types[key]:
schema[key + "." + d.name] = d.type
chain_id = domain.chainId
contract_address = domain.verifyingContract
name = ""
if domain.name is not None:
if (domain.name is not None):
name = domain.name
display = erc7730.display
contracts = list[EIP712ContractDescriptor]()
Expand All @@ -72,34 +52,26 @@ def to_eip712_mapper(erc7730: ERC7730Descriptor) -> EIP712DAppDescriptor | list[
messages = list[EIP712MessageDescriptor]()
if format.fields is not None:
eip712Fields = parseFields(display, primaryType, list[EIP712Field](), format.fields)
messages.append(
EIP712MessageDescriptor(
schema=schema, mapper=EIP712Mapper(label=primaryType, fields=eip712Fields)
)
)
contracts.append(
EIP712ContractDescriptor(address=contract_address, contractName=name, messages=messages)
)
messages.append(EIP712MessageDescriptor(schema = schema, mapper = EIP712Mapper(label = primaryType, fields = eip712Fields)))
contracts.append(EIP712ContractDescriptor(address=contract_address, contractName=name, messages=messages))
return EIP712DAppDescriptor(blockchainName="ethereum", chainId=chain_id, name=name, contracts=contracts)
else:
exceptions.append(Exception(f"context for {erc7730} is None or is not EIP712")) # type: ignore
exceptions.append(Exception(f"context for {erc7730} is None or is not EIP712")) # type: ignore
return exceptions

def parseFields(display: Display, primaryType: str, output: list[EIP712Field], fields: Fields) -> list[EIP712Field]:
for _, field in fields:
if isinstance(field, Reference):
# get field from definition section
if isinstance(field, Reference):
# get field from definition section
if display.definitions is not None:
for _, f in display.definitions[field.ref]:
parseField(primaryType, output, f)
elif isinstance(field, StructFormats):
elif isinstance(field, StructFormats):
parseFields(display, primaryType, output, field.fields)
elif isinstance(field, Field):
elif isinstance(field, Field):
parseField(primaryType, output, field)
return output

def parseField(primaryType: str, output: list[EIP712Field], field: Field) -> list[EIP712Field]:
name = field.label
assetPath = None
Expand All @@ -108,7 +80,7 @@ def parseField(primaryType: str, output: list[EIP712Field], field: Field) -> lis
case FieldFormat.NFT_NAME:
assetPath = field.collectionPath
case FieldFormat.TOKEN_NAME:
if field.tokenAmountParameters is not None:
if (field.tokenAmountParameters is not None):
assetPath = field.tokenAmountParameters.tokenPath
fieldFormat = EIP712Format.AMOUNT
case FieldFormat.ALLOWANCE_AMOUNT:
Expand All @@ -122,18 +94,12 @@ def parseField(primaryType: str, output: list[EIP712Field], field: Field) -> lis
output.append(EIP712Field(path=primaryType, label=name, assetPath=assetPath, format=fieldFormat, coinRef=None))
return output

def to_erc7730_mapper(eip712DappDescriptor: EIP712DAppDescriptor) -> ERC7730Descriptor:
verifyingContract = None
if eip712DappDescriptor.contracts.__len__() > 0:
verifyingContract = eip712DappDescriptor.contracts[0].address
domain = Domain(
name=eip712DappDescriptor.name,
version=None,
chainId=eip712DappDescriptor.chain_id,
verifyingContract=verifyingContract,
)
formats = dict[str, Format]()
domain = Domain(name = eip712DappDescriptor.name, version = None, chainId = eip712DappDescriptor.chain_id, verifyingContract = verifyingContract)
formats = dict[str,Format]()
schemas = list[EIP712JsonSchema | AnyUrl]()
for contract in eip712DappDescriptor.contracts:
types = dict[str, list[EIP712Domain]]()
Expand All @@ -153,24 +119,15 @@ def to_erc7730_mapper(eip712DappDescriptor: EIP712DAppDescriptor) -> ERC7730Desc
dateParameters = DateParameters(encoding=DateEncoding.TIMESTAMP)
case _:
pass
fields[item.label] = Field(
sources=None,
collectionPath=None,
tokenAmountParameters=tokenAmountParameters,
allowanceAmountParameters=None,
percentageParameters=None,
dateParameters=dateParameters,
enumParameters=None,
)
eip712Domains.append(EIP712Domain(name=item.label, type=item.format.name))
fields[item.label] = Field(sources=None, collectionPath=None, tokenAmountParameters=tokenAmountParameters, allowanceAmountParameters=None, percentageParameters=None, dateParameters=dateParameters, enumParameters=None)
eip712Domains.append(EIP712Domain(name = item.label, type = item.format.name))
types[mapper.label] = eip712Domains
formats[mapper.label] = Format(
id=None, intent=None, fields=Fields(root=fields), required=None, screens=None
)
schemas.append(EIP712JsonSchema(primaryType=mapper.label, types=types))
formats[mapper.label] = Format(id=None, intent=None, fields=Fields(root=fields), required=None, screens=None)
schemas.append(EIP712JsonSchema(primaryType = mapper.label, types = types))
eip712 = EIP712(domain=domain, schemas=schemas)
context = EIP712Context(eip712=eip712)
display = Display(definitions=None, formats=formats)
eip712 = EIP712(domain = domain, schemas = schemas)
context = EIP712Context(eip712 = eip712)
display = Display(definitions=None, formats = formats)
metadata = Metadata(owner=None, info=None, token=None, constants=None, enums=None)
return ERC7730Descriptor(context=context, includes=None, metadata=metadata, display=display)
return ERC7730Descriptor(context = context, includes=None, metadata=metadata, display=display)
"""
68 changes: 61 additions & 7 deletions src/erc7730/model/context.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
from typing import Union, Optional
from pydantic import AnyUrl
from enum import Enum
from typing import ForwardRef, Union, Optional
from pydantic import AnyUrl, RootModel
from erc7730.model.base import BaseLibraryModel
from erc7730.model.types import ContractAddress, Id
from erc7730.model.abi import ABI


class EIP712Domain(BaseLibraryModel):
name: str
type: str


class Types(BaseLibraryModel):
EIP712Domain: list[EIP712Domain]


class EIP712JsonSchema(BaseLibraryModel):
primaryType: str
types: dict[str, list[EIP712Domain]]
types: Types


class EIP712Schema(BaseLibraryModel):
Expand All @@ -26,22 +30,72 @@ class Domain(BaseLibraryModel):
verifyingContract: Optional[ContractAddress] = None


class Deployment(BaseLibraryModel):
chainId: Optional[int] = None
address: Optional[str] = None


class Deployments(RootModel[list[Deployment]]):
"""deployments"""


class EIP712(BaseLibraryModel):
domain: Optional[Domain] = None
schemas: Optional[list[Union[EIP712JsonSchema, AnyUrl]]] = None
domainSeparator: Optional[str] = None
deployments: Optional[Deployments] = None


class EIP712DomainBinding(BaseLibraryModel):
eip712: EIP712


AbiJsonSchema = list[ABI]
class AbiParameter(BaseLibraryModel):
name: str
type: str
internalType: Optional[str] = None
components: Optional[list[ForwardRef("AbiParameter")]] = None # type: ignore


AbiParameter.model_rebuild()


class StateMutability(Enum):
pure = "pure"
view = "view"
nonpayable = "nonpayable"
payable = "payable"


class Type(Enum):
function = "function"
constructor = "constructor"
receive = "receive"
fallback = "fallback"


class AbiJsonSchemaItem(BaseLibraryModel):
name: str
inputs: list[AbiParameter]
outputs: Optional[list[AbiParameter]]
stateMutability: Optional[StateMutability] = None
type: Type


class AbiJsonSchema(RootModel[list[AbiJsonSchemaItem]]):
"""abi json schema"""


class Factory(BaseLibraryModel):
deployments: Deployments
deployEvent: str


class Contract(BaseLibraryModel):
chainId: Optional[int] = None
address: Optional[ContractAddress] = None
abi: Optional[Union[AnyUrl, AbiJsonSchema]] = None
deployments: Optional[Deployments] = None
addressMatcher: Optional[AnyUrl] = None
factory: Optional[Factory] = None


class ContractBinding(BaseLibraryModel):
Expand Down
Loading

0 comments on commit dd09ea5

Please sign in to comment.