ERC-8257: Agent Tool Registry

Thanks for opening this. Quick comment on item 2 (predicate ERC-165 dispatch + composability): the existing pinned IRequirementTypes markers (IERC721Holding, IERC1155Holding, ISubscription) cleanly cover on-chain holdings — same EVM chain as the registry, single Solidity read. There’s a fourth shape that the data parameter on IAccessPredicate.hasAccess already supports natively but no marker yet describes: off-chain-signed wallet-state attestations.

The case for it as a distinct kind:

  1. Cross-chain wallet state cannot be expressed as a native EVM predicate. Wallet state on non-EVM chains (Solana, XRPL, Bitcoin) can’t be evaluated from a Solidity predicate. The natural shape is for an off-chain issuer to evaluate the condition set against the relevant chain data, sign a verdict, and have the on-chain predicate verify the signature. The spec’s data parameter (“Opaque context bytes (e.g., tokenId, proof, signature)”) is designed for exactly this.

  2. It’s distinct from the AccessProof pattern in §“Account Parameter Is Advisory.” That pattern is requester-self-signed — the wallet signs a challenge to prove it is account. The attestation pattern here is issuer-signed — an external service signs a verdict about account’s wallet state. Identity-binding and state-binding are orthogonal; a complete access scheme may want both, and conflating them at the marker layer would lose that distinction.

  3. Gas fits comfortably. ECDSA P-256 verification via the RIP-7212 precompile is ~3,450 gas; ABI decode of a seven-tuple proof is another few thousand. Well under the 200k cap.

Concrete proposal:

/// @dev kind for off-chain-signed wallet-state attestation requirements.
///      data = abi.encode(string issuerJWKSURI, bytes32 conditionHash)
///      interfaceId = 0x7a111640
interface IWalletStateAttestation {
    function walletStateAttestation() external;
}

Selector 0x7a111640 = bytes4(keccak256("walletStateAttestation()")), verified non-colliding with the three pinned IDs.

The getRequirements.data layout abi.encode(string issuerJWKSURI, bytes32 conditionHash) tells an agent two things: where to fetch the issuer’s public-key set (a JWKS document at a well-known URL — same trust-anchor pattern as the spec’s manifest origin-binding), and which condition set the predicate enforces. The hasAccess.data payload then carries the proof itself: abi.encode(bool pass, address wallet, bytes32 conditionHash, uint256 blockNumber, bytes32 r, bytes32 s, bytes32 messageHash).

A working reference predicate that matches this layout, verifies P-256 via RIP-7212, advertises IAccessPredicate + IERC165 for registration validation, and returns false (rather than reverts) on any check failure is at:

Tests in the same repo (InsumerAccessPredicate.t.sol) include a happy-path case that runs real ECDSA P-256 verification of a live signed attestation through the precompile, plus eight failure modes (tampered signature, tampered message hash, wrong account, wrong condition hash, pass=false, stale, future-dated, empty data).

Happy to fold the marker into a PR against IRequirementTypes.sol if it’s useful, or leave it as a third-party marker per the spec’s extension guidance — whichever fits the cadence you’re running.