{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "midnight-nft-collection/1",
  "title": "NFT metadata for Midnight: collection file",
  "type": "object",
  "required": ["schema", "name", "symbol", "supply", "state", "revision", "midnight", "items"],
  "properties": {
    "schema": { "const": "midnight-nft-collection/1" },
    "name": { "type": "string", "minLength": 1, "maxLength": 64 },
    "symbol": { "type": "string", "pattern": "^\\S{1,12}$" },
    "description": { "type": "string" },
    "image": { "$ref": "#/$defs/uri" },
    "image_sha256": { "$ref": "#/$defs/sha256" },
    "banner_image": { "$ref": "#/$defs/uri" },
    "banner_sha256": { "$ref": "#/$defs/sha256" },
    "external_link": { "$ref": "#/$defs/uri" },
    "supply": { "type": "integer", "minimum": 1 },
    "state": { "enum": ["sealed", "revealed"] },
    "revision": { "type": "integer", "minimum": 1 },
    "licence": { "type": "string" },
    "midnight": {
      "type": "object",
      "required": ["network", "kind", "decimals"],
      "properties": { "network": { "type": "string" }, "kind": { "enum": ["unshielded", "shielded", "contract"] }, "decimals": { "const": 0 } }
    },
    "royalty": {
      "type": "object",
      "required": ["bps", "enforcement"],
      "properties": { "bps": { "type": "integer", "minimum": 0, "maximum": 10000 }, "recipient": { "type": "string" }, "enforcement": { "enum": ["market", "voluntary", "none"] } }
    },
    "traits": {
      "type": "object",
      "additionalProperties": { "type": "object", "additionalProperties": { "type": "integer", "minimum": 1 } }
    },
    "bundle": {
      "type": "object",
      "required": ["uri", "sha256"],
      "properties": { "uri": { "$ref": "#/$defs/uri" }, "sha256": { "$ref": "#/$defs/sha256" }, "bytes": { "type": "integer", "minimum": 1 } }
    },
    "items": { "type": "array", "minItems": 1 },
    "provenance": { "type": "object" }
  },
  "dependentRequired": { "image": ["image_sha256"], "banner_image": ["banner_sha256"] },
  "allOf": [
    {
      "if": { "properties": { "state": { "const": "revealed" } } },
      "then": {
        "properties": {
          "items": {
            "items": {
              "type": "object",
              "required": ["id", "name", "metadata", "metadata_sha256", "image", "image_sha256"],
              "properties": {
                "id": { "type": "integer" },
                "domainSep": { "$ref": "#/$defs/sha256" },
                "name": { "type": "string", "minLength": 1 },
                "metadata": { "$ref": "#/$defs/uri" },
                "metadata_sha256": { "$ref": "#/$defs/sha256" },
                "image": { "$ref": "#/$defs/uri" },
                "image_sha256": { "$ref": "#/$defs/sha256" }
              }
            }
          },
          "provenance": {
            "required": ["sealed_sha256", "beacon_block", "offset", "salts"],
            "properties": {
              "sealed_sha256": { "$ref": "#/$defs/sha256" },
              "beacon_block": { "type": "object", "required": ["height", "hash"], "properties": { "height": { "type": "integer" }, "hash": { "type": "string", "pattern": "^(0x)?[0-9a-f]{64}$" } } },
              "offset": { "type": "integer", "minimum": 0 },
              "salts": { "type": "array", "items": { "$ref": "#/$defs/sha256" } }
            }
          }
        }
      }
    },
    {
      "if": { "properties": { "state": { "const": "sealed" } } },
      "then": {
        "required": ["provenance"],
        "properties": {
          "items": {
            "items": {
              "type": "object",
              "required": ["id"],
              "properties": { "id": { "type": "integer" }, "domainSep": { "$ref": "#/$defs/sha256" } },
              "additionalProperties": false
            }
          },
          "provenance": {
            "required": ["method", "beacon", "unminted", "placeholder", "commitments"],
            "properties": {
              "method": { "const": "offset" },
              "beacon": { "type": "object", "required": ["chain", "rule", "time"], "properties": { "chain": { "type": "string" }, "network": { "type": "string" }, "rule": { "const": "first-block-at-or-after" }, "time": { "type": "string", "format": "date-time" } } },
              "unminted": { "enum": ["burned", "open"] },
              "placeholder": { "type": "object", "required": ["image", "image_sha256"], "properties": { "image": { "$ref": "#/$defs/uri" }, "image_sha256": { "$ref": "#/$defs/sha256" } } },
              "commitments": { "type": "array", "items": { "$ref": "#/$defs/sha256" }, "uniqueItems": true },
              "salts": false
            }
          }
        }
      }
    },
    {
      "if": { "properties": { "state": { "const": "revealed" }, "midnight": { "properties": { "kind": { "const": "shielded" } } } }, "required": ["state", "midnight"] },
      "then": { "required": ["bundle"] }
    }
  ],
  "additionalProperties": true,
  "$comment": "Rules a schema cannot express and the validator checks: items.length equals supply; ids are unique and in order; domainSeps are unique; commitments and salts have one entry per slot; trait counts do not exceed the supply.",
  "$defs": {
    "sha256": { "type": "string", "pattern": "^[0-9a-f]{64}$" },
    "uri": { "type": "string", "pattern": "^(ipfs|ar|https)://\\S+$" }
  }
}
