{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://nkips.org/nkip-0006/schema.json",
  "title": "NKIP-0006 PGP chat over Nostr v2",
  "description": "SHAPE ONLY: the v2 event (without id/sig), the signed inner payload, the hello body and the out-of-band invite. Not expressible here and checked by tools/nkip0006.py instead: the wildcard recipient key id, the tag derivation, signer == from, fingerprint(pubKey) == fp / from, total UTF-8 length of the padded inner payload a multiple of 256 bytes, ts window, and a fresh pubkey per event (a property across events).",
  "$defs": {
    "fingerprint": {
      "type": "string",
      "pattern": "^([0-9A-F]{40}|[0-9A-F]{64})$"
    },
    "secret": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "event": {
      "type": "object",
      "required": [
        "kind",
        "created_at",
        "tags",
        "content"
      ],
      "properties": {
        "kind": {
          "const": 9061
        },
        "created_at": {
          "type": "integer",
          "minimum": 0
        },
        "pubkey": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$",
          "description": "A fresh key for every event; never reused (checked across events, outside the schema)."
        },
        "tags": {
          "type": "array",
          "minItems": 1,
          "maxItems": 3,
          "prefixItems": [
            {
              "type": "array",
              "prefixItems": [
                {
                  "const": "z"
                },
                {
                  "type": "string",
                  "pattern": "^[0-9a-f]{32}$"
                }
              ],
              "items": false,
              "minItems": 2
            }
          ],
          "items": {
            "type": "array",
            "oneOf": [
              {
                "prefixItems": [
                  {
                    "const": "expiration"
                  },
                  {
                    "type": "string",
                    "pattern": "^[0-9]{1,16}$"
                  }
                ],
                "items": false,
                "minItems": 2
              },
              {
                "prefixItems": [
                  {
                    "const": "nonce"
                  },
                  {
                    "type": "string",
                    "pattern": "^[0-9]{1,20}$"
                  },
                  {
                    "type": "string",
                    "pattern": "^[0-9]{1,3}$"
                  }
                ],
                "items": false,
                "minItems": 3
              }
            ]
          },
          "description": "z first; then at most one expiration (NIP-40) and one nonce (NIP-13). Uniqueness and the 30-day floor are checked by the tool."
        },
        "content": {
          "type": "string",
          "pattern": "^-----BEGIN PGP MESSAGE-----\\r?\\n\\r?\\n"
        }
      }
    },
    "inner": {
      "type": "object",
      "required": [
        "v",
        "type",
        "id",
        "ts",
        "from",
        "to",
        "body",
        "pad"
      ],
      "additionalProperties": false,
      "properties": {
        "v": {
          "const": "nkip06/2"
        },
        "type": {
          "enum": [
            "msg",
            "hello",
            "rekey"
          ]
        },
        "id": {
          "type": "string",
          "pattern": "^[0-9a-f]{32}$"
        },
        "ts": {
          "type": "integer",
          "minimum": 0
        },
        "from": {
          "$ref": "#/$defs/fingerprint"
        },
        "to": {
          "$ref": "#/$defs/fingerprint"
        },
        "body": {},
        "pad": {
          "type": "string",
          "pattern": "^ *$",
          "description": "Spaces chosen so the whole serialized payload is a multiple of 256 bytes (checked outside the schema)."
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "type": {
                "const": "msg"
              }
            }
          },
          "then": {
            "properties": {
              "body": {
                "type": "string"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "hello"
              }
            }
          },
          "then": {
            "properties": {
              "body": {
                "$ref": "#/$defs/hello"
              }
            }
          }
        },
        {
          "if": {
            "properties": {
              "type": {
                "const": "rekey"
              }
            }
          },
          "then": {
            "properties": {
              "body": {
                "type": "object",
                "required": [
                  "chan"
                ],
                "properties": {
                  "chan": {
                    "$ref": "#/$defs/secret"
                  }
                }
              }
            }
          }
        }
      ]
    },
    "hello": {
      "type": "object",
      "required": [
        "name",
        "pubKey",
        "chan"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64,
          "pattern": "^[^\\x00-\\x1f\\x7f]*$"
        },
        "pubKey": {
          "type": "string",
          "pattern": "-----BEGIN PGP PUBLIC KEY BLOCK-----"
        },
        "chan": {
          "$ref": "#/$defs/secret"
        }
      }
    },
    "invite": {
      "type": "object",
      "required": [
        "ver",
        "name",
        "pubKey",
        "fp",
        "intro"
      ],
      "properties": {
        "ver": {
          "const": 2
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64,
          "pattern": "^[^\\x00-\\x1f\\x7f]*$"
        },
        "pubKey": {
          "type": "string",
          "pattern": "-----BEGIN PGP PUBLIC KEY BLOCK-----"
        },
        "fp": {
          "$ref": "#/$defs/fingerprint"
        },
        "intro": {
          "$ref": "#/$defs/secret"
        },
        "v1": {
          "type": "boolean",
          "default": false
        }
      }
    }
  }
}
