{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://starkscan.co/schemas/starkscan-portable-verification-receipt-v1.schema.json",
  "title": "Starkscan portable exact-verification receipt",
  "type": "object",
  "additionalProperties": false,
  "required": ["schemaVersion", "algorithm", "keyId", "evidence", "signature"],
  "properties": {
    "schemaVersion": {"const": "starkscan-portable-verification-receipt-v1"},
    "algorithm": {"const": "Ed25519"},
    "keyId": {"type": "string", "pattern": "^[A-Za-z0-9._:-]{1,128}$"},
    "evidence": {
      "type": "object",
      "additionalProperties": false,
      "required": ["jobId", "chainId", "classHash", "receiptId", "verification", "sourceArchiveDigest", "toolchainPolicyId", "candidateDigest", "declaration", "proofScope", "notProofOf", "issuedAt"],
      "properties": {
        "jobId": {"type": "string", "pattern": "^vrf_[a-z0-9]{24,40}$"},
        "chainId": {"enum": ["SN_MAIN", "SN_SEPOLIA"]},
        "classHash": {"type": "string", "pattern": "^0x(?:[1-7][0-9a-f]{0,62}|[89a-f][0-9a-f]{0,61}|80{12}(?:0[0-9a-f]{49}|10[0-9a-f]{48}|110{48}))$"},
        "receiptId": {
          "type": "integer",
          "minimum": 1,
          "description": "Mathematically integral JSON decimal and exponent spellings are normalized to the canonical unsigned base-10 integer before receipt validation and signature verification."
        },
        "verification": {"const": "verified_exact"},
        "sourceArchiveDigest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
        "toolchainPolicyId": {"const": "starkscan-exact-v25"},
        "candidateDigest": {"type": "string", "pattern": "^sha256:[0-9a-f]{64}$"},
        "declaration": {
          "type": "object",
          "additionalProperties": false,
          "required": ["blockNumber", "blockHash", "transactionHash", "compiledClassHash"],
          "properties": {
            "blockNumber": {
              "type": "integer",
              "minimum": 0,
              "description": "Mathematically integral JSON decimal and exponent spellings are normalized to the canonical unsigned base-10 integer before receipt validation and signature verification."
            },
            "blockHash": {"type": "string", "pattern": "^0x(?:[1-7][0-9a-f]{0,62}|[89a-f][0-9a-f]{0,61}|80{12}(?:0[0-9a-f]{49}|10[0-9a-f]{48}|110{48}))$"},
            "transactionHash": {"type": "string", "pattern": "^0x(?:[1-7][0-9a-f]{0,62}|[89a-f][0-9a-f]{0,61}|80{12}(?:0[0-9a-f]{49}|10[0-9a-f]{48}|110{48}))$"},
            "compiledClassHash": {"type": "string", "pattern": "^0x(?:[1-7][0-9a-f]{0,62}|[89a-f][0-9a-f]{0,61}|80{12}(?:0[0-9a-f]{49}|10[0-9a-f]{48}|110{48}))$"}
          }
        },
        "proofScope": {"const": "exact_source_rebuild_equals_finalized_declared_class"},
        "notProofOf": {
          "type": "array",
          "minItems": 5,
          "maxItems": 5,
          "uniqueItems": true,
          "items": {"enum": ["security", "audit", "official_attribution", "deployment_configuration", "current_address_class"]}
        },
        "issuedAt": {"type": "string", "format": "date-time"}
      }
    },
    "signature": {"type": "string", "pattern": "^[A-Za-z0-9_-]{86}$"}
  }
}
