--- eip: 8242 title: H3 Spatial Identity Extension for On-Chain Agents description: A lightweight on-chain registry for agent spatial identity using H3 hexagonal indexing, enabling spatial-aware agent discovery without transport or execution constraints. author: Opacus Protocol (@bl10buer) discussions-to: https://ethereum-magicians.org/t/erc-8242-agent-quic-http3-transport-endpoint-registry/28394 status: Draft type: Standards Track category: ERC created: 2026-03-28 requires: 165 --- ## Abstract ERC-8242 defines `IERC8242`, a standard on-chain interface for registering and discovering agent spatial identity using Uber's H3 hexagonal hierarchical indexing system. Any contract, scheduler, or off-chain client can call `discoverAgents()` to resolve agents by spatial identity without relying on a centralised directory. This standard is a pure metadata extension: **it does not define transport, execution, or networking layers.** ## Motivation Autonomous agents operating across decentralised networks increasingly need to express spatial context for routing, selection, and coordination. Today there is no standard on-chain interface for agent spatial identity: each protocol invents a proprietary mechanism, creating fragmentation and lock-in. H3 hexagonal indexing provides a compact, hierarchical representation of spatial identity at resolutions 0–15 (global to ~1 m²). By anchoring spatial metadata on-chain via a common interface, ERC-8242 enables: * **Composable spatial discovery** — any contract or on-chain scheduler can call `discoverAgents(h3Parent, resolution, preference, offset, limit)` to resolve agents by execution locality at execution time, with no off-chain infrastructure dependency. * **Routing hints** — `execution_preference` signals whether an agent prefers local, regional, or global task assignment; consumers treat this as a non-binding agent selection signal. * **Lightweight metadata** — no bond, no fee, no transport fields, no networking assumptions. A single `spatial` object is all that is required. * **Backward compatible** — if a `spatial` record is absent, the agent is assumed `"global"`. **Example:** an on-chain intent-layer contract selects an agent for a localised task by calling `discoverAgents(parentCell, 5, Local, 0, 10)`. No DNS lookup, no off-chain API call — the spatial routing decision is fully reproducible on-chain. This standard addresses a gap not covered by any existing ERC: there is no application-layer interface for on-chain spatial identity of agents with hierarchical spatial filtering. ## Specification The key words "MUST", "MUST NOT", "SHOULD", "MAY" in this document are to be interpreted as described in RFC 2119. ### Definitions | Term | Definition | |---|---| | **Spatial Identity** | An agent's declared H3 cell; used as a routing hint and agent selection signal. Not a claim of physical presence. | | **Execution Locality** | The `execution_preference` field signals the agent's preferred task scope: `Local`, `Regional`, or `Global`. | | **H3 Index** | A string-encoded H3 cell identifier (e.g., `"8928308280fffff"`). | | **Resolution** | H3 resolution integer from 0 (global, ~4,250,547 km²) to 15 (~0.9 m²). Recommended value: `5` (~252 km²). | ### Enums ```solidity enum ExecutionPreference { Local, // Prefer tasks within the same H3 cell or immediate neighbours Regional, // Prefer tasks within parent cells up to resolution 3 Global // No spatial preference (default) } ``` ### Structs ```solidity struct SpatialRecord { address agent; string h3Index; // H3 cell identifier string uint8 resolution; // H3 resolution (0–15) ExecutionPreference preference; // Routing hint; consumers MUST treat as non-binding uint64 registeredAt; // UNIX timestamp set on creation; MUST NOT change thereafter uint64 updatedAt; // UNIX timestamp of most recent mutation; equals registeredAt on creation } ``` ### Interface ```solidity interface IERC8242 { function registerSpatial( string calldata h3Index, uint8 resolution, ExecutionPreference preference ) external; function updateSpatial( string calldata h3Index, uint8 resolution, ExecutionPreference preference ) external; function deregisterSpatial() external; function getSpatial(address agent) external view returns (SpatialRecord memory); function discoverAgents( string calldata h3Parent, uint8 resolution, ExecutionPreference preference, uint256 offset, uint256 limit ) external view returns (SpatialRecord[] memory records, uint256 total); } ``` ### Methods #### `registerSpatial` ```solidity function registerSpatial( string calldata h3Index, uint8 resolution, ExecutionPreference preference ) external; ``` * **MUST** revert if `h3Index` is empty. * **MUST** revert if the caller is already registered. * **MUST** revert if `resolution > 15`. * **MUST** set `registeredAt = block.timestamp` and `updatedAt = block.timestamp`. * **MUST** emit `SpatialRegistered(agent, h3Index, preference)`. * **MUST NOT** collect any fee or bond. #### `updateSpatial` ```solidity function updateSpatial( string calldata h3Index, uint8 resolution, ExecutionPreference preference ) external; ``` * **MUST** only be callable by the registered agent (`msg.sender` matches stored record). * **MUST NOT** collect any fee. * **MUST** set `updatedAt = block.timestamp`. * **MUST** emit `SpatialUpdated(agent, h3Index, preference)`. #### `deregisterSpatial` ```solidity function deregisterSpatial() external; ``` * **MUST** delete the spatial record for `msg.sender`. * **MUST** emit `SpatialDeregistered(agent)`. #### `getSpatial` ```solidity function getSpatial(address agent) external view returns (SpatialRecord memory); ``` * **MUST** return the full `SpatialRecord` for the given agent. * **MUST** return an empty record (all zero/default values) if no record exists. #### `discoverAgents` ```solidity function discoverAgents( string calldata h3Parent, uint8 resolution, ExecutionPreference preference, uint256 offset, uint256 limit ) external view returns (SpatialRecord[] memory records, uint256 total); ``` * **MUST** filter by agents whose `h3Index` is a child of `h3Parent` at the given `resolution` when `h3Parent` is non-empty. * **MUST** filter by `preference` when `preference != ExecutionPreference.Global`. * `offset` / `limit` provide pagination. * Results **MUST** be ordered by ascending `registeredAt` to ensure consistent, non-duplicating pagination across calls. * **SHOULD** return all registered agents when `h3Parent` is empty and `preference == ExecutionPreference.Global`. ### Events ```solidity event SpatialRegistered( address indexed agent, string h3Index, ExecutionPreference preference ); event SpatialUpdated( address indexed agent, string h3Index, ExecutionPreference preference ); event SpatialDeregistered(address indexed agent); ``` ### [ERC-165](./eip-165.md) Compliant contracts MUST implement the `IERC8242` interface defined by this standard and MUST return `true` from `supportsInterface` for `type(IERC8242).interfaceId`. ### Off-Chain JSON Schema For off-chain agent identity documents (e.g., DID documents, registration files), the canonical `spatial` object is: ```json { "spatial": { "h3_index": "8928308280fffff", "resolution": 5, "execution_preference": "local" } } ``` | Field | Type | Required | Description | |---|---|---|---| | `h3_index` | string | yes (if `spatial` present) | H3 cell identifier | | `resolution` | integer (0–15) | yes | H3 resolution; recommended: `5` | | `execution_preference` | `"local"` \| `"regional"` \| `"global"` | no | Routing hint; default: `"global"` | If `spatial` is not present in an agent document, the agent MUST be treated as having `execution_preference = "global"`. ### Validation Rules * `h3_index` — REQUIRED when `spatial` is present; SHOULD be a valid 15-character hex H3 cell string. * `resolution` — REQUIRED; integer in range 0–15. * `execution_preference` — OPTIONAL; default `"global"`. ## Rationale * **H3 over geohash or S2** — H3 provides uniform hexagonal cells with consistent neighbour topology, well-suited for agent routing. The string-encoded cell IDs are human-readable and unambiguous at all resolutions. * **No bond or fee** — Spatial identity is a lightweight metadata claim. Economic friction would deter adoption without meaningful Sybil resistance benefit; spatial cells are non-exclusive and non-rivalrous. * **execution_preference as hint** — Treating execution locality as a non-binding signal keeps the standard composable: consumers apply their own scoring. A hard constraint would require on-chain spatial proofs, which is out of scope. * **No transport fields** — Transport, networking, and execution infrastructure are deliberately excluded. This extension standardizes spatial identity for agents using H3 indexing. It does not define transport, execution, or networking layers. * **Registration-order pagination** — Ordering by `registeredAt` ascending ensures deterministic, stable pagination even as new entries are added. ## Backwards Compatibility No existing ERC is modified. If a `spatial` record is absent for an agent, consumers MUST treat that agent as `execution_preference = "global"`. ERC-8242 is composable with any agent identity or registry standard. ## Reference Implementation A reference implementation is available as `contracts/ERC8242SpatialIdentity.sol` in the Opacus-Standart repository. ## Security Considerations * **Self-reported claims** — `h3Index` and `execution_preference` are self-reported and cannot be verified on-chain. Consumers MUST treat spatial records as non-binding routing hints only. * **No financial risk** — This standard involves no bonds, fees, or token transfers, eliminating reentrancy and token-approval attack surfaces entirely. * **H3 index validation** — `h3Index` is stored as an opaque string. Implementations SHOULD validate that it is a well-formed H3 cell identifier in `registerSpatial` to prevent malformed entries. * **Pagination stability** — Consumers paginating `discoverAgents` results MUST be aware that new registrations may shift total counts between calls. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).