Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an ERC-7730 v2 pipeline to the codebase: new v2 input/resolved Pydantic models, an input→resolved converter, v2-specific linters, and golden-file tests validating conversion output.
Changes:
- Introduce v2 input + resolved descriptor models (context/metadata/display) and discriminated unions.
- Implement v2 input→resolved conversion (selectors, references, params, constants/maps/enums).
- Add v2 linting entrypoints + linters and golden reference tests with sample v2 descriptors.
Reviewed changes
Copilot reviewed 66 out of 69 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/v2/convert/resolved/test_convert_input_to_resolved.py | Golden-file conversion tests for v2 input→resolved. |
| tests/v2/convert/resolved/data/calldata_with_extended_params_input.json | Input fixture for calldata params conversion. |
| tests/v2/convert/resolved/data/calldata_with_extended_params_resolved.json | Expected resolved output for calldata params conversion. |
| tests/v2/convert/resolved/data/deprecated_abi_ignored_input.json | Input fixture asserting deprecated ABI is ignored. |
| tests/v2/convert/resolved/data/deprecated_abi_ignored_resolved.json | Expected resolved output with deprecated ABI removed/ignored. |
| tests/v2/convert/resolved/data/deprecated_schemas_ignored_input.json | Input fixture asserting deprecated EIP-712 schemas are ignored. |
| tests/v2/convert/resolved/data/deprecated_schemas_ignored_resolved.json | Expected resolved output with deprecated schemas removed/ignored. |
| tests/v2/convert/resolved/data/field_group_basic_input.json | Input fixture for field-group scoping. |
| tests/v2/convert/resolved/data/field_group_basic_resolved.json | Expected resolved output for field-group scoping. |
| tests/v2/convert/resolved/data/field_group_with_iteration_input.json | Input fixture for field-group iteration. |
| tests/v2/convert/resolved/data/field_group_with_iteration_resolved.json | Expected resolved output for field-group iteration. |
| tests/v2/convert/resolved/data/field_group_with_label_input.json | Input fixture for field-group labels. |
| tests/v2/convert/resolved/data/field_group_with_label_resolved.json | Expected resolved output for field-group labels. |
| tests/v2/convert/resolved/data/field_with_encryption_input.json | Input fixture for encryption metadata on fields. |
| tests/v2/convert/resolved/data/field_with_encryption_resolved.json | Expected resolved output for encryption metadata. |
| tests/v2/convert/resolved/data/field_with_separator_input.json | Input fixture for array separator handling. |
| tests/v2/convert/resolved/data/field_with_separator_resolved.json | Expected resolved output for array separator handling. |
| tests/v2/convert/resolved/data/field_with_visibility_conditions_input.json | Input fixture for conditional visibility rules. |
| tests/v2/convert/resolved/data/field_with_visibility_conditions_resolved.json | Expected resolved output for conditional visibility rules. |
| tests/v2/convert/resolved/data/field_with_visibility_simple_input.json | Input fixture for simple visibility rules. |
| tests/v2/convert/resolved/data/field_with_visibility_simple_resolved.json | Expected resolved output for simple visibility rules. |
| tests/v2/convert/resolved/data/format_chain_id_input.json | Input fixture for chainId field format. |
| tests/v2/convert/resolved/data/format_chain_id_resolved.json | Expected resolved output for chainId field format. |
| tests/v2/convert/resolved/data/format_interoperable_address_name_input.json | Input fixture for interoperable address name format. |
| tests/v2/convert/resolved/data/format_interoperable_address_name_resolved.json | Expected resolved output for interoperable address name format. |
| tests/v2/convert/resolved/data/format_token_ticker_input.json | Input fixture for token ticker format. |
| tests/v2/convert/resolved/data/format_token_ticker_resolved.json | Expected resolved output for token ticker format. |
| tests/v2/convert/resolved/data/format_with_interpolated_intent_input.json | Input fixture for interpolated intent strings. |
| tests/v2/convert/resolved/data/format_with_interpolated_intent_resolved.json | Expected resolved output for interpolated intent strings. |
| tests/v2/convert/resolved/data/metadata_with_contract_name_input.json | Input fixture for metadata.contractName. |
| tests/v2/convert/resolved/data/metadata_with_contract_name_resolved.json | Expected resolved output for metadata.contractName. |
| tests/v2/convert/resolved/data/metadata_with_maps_input.json | Input fixture for metadata.maps. |
| tests/v2/convert/resolved/data/metadata_with_maps_resolved.json | Expected resolved output for metadata.maps. |
| tests/v2/convert/resolved/data/minimal_contract_v2_input.json | Minimal contract-context v2 input fixture. |
| tests/v2/convert/resolved/data/minimal_contract_v2_resolved.json | Expected resolved output for minimal contract-context fixture. |
| tests/v2/convert/resolved/data/minimal_eip712_v2_input.json | Minimal EIP-712-context v2 input fixture. |
| tests/v2/convert/resolved/data/minimal_eip712_v2_resolved.json | Expected resolved output for minimal EIP-712-context fixture. |
| tests/v2/convert/resolved/data/token_amount_with_chainid_input.json | Input fixture for tokenAmount + chainIdPath parameters. |
| tests/v2/convert/resolved/data/token_amount_with_chainid_resolved.json | Expected resolved output for tokenAmount + chainIdPath parameters. |
| tests/v2/convert/resolved/init.py | Test package init for v2 resolved conversion tests. |
| tests/v2/convert/init.py | Test package init for v2 conversion tests. |
| tests/v2/init.py | Test package init for v2 tests. |
| src/erc7730/model/input/v2/init.py | v2 input model package init. |
| src/erc7730/model/input/v2/context.py | v2 input context models (contract/EIP-712). |
| src/erc7730/model/input/v2/descriptor.py | v2 input descriptor root model. |
| src/erc7730/model/input/v2/display.py | v2 input display/field/params models (incl. groups, visibility, maps). |
| src/erc7730/model/input/v2/format.py | v2 field format enums. |
| src/erc7730/model/input/v2/metadata.py | v2 input metadata models (incl. maps/enums/constants). |
| src/erc7730/model/input/v2/unions.py | v2 discriminators for fields/params/visibility unions. |
| src/erc7730/model/resolved/v2/init.py | v2 resolved model package init. |
| src/erc7730/model/resolved/v2/context.py | v2 resolved context models with normalized addresses and deprecated fields dropped. |
| src/erc7730/model/resolved/v2/descriptor.py | v2 resolved descriptor root model. |
| src/erc7730/model/resolved/v2/display.py | v2 resolved display/field/params models. |
| src/erc7730/model/resolved/v2/metadata.py | v2 resolved metadata models (resolved enums/maps). |
| src/erc7730/convert/resolved/v2/init.py | v2 conversion helpers package init. |
| src/erc7730/convert/resolved/v2/constants.py | v2 constant provider + path resolution helpers (incl. map reference scaffolding). |
| src/erc7730/convert/resolved/v2/convert_erc7730_input_to_resolved.py | Main v2 input→resolved converter implementation. |
| src/erc7730/convert/resolved/v2/enums.py | Enum reference parsing/validation helpers for v2 conversion. |
| src/erc7730/convert/resolved/v2/parameters.py | v2 parameter resolution for field formats (token amount/ticker, calldata, etc.). |
| src/erc7730/convert/resolved/v2/references.py | v2 display definition reference inlining. |
| src/erc7730/convert/resolved/v2/values.py | v2 field value/path resolution + constant encoding. |
| src/erc7730/lint/v2/init.py | v2 linter base + MultiLinter runner. |
| src/erc7730/lint/v2/lint.py | v2 lint CLI/entrypoint functions (load→convert→lint). |
| src/erc7730/lint/v2/lint_transaction_type_classifier.py | v2 transaction classification linter (permit heuristics + ABI classifier hook). |
| src/erc7730/lint/v2/lint_validate_display_fields.py | v2 ABI-backed display path validation (via explorer ABI fetch). |
| src/erc7730/lint/v2/lint_validate_max_length.py | v2 max-length checks for Ledger device constraints. |
| src/erc7730/lint/v2/path_schemas.py | v2 schema-path extraction for linting. |
| specs/erc7730-v1.schema.json | Adds/records the v1 JSON schema file under specs/. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
The lint CLI command was hardcoded to use the v1 model, causing false errors when linting v2 descriptors. This adds auto-detection based on the $schema field and routes to the v2 linter accordingly. A --v2 flag is also available for explicit override.
Pure/view functions cannot produce transactions and don't need clear signing descriptors. Skip them by default in get_functions() to reduce noise in lint output. The generator still includes all functions via include_read_only=True.
rich.print wraps long strings at terminal width, inserting literal newlines into JSON string values (e.g. hex descriptor fields). This corrupts the output when piped or captured. Use builtins.print for schema, resolve, and calldata commands that output raw JSON.
The calldata command now auto-detects v2 descriptors (via $schema field) and builds ABI Function objects from human-readable format keys in display.formats, instead of requiring an embedded ABI in the contract context. Fields with visible="never" are skipped to match v1 behavior.
- `erc7730 resolve` now auto-detects v2 descriptors and uses the v2 resolver (or accepts --v2 flag). - `erc7730 convert erc7730-to-eip712` now detects v2 descriptors early and exits with a clear error: v2 drops embedded EIP-712 schemas, so conversion to legacy format is not supported.
Reconstruct EIP-712 schemas from v2 descriptors where the embedded schemas have been removed. The display.formats keys (encodeType strings) are parsed back into full EIP-712 type definitions and the EIP712Domain is rebuilt from the domain/deployment info. - Add `parse_encode_type()` utility to reverse encodeType strings - New `ERC7730V2toEIP712Converter` for v2 -> legacy EIP-712 conversion - Update `command_convert_erc7730_to_eip712` to dispatch to v2 converter - Add `validate_eip712_domain_fields()` to warn on non-standard or mis-ordered EIP712Domain fields in v1 descriptors - V2 domain reconstruction emits fields in canonical EIP-712 order: name, version, chainId, verifyingContract, salt
- Emit name, version, salt only when present in domain (instead of always) - Emit chainId + verifyingContract when deployments exist (unchanged) - Add salt field to v2 InputDomain and ResolvedDomain models - Propagate salt through the resolve step
- Add ValidateEIP712DomainLinter that checks EIP712Domain fields are in canonical EIP-712 order and warns about non-standard field names - Incorrect ordering is reported as a critical error - Move validate_eip712_domain_fields from converter to linter module - Reuse the validation function from the v1 converter
- Remove unused imports flagged by pycln (function_to_selector, ResolvedValueConstant) - Break long line in main.py to satisfy ruff E501 (120 char limit) - Add nosec B112 to intentional try/except/continue in _any_v2_descriptor - Pin sphinx<9 to work around sphinx-github-style IndexError with Sphinx 9
The lockfile hash was out of sync after pinning sphinx<9, causing CI to fail on `pdm install --frozen-lockfile`.
- parameters.py: use data_or_container_path_concat instead of unsupported + operator on DataPath - convert_erc7730_v2_to_eip712.py: convert path objects to str for _resolve_calldata_param_path, remove non-existent chainId access on v2 ResolvedCallDataParameters - convert_erc7730_v2_input_to_calldata.py: narrow value type to ScalarType, convert field.path to str before passing to _convert_v2_value - main.py: use distinct variable name to avoid type conflict across if/else branches with walrus operator
Sphinx 8.2.x introduced a dependency on roman-numerals-py which causes "No module named 'roman_numerals'" when loading sphinx.builders.latex. Pinning to 8.1.x avoids this dependency entirely.
The GitHubLexer.get_tokens_unprocessed method accesses tokens[idx+1] without bounds checking, causing IndexError when a builtin class or Name token is the last in the list. This is a bug in sphinx-github-style 1.2.2 (latest). Added a monkey-patch in conf.py to add the missing bounds check.
The Address type normalizes addresses to lowercase via a BeforeValidator, which caused v2 calldata output to differ from v1 for constant token addresses. Use MixedCaseAddress instead to preserve the original casing from the descriptor file, aligning v2 behavior with v1.
Align v2 resolved/calldata conversion with current schema semantics by handling optional encryption on shared field definitions and normalizing path/value parameter resolution. Add regression fixtures for encryption-by-definition and updated resolved outputs to keep v2 conversion tests consistent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context: https://github.com/ethereum/ERCs/blob/master/assets/erc-7730/erc7730-v2.schema.json
NOTE: v2 support is experimental and not fully tested. The only guarantee is v1 full backward-compatibility