Skip to content

Description ​

Recommended offchain data profile for ERC-8004 validation records

This document provides implementation-agnostic guidance for structuring validation request and response data referenced by the requestUri and responseUri fields in ERC-8004 Validation Registry contracts.

Document Purpose ​

This profile document offers practical, non-normative recommendations for validation data formats used with ERC-8004 Validation Registries, based on real-world usage patterns (analysis of 8,219 production records) and community feedback.

Relationship to EIP-8004 ​

Important: This is not part of the official EIP-8004 specification.

Official EIP-8004 defines:

  • Validation Registry smart contract interface
  • Onchain fields: validatorAddress, agentId, requestUri, responseUri, response, tag
  • URI references to offchain data

This profile suggests:

  • Offchain JSON structure for validation requests and responses
  • Three validation type patterns (crypto-economic, TEE, zkML)
  • Known custom format recognition (Groth16, PLONK, STARK)
  • Evidence attachment guidelines

The official EIP does not mandate specific offchain formats. These are community-developed guidelines.

Terminology ​

This document follows conventions defined in Conventions, including:

  • RFC 2119 keywords: MUST, SHOULD, MAY
  • Field types: string, number, boolean, object, array
  • CAIP formats: CAIP-2 for blockchain IDs, CAIP-10 for addresses
  • Timestamps: ISO 8601 format in UTC

For attachment file patterns, see Attachment Pattern Guidelines.

Intended Audience ​

  • Validators: Creating validation requests and responses
  • Agent Developers: Understanding validation requirements
  • Registry Implementers: Building Validation Registry contracts and indexers
  • Explorer Developers: Parsing and displaying validation data

Table of Contents ​

  1. Overview
  2. Format Compatibility Approach
  3. Validation Request Profile
  4. Validation Response Profile
  5. Known Custom Formats
  6. Attachment Pattern
  7. Parse Status Indicators
  8. Migration Guide
  9. Examples

Overview ​

Onchain vs Offchain Data ​

Onchain (Validation Registry contract):

  • validatorAddress (address) - Who is validating
  • agentId (uint256) - Which agent
  • requestUri (string) - Link to offchain request data
  • requestHash (bytes32) - Hash commitment (for HTTP URIs)
  • responseUri (string) - Link to offchain response data
  • responseHash (bytes32) - Hash commitment (for HTTP URIs)
  • response (uint8) - Score (0-100)
  • tag (bytes32) - Category/purpose
  • lastUpdate (uint256) - Unix timestamp of last update

Onchain Events (for indexers):

  • ValidationRequest: validatorAddress (indexed), agentId (indexed), requestUri, requestHash (indexed)
  • ValidationResponse: validatorAddress (indexed), agentId (indexed), requestHash (indexed), response, responseUri, responseHash, tag

Note for Indexers: The indexed parameters can be efficiently filtered in event queries.

Timestamp Note: The onchain lastUpdate field stores a Unix timestamp (uint256), while the offchain JSON uses createdAt in ISO 8601 format. This separation allows human-readable dates in JSON while maintaining efficient onchain storage.

Offchain (referenced by requestUri / responseUri):

  • Detailed validation criteria
  • Proof data (zkSNARK, TEE attestation, etc.)
  • Test results and evidence
  • Context and methodology

Non-normative - Guiding Principle: These profiles aim to guide, not block. Implementations SHOULD accept all valid JSON data. Non-conforming formats MAY receive informational suggestions but SHOULD NOT be rejected.

Format Compatibility Approach ​

Non-normative: This section describes 8004scan's recommended approach to handling diverse validation formats.

Parse Status: success (no issues) or warning (minor suggestions)

The community-recommended profile format for maximum interoperability.

When to Use:

  • New validation systems
  • Multi-chain deployments
  • Public registries requiring interoperability
  • Integration with multiple ERC-8004 tools

Benefits:

  • ✅ Better indexing and searchability
  • ✅ Frontend displays all metadata
  • ✅ Compatible with standard tooling
  • ✅ Easier integration across platforms

Level 2: Known Custom Formats 🟡 ​

Parse Status: known_custom

Recognized specialized formats that don't conform to ERC-8004 but are widely used.

Supported Formats:

  • Groth16 zkSNARK Proof - Complete zero-knowledge proofs
  • PLONK Proof - (Future support planned)
  • STARK Proof - (Future support planned)
  • Halo2 Proof - (Future support planned)

When to Use:

  • Existing production systems (e.g., ZyFi protocol)
  • Specialized proof requirements
  • Migration period from custom to standard

Limitations:

  • ⚠️ Limited metadata extraction
  • ⚠️ Manual format interpretation required
  • ⚠️ May not appear in some filtered views

Level 3: Unknown Formats ⚠️ ​

Parse Status: unknown

Valid JSON that doesn't match any recognized pattern.

Handling:

  • Data stored as-is in offchain_request_data / offchain_response_data
  • Displayed as raw JSON in UI
  • No automatic metadata extraction

Recommendation: Consider migrating to Level 1 (Recommended Profile) for better interoperability, or contact the community to add Level 2 support for your format.

Validation Request Profile ​

json
{
  // ============ REQUIRED FIELDS ============
  "agentRegistry": "eip155:84532:0x8004C269D0A5647E51E121FeB226200ECE932d55",
  "agentId": 56,
  "validatorAddress": "eip155:84532:0x4baf957830423f36978039e32d95ee958aa0560c",
  "createdAt": "2025-12-20T05:00:38Z",
  "validationType": "zkml-proof",

  // ============ RECOMMENDED FIELDS ============
  "reasoning": "Request validation for agent rebalancing logic",
  "deadline": "2025-12-21T05:00:38Z",

  // ============ OPTIONAL: VALIDATION TYPE PAYLOADS ============

  // For crypto-economic validations
  "job": {
    "taskDescription": "Validate portfolio rebalancing logic",
    "expectedOutputFormat": "JSON schema with rebalancing recommendations",
    "testDataUri": "ipfs://Qm...",
    "successCriteria": "Optimal allocation within 2% of benchmark"
  },

  // For TEE attestation validations
  "teeRequest": {
    "attestationType": "sgx",
    "requiredEnclave": "ProductID:1,SecurityVersion:2",
    "measurementHash": "0x..."
  },

  // For zkML proof validations
  "zkmlRequest": {
    "circuit": "zyfi-rebalancing-validation",
    "publicInputs": ["4190804445", "1"],
    "verifierAddress": "0x4baf957830423f36978039e32d95ee958aa0560c"
  },

  // ============ OPTIONAL: BOUNTY ============
  "bounty": {
    "amount": "1000000000000000000",
    "token": "eip155:84532:0x...",
    "conditions": "Paid upon successful validation within 24 hours"
  },

  // ============ OPTIONAL: ATTACHMENTS ============
  "attachments": [
    {
      "name": "Test Dataset",
      "uri": "ipfs://Qmxxx...",
      "mimeType": "application/json",
      "size": 50000,
      "description": "Sample portfolio data for rebalancing validation",
      "uploadedAt": "2025-12-20T05:00:00Z"
    }
  ]
}

Required Fields ​

FieldTypeFormatDescription
agentRegistrystringCAIP-10Agent's identity registry address (e.g., eip155:84532:0x8004C...)
agentIdnumberuint256Agent token ID
validatorAddressstringCAIP-10Validator's wallet address (e.g., eip155:84532:0x4baf...)
createdAtstringISO 8601Request creation timestamp
validationTypestringenumOne of: crypto-economic, tee-attestation, zkml-proof
FieldTypeDescription
reasoningstringExplanation of why validation is needed
deadlinestring (ISO 8601)Expected response deadline

Optional Fields by Validation Type ​

Crypto-Economic (job object):

  • taskDescription - What the agent should do
  • expectedOutputFormat - Format specification
  • testDataUri - Test data location
  • successCriteria - How success is measured

TEE Attestation (teeRequest object):

  • attestationType - TEE type (e.g., "sgx", "sev", "tdx")
  • requiredEnclave - Enclave requirements
  • measurementHash - Expected measurement

zkML Proof (zkmlRequest object):

  • circuit - Circuit identifier
  • publicInputs - Public inputs array
  • verifierAddress - Verifier contract address

Validation Response Profile ​

json
{
  // ============ REQUIRED FIELDS ============
  "requestHash": "0x5c1a08c66c0489030f05990a83534280ee08da7cd944dc353bf4b661c5c96657",
  "validatorAddress": "eip155:84532:0x4baf957830423f36978039e32d95ee958aa0560c",
  "agentId": 56,
  "response": 100,
  "createdAt": "2025-12-20T06:00:00Z",

  // ============ RECOMMENDED FIELDS ============
  "result": "passed",
  "reasoning": "Agent successfully passed all validation tests",
  "confidence": 0.95,

  // ============ OPTIONAL: VALIDATION TYPE PROOFS ============

  // For crypto-economic validations
  "executionProof": {
    "outputUri": "ipfs://Qmyyy...",
    "executionTime": "2.5s",
    "resourceUsage": {
      "cpu": "0.8 cores",
      "memory": "512MB",
      "network": "10MB"
    }
  },

  // For TEE attestation validations
  "teeAttestation": {
    "quote": "0x...",
    "quoteSignature": "0x...",
    "reportData": "0x...",
    "timestamp": "2025-12-20T05:30:00Z"
  },

  // For zkML proof validations
  "zkmlProof": {
    "proof": {
      "pi_a": ["...", "...", "1"],
      "pi_b": [[...], [...], ["1", "0"]],
      "pi_c": ["...", "...", "1"],
      "protocol": "groth16",
      "curve": "bn128"
    },
    "publicSignals": ["4190804445", "1"],
    "verifiedAt": "2025-12-20T05:45:00Z"
  },

  // ============ OPTIONAL: ATTACHMENTS ============
  "attachments": [
    {
      "name": "Validation Report",
      "uri": "ipfs://Qmzzz...",
      "mimeType": "application/pdf",
      "size": 2048000,
      "description": "Comprehensive validation report with test results",
      "uploadedAt": "2025-12-20T05:50:00Z"
    }
  ]
}

Required Fields ​

FieldTypeFormatDescription
requestHashstringbytes32 hexHash of the validation request
validatorAddressstringCAIP-10Validator's wallet address
agentIdnumberuint256Agent token ID
responsenumber0-100 (uint8 onchain)Validation score
createdAtstringISO 8601Response creation timestamp
FieldTypeValuesDescription
resultstringpassed, failed, partialValidation result
reasoningstring-Explanation of the result
confidencenumber0.0-1.0Confidence level in the result

Known Custom Formats ​

Groth16 zkSNARK Proof ​

Format Type: groth16_zksnark
Parse Status: known_custom
Use Case: Zero-knowledge proof validation (e.g., ZyFi rebalancing)

json
{
  // ============ PROOF STRUCTURE ============
  "proof": {
    "pi_a": ["8070450532247928943", "1234567890123456789", "1"],
    "pi_b": [
      ["...", "..."],
      ["...", "..."],
      ["1", "0"]
    ],
    "pi_c": ["...", "...", "1"],
    "protocol": "groth16",
    "curve": "bn128"
  },

  // ============ PUBLIC SIGNALS ============
  "publicSignals": ["4190804445", "1"],

  // ============ VERIFICATION INFO ============
  "verifierAddress": "0x4baf957830423f36978039e32d95ee958aa0560c",
  "validationRegistryAddress": "0x8004C269D0A5647E51E121FeB226200ECE932d55",

  // ============ METADATA ============
  "chainId": 84532,
  "circuit": "zyfi-rebalancing-validation",
  "version": "1.0",
  "timestamp": 1734675235991
}

Known Usage:

  • ZyFi Protocol: 8,000+ validations on Base Sepolia
  • Circuit: zyfi-rebalancing-validation
  • Verifier: 0x4baf957830423f36978039e32d95ee958aa0560c

Detection Criteria:

  • Has proof object with pi_a, pi_b, pi_c fields
  • Has publicSignals array
  • Has verifierAddress or validationRegistryAddress

Attachment Pattern ​

Overview ​

Inspired by v1 frontend, the attachment pattern allows adding multiple evidence files to validation requests or responses.

Attachment Object Schema ​

typescript
interface AttachmentFile {
  // Required
  name: string; // Display name (e.g., "Security Audit Report")
  uri: string; // IPFS/HTTPS/Arweave URI
  mimeType: string; // MIME type (e.g., "application/pdf")
  size: number; // File size in bytes

  // Optional
  description?: string; // Context: test environment, tools, timestamps
  uploadedAt?: string; // Upload timestamp (ISO 8601)
}

Supported File Types ​

  • ✅ Documents: PDF, Word, Markdown
  • ✅ Images: PNG, JPEG, WebP, GIF
  • ✅ Videos: MP4, WebM (size limits apply)
  • ✅ Data: JSON, CSV, XML
  • ✅ Archives: ZIP, TAR
  • ✅ Any other format

Usage Examples ​

Example 1: Test Environment Info ​

json
{
  "name": "Load Test Results",
  "uri": "ipfs://QmXxx...",
  "mimeType": "application/json",
  "size": 50000,
  "description": "Conducted on testnet (Sepolia) on 2025-12-20 at 10:00 UTC. Agent handled 1000 req/sec with 99.9% uptime.",
  "uploadedAt": "2025-12-20T10:00:00Z"
}

Example 2: Security Audit ​

json
{
  "name": "Security Audit Report",
  "uri": "ipfs://QmYyy...",
  "mimeType": "application/pdf",
  "size": 2048000,
  "description": "Automated scan using Slither v0.9.6 and Mythril v0.23.15. Manual review by certified auditor.",
  "uploadedAt": "2025-12-20T09:00:00Z"
}

Example 3: Benchmark Data ​

json
{
  "name": "Benchmark Data",
  "uri": "ipfs://QmZzz...",
  "mimeType": "text/csv",
  "size": 100000,
  "description": "10,000 iterations, AWS c5.xlarge instance, Node.js v20.10.0, isolated network environment.",
  "uploadedAt": "2025-12-20T08:00:00Z"
}

Parse Status Indicators ​

When querying validation data via the 8004scan API, each record includes a parse_status field indicating format compliance.

StatusMeaningUI DisplayAction Required
successERC-8004 compliant, no warnings✅ Green checkmarkNone
warningERC-8004 compliant, minor suggestions🟡 Yellow warningReview suggestions
known_customRecognized custom format (e.g., Groth16)🟡 Custom badgeConsider migrating
unknownUnrecognized format⚠️ Grey question markUpdate to standard
errorParse/fetch failure❌ Red errorFix URI/data

Frontend Integration Example ​

typescript
function getStatusBadge(parseStatus: string) {
  switch (parseStatus) {
    case 'success':
      return <Badge variant="success">✅ Standard</Badge>
    case 'warning':
      return <Badge variant="warning">🟡 Warning</Badge>
    case 'known_custom':
      return <Badge variant="info">🟡 Custom Format</Badge>
    case 'unknown':
      return <Badge variant="secondary">⚠️ Unknown</Badge>
    case 'error':
      return <Badge variant="destructive">❌ Error</Badge>
  }
}

Migration Guide ​

From Groth16 to ERC-8004 Standard ​

Current Format (Level 2 - Known Custom):

json
{
  "proof": {...},
  "publicSignals": [...],
  "verifierAddress": "0x4baf957...",
  "chainId": 84532,
  "circuit": "zyfi-rebalancing-validation"
}

Option 1: Minimal Upgrade (Add ERC-8004 envelope):

json
{
  // Add ERC-8004 required fields
  "agentRegistry": "eip155:84532:0x8004C269...",
  "agentId": 56,
  "validatorAddress": "eip155:84532:0x4baf957...",
  "createdAt": "2025-12-20T05:00:38Z",
  "validationType": "zkml-proof",

  // Wrap existing proof in proofData
  "zkmlProof": {
    "proof": {...},
    "publicSignals": [...],
    "protocol": "groth16",
    "circuit": "zyfi-rebalancing-validation"
  }
}

Option 2: Full Upgrade (Use attachments):

json
{
  // ERC-8004 envelope
  "agentRegistry": "eip155:84532:0x8004C269...",
  "agentId": 56,
  "validatorAddress": "eip155:84532:0x4baf957...",
  "createdAt": "2025-12-20T05:00:38Z",
  "validationType": "zkml-proof",

  // Main explanation
  "reasoning": "Agent rebalancing logic validated using zkSNARK proof",

  // Upload proof as separate attachment
  "attachments": [
    {
      "name": "Groth16 Proof",
      "uri": "ipfs://bafkrei...",
      "mimeType": "application/json",
      "size": 4096,
      "description": "ZyFi rebalancing validation circuit proof",
      "uploadedAt": "2025-12-20T05:00:00Z"
    }
  ]
}

Examples ​

Example 1: Complete zkML Validation Request ​

json
{
  "agentRegistry": "eip155:84532:0x8004C269D0A5647E51E121FeB226200ECE932d55",
  "agentId": 56,
  "validatorAddress": "eip155:84532:0x4baf957830423f36978039e32d95ee958aa0560c",
  "createdAt": "2025-12-20T05:00:38Z",
  "validationType": "zkml-proof",

  "reasoning": "Validate agent's portfolio rebalancing algorithm using zero-knowledge proof",
  "deadline": "2025-12-21T05:00:38Z",

  "zkmlRequest": {
    "circuit": "zyfi-rebalancing-validation",
    "publicInputs": ["4190804445", "1"],
    "verifierAddress": "0x4baf957830423f36978039e32d95ee958aa0560c"
  },

  "attachments": [
    {
      "name": "Test Portfolio Data",
      "uri": "ipfs://QmXxx...",
      "mimeType": "application/json",
      "size": 50000,
      "description": "Sample portfolio with 100 assets for validation testing",
      "uploadedAt": "2025-12-20T04:00:00Z"
    }
  ]
}

Example 2: Complete Validation Response with Groth16 Proof ​

json
{
  "requestHash": "0x5c1a08c66c0489030f05990a83534280ee08da7cd944dc353bf4b661c5c96657",
  "validatorAddress": "eip155:84532:0x4baf957830423f36978039e32d95ee958aa0560c",
  "agentId": 56,
  "response": 100,
  "createdAt": "2025-12-20T06:00:00Z",

  "result": "passed",
  "reasoning": "Agent's rebalancing logic validated successfully. All test cases passed.",
  "confidence": 1.0,

  "zkmlProof": {
    "proof": {
      "pi_a": ["8070450532247928943", "1234567890123456789", "1"],
      "pi_b": [
        ["12345...", "67890..."],
        ["11111...", "22222..."],
        ["1", "0"]
      ],
      "pi_c": ["99999...", "88888...", "1"],
      "protocol": "groth16",
      "curve": "bn128"
    },
    "publicSignals": ["4190804445", "1"],
    "verifiedAt": "2025-12-20T05:45:00Z"
  },

  "attachments": [
    {
      "name": "Validation Report",
      "uri": "ipfs://QmYyy...",
      "mimeType": "application/pdf",
      "size": 1024000,
      "description": "Comprehensive validation report with detailed test results and methodology",
      "uploadedAt": "2025-12-20T05:50:00Z"
    }
  ]
}

See Also ​