Commit b5cf837
core: Support struct field access in declarative calls
Implement full support for named and mixed struct field access in declarative
calls within subgraph manifests. This enables patterns like:
- event.params.asset.addr (named field access)
- event.params.asset.0.name (mixed numeric/named access)
- event.params.data.1.user.id (arbitrary nesting depth)
## Key Changes
### Enhanced Field Access Architecture
- Unified `StructField(Word, Vec<FieldAccess>)` supporting both numeric indices and property names
- Added `FieldAccess` enum with `Index(usize)` and `Name(Word)` variants
- Extended parsing to handle arbitrary nesting depth: `event.params.a.b.c.d`
### ABI-Driven Named Field Resolution
- Added `StructFieldInfo` to preserve component field names from ABI JSON
- Implemented `MappingABI::parse_struct_field_mappings()` for direct ABI JSON parsing
- Extended `MappingABI` with `struct_field_mappings` field
### Smart Error Messages
- Show available field names when invalid names are used
- Provide declarative call context in all error messages
- Suggest numeric alternatives when ABI context unavailable
### Integration with Event Processing
- Added `*_with_abi()` method overloads accepting ABI context and event names
- Modified `from_log_trigger_with_event()` to pass ABI information through call chain
- Updated Ethereum data source to provide event context
## Why This Indirection is Necessary
The ethabi crate has a significant limitation: when parsing ABI JSON into
`ParamType` structures, **tuple field names are completely lost**. While the
original ABI JSON contains rich component information like:
```json
{
"name": "asset",
"type": "tuple",
"components": [
{"name": "addr", "type": "address"},
{"name": "amount", "type": "uint256"}
]
}
```
The ethabi parser converts this to `ParamType::Tuple(vec\![Address, Uint(256)])`,
discarding the field names "addr" and "amount" entirely. This makes named field
access impossible using ethabi's parsed structures alone.
Our solution preserves the original ABI component information by:
1. **Direct ABI JSON parsing** to extract component field names before ethabi processing
2. **Parallel struct field mappings** that map field names to tuple indices
3. **Runtime field resolution** using the preserved component information
This indirection is essential because:
- **ethabi limitation**: Tuple field names are lost during ABI parsing
- **User experience**: Named access like `asset.addr` is much clearer than `asset.0`
- **Type safety**: We maintain ethabi's type safety while adding name resolution
- **Backward compatibility**: Numeric indices continue to work unchanged
## Test Coverage
- Comprehensive end-to-end test with real ABI JSON parsing
- Error message validation with available field name suggestions
- Mixed numeric/named access pattern testing
- Integration testing with declarative call contexts
- Reduced test suite from 19 to 16 tests by eliminating redundancy
Addresses feedback from PR review and implements the complete named struct
field access feature for Graph Node declarative calls.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>1 parent b7a5cc3 commit b5cf837
File tree
3 files changed
+480
-202
lines changed- chain/ethereum/src
- graph/src/data_source
- runtime/test/src
3 files changed
+480
-202
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
800 | 800 | | |
801 | 801 | | |
802 | 802 | | |
803 | | - | |
| 803 | + | |
804 | 804 | | |
805 | 805 | | |
806 | 806 | | |
807 | 807 | | |
| 808 | + | |
808 | 809 | | |
809 | 810 | | |
810 | 811 | | |
| |||
0 commit comments