{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://synor.io/schemas/contract.json",
  "title": "Synor Contract SDK",
  "description": "Smart contract deployment, interaction, and ABI management",

  "$defs": {
    "ContractConfig": {
      "type": "object",
      "allOf": [{ "$ref": "common.json#/$defs/SynorConfig" }]
    },

    "ContractAddress": {
      "$ref": "common.json#/$defs/Address"
    },

    "AbiType": {
      "type": "string",
      "enum": [
        "uint8", "uint16", "uint32", "uint64", "uint128", "uint256",
        "int8", "int16", "int32", "int64", "int128", "int256",
        "bool", "string", "bytes", "bytes32", "address",
        "tuple", "array"
      ]
    },

    "AbiParameter": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "type": { "$ref": "#/$defs/AbiType" },
        "indexed": { "type": "boolean" },
        "components": {
          "type": "array",
          "items": { "$ref": "#/$defs/AbiParameter" }
        }
      },
      "required": ["name", "type"]
    },

    "AbiFunction": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "type": {
          "type": "string",
          "enum": ["function", "constructor", "fallback", "receive"]
        },
        "stateMutability": {
          "type": "string",
          "enum": ["pure", "view", "nonpayable", "payable"]
        },
        "inputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/AbiParameter" }
        },
        "outputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/AbiParameter" }
        }
      },
      "required": ["name", "type", "inputs"]
    },

    "AbiEvent": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "type": { "const": "event" },
        "anonymous": { "type": "boolean" },
        "inputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/AbiParameter" }
        }
      },
      "required": ["name", "type", "inputs"]
    },

    "AbiError": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "type": { "const": "error" },
        "inputs": {
          "type": "array",
          "items": { "$ref": "#/$defs/AbiParameter" }
        }
      },
      "required": ["name", "type"]
    },

    "ABI": {
      "type": "array",
      "items": {
        "oneOf": [
          { "$ref": "#/$defs/AbiFunction" },
          { "$ref": "#/$defs/AbiEvent" },
          { "$ref": "#/$defs/AbiError" }
        ]
      }
    },

    "ContractInterface": {
      "type": "object",
      "properties": {
        "address": { "$ref": "#/$defs/ContractAddress" },
        "abi": { "$ref": "#/$defs/ABI" },
        "functions": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/AbiFunction" }
        },
        "events": {
          "type": "object",
          "additionalProperties": { "$ref": "#/$defs/AbiEvent" }
        }
      },
      "required": ["abi"]
    },

    "DeployRequest": {
      "type": "object",
      "properties": {
        "bytecode": { "type": "string", "description": "Contract bytecode (hex)" },
        "abi": { "$ref": "#/$defs/ABI" },
        "args": {
          "type": "array",
          "description": "Constructor arguments"
        },
        "value": { "$ref": "common.json#/$defs/Amount" },
        "gasLimit": { "type": "integer" },
        "gasPrice": { "$ref": "common.json#/$defs/Amount" }
      },
      "required": ["bytecode"]
    },

    "DeployResponse": {
      "type": "object",
      "properties": {
        "address": { "$ref": "#/$defs/ContractAddress" },
        "txHash": { "$ref": "common.json#/$defs/TxHash" },
        "blockNumber": { "type": "integer" },
        "gasUsed": { "type": "integer" }
      },
      "required": ["address", "txHash"]
    },

    "CallRequest": {
      "type": "object",
      "properties": {
        "contract": { "$ref": "#/$defs/ContractAddress" },
        "method": { "type": "string" },
        "args": { "type": "array" },
        "blockNumber": {
          "oneOf": [
            { "type": "integer" },
            { "type": "string", "enum": ["latest", "pending", "earliest"] }
          ]
        }
      },
      "required": ["contract", "method"]
    },

    "CallResponse": {
      "type": "object",
      "properties": {
        "result": {},
        "decoded": { "type": "object" }
      },
      "required": ["result"]
    },

    "SendRequest": {
      "type": "object",
      "properties": {
        "contract": { "$ref": "#/$defs/ContractAddress" },
        "method": { "type": "string" },
        "args": { "type": "array" },
        "value": { "$ref": "common.json#/$defs/Amount" },
        "gasLimit": { "type": "integer" },
        "gasPrice": { "$ref": "common.json#/$defs/Amount" },
        "nonce": { "type": "integer" }
      },
      "required": ["contract", "method"]
    },

    "SendResponse": {
      "type": "object",
      "properties": {
        "txHash": { "$ref": "common.json#/$defs/TxHash" },
        "blockNumber": { "type": "integer" },
        "gasUsed": { "type": "integer" },
        "status": { "type": "boolean" },
        "events": {
          "type": "array",
          "items": { "$ref": "#/$defs/Event" }
        }
      },
      "required": ["txHash"]
    },

    "Event": {
      "type": "object",
      "properties": {
        "address": { "$ref": "#/$defs/ContractAddress" },
        "name": { "type": "string" },
        "signature": { "type": "string" },
        "topics": {
          "type": "array",
          "items": { "type": "string" }
        },
        "data": { "type": "string" },
        "decoded": { "type": "object" },
        "blockNumber": { "type": "integer" },
        "txHash": { "$ref": "common.json#/$defs/TxHash" },
        "logIndex": { "type": "integer" }
      },
      "required": ["address", "topics", "data"]
    },

    "EventFilter": {
      "type": "object",
      "properties": {
        "address": { "$ref": "#/$defs/ContractAddress" },
        "topics": {
          "type": "array",
          "items": {
            "oneOf": [
              { "type": "string" },
              { "type": "array", "items": { "type": "string" } },
              { "type": "null" }
            ]
          }
        },
        "fromBlock": {
          "oneOf": [
            { "type": "integer" },
            { "type": "string", "enum": ["latest", "pending", "earliest"] }
          ]
        },
        "toBlock": {
          "oneOf": [
            { "type": "integer" },
            { "type": "string", "enum": ["latest", "pending", "earliest"] }
          ]
        }
      }
    },

    "GetEventsRequest": {
      "type": "object",
      "properties": {
        "contract": { "$ref": "#/$defs/ContractAddress" },
        "filter": { "$ref": "#/$defs/EventFilter" },
        "eventName": { "type": "string" }
      },
      "required": ["contract"]
    },

    "GetEventsResponse": {
      "type": "object",
      "properties": {
        "events": {
          "type": "array",
          "items": { "$ref": "#/$defs/Event" }
        }
      },
      "required": ["events"]
    },

    "EncodeCallRequest": {
      "type": "object",
      "properties": {
        "method": { "type": "string" },
        "args": { "type": "array" },
        "abi": { "$ref": "#/$defs/ABI" }
      },
      "required": ["method", "abi"]
    },

    "EncodeCallResponse": {
      "type": "object",
      "properties": {
        "data": { "type": "string", "description": "Encoded calldata (hex)" },
        "selector": { "type": "string", "description": "Function selector (4 bytes hex)" }
      },
      "required": ["data", "selector"]
    },

    "DecodeResultRequest": {
      "type": "object",
      "properties": {
        "data": { "type": "string" },
        "method": { "type": "string" },
        "abi": { "$ref": "#/$defs/ABI" }
      },
      "required": ["data", "method", "abi"]
    },

    "DecodeResultResponse": {
      "type": "object",
      "properties": {
        "decoded": {},
        "raw": { "type": "array" }
      },
      "required": ["decoded"]
    },

    "Subscription": {
      "type": "object",
      "properties": {
        "id": { "type": "string" },
        "contract": { "$ref": "#/$defs/ContractAddress" },
        "eventName": { "type": "string" },
        "filter": { "$ref": "#/$defs/EventFilter" },
        "createdAt": { "$ref": "common.json#/$defs/Timestamp" }
      },
      "required": ["id", "contract"]
    }
  }
}
