Pulled the WYRIWE spec to give you accurate answers on all three. Several things to correct, none of them architectural, all fixable.
1. inputHash derivation — remove the check
Your implementation:
if (keccak256(abi.encodePacked(rawInputHash, sanitizationPipelineHash)) != inputHash) {
return false;
}
Per the WYRIWE spec, input_hash = keccak256(sanitized_input), it’s an independent commitment to the actual bytes fed to the model, not mathematically derived from the other two hashes. The three hashes form a provable chain but not an on-chain derivable one. The check can be removed, the EIP-712 signature binding already covers it. If the gateway signed a struct containing all three hashes, they’re cryptographically bound without needing a derivation formula.
2. ATTESTATION_TYPEHASH - four corrections
Current:
WyriweAttestation(bytes32 manifestHash, bytes32 rawInputHash, bytes32 sanitizationPipelineHash,
bytes32 inputHash, bytes32 outputHash, uint256 agentId, address registry, uint64 timestamp)
Should be:
WyriweAttestation(bytes32 agentId, address registry, bytes32 modelHash, bytes32 rawInputHash,
bytes32 sanitizationPipelineHash, bytes32 inputHash, bytes32 outputHash, uint256 timestamp)
Changes:
-
manifestHash → modelHash (field name per spec)
-
agentId type: uint256 → bytes32
-
timestamp type: uint64 → uint256
-
Field order: spec order is agentId, registry, modelHash first, matches the struct definition
3. Domain name
"WYRIWE" → "ERC8004AttestationGateway" per spec.
4. Domain verifying contract
// current
registry // ← should be address(this)
The verifying contract in the EIP-712 domain separator should be the contract calling ecrecover , that’s WyriweVerifier, not the registry. Using registry makes the domain separator unstable across deployments.
5. One thing you got better than the spec
block.chainid (dynamic) is the right call. The spec had chainId: 1 hardcoded, I’ve updated ERC-draft.md to require block.chainid and flag hardcoded values as NOT permitted. Your implementation was already correct.
WYRIWE spec for reference: https://github.com/TMerlini/wyriwe
The struct definition and domain config are in ERC-draft.md. Let me know if anything in the spec is ambiguous and I’ll clarify.
Tiago / dinamic.eth