{
  "language": "Solidity",
  "sources": {
    "contracts/ASCheckpointAnchor.sol": {
      "content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity 0.8.30;\n\n/// @notice AN01-F01 development contract. Publishes commitments, not consent.\ncontract ASCheckpointAnchor {\n    error UnauthorizedPublisher();\n    error UnauthorizedGuardian();\n    error Halted();\n    error InvalidSequence();\n    error ConflictingCheckpoint();\n    error InvalidCommitment();\n\n    event ASCheckpointAnchored(\n        bytes32 indexed identityCommitment,\n        uint64 indexed sequence,\n        bytes32 indexed checkpointCommitment,\n        bytes32 previousCheckpointCommitment,\n        bytes32 asGenesisCommitment,\n        bytes32 anchorId,\n        address publisher\n    );\n    event ASHalted(address indexed guardian);\n\n    bytes32 public immutable asGenesisCommitment;\n    bytes32 public immutable anchorIntentCommitment;\n    bytes32 public immutable identityCommitment;\n    address public immutable publisher;\n    address public immutable guardian;\n    bool public halted;\n\n    struct Checkpoint {\n        bytes32 commitment;\n        bytes32 previous;\n        bytes32 anchorId;\n    }\n    mapping(uint64 => Checkpoint) private checkpoints;\n    uint64 private headSequence;\n    bytes32 private headCommitment;\n\n    constructor(bytes32 asGenesisCommitment_, bytes32 anchorIntentCommitment_,\n                bytes32 identityCommitment_, address publisher_, address guardian_) {\n        if (asGenesisCommitment_ == bytes32(0) || anchorIntentCommitment_ == bytes32(0)\n            || identityCommitment_ == bytes32(0) || publisher_ == address(0)\n            || guardian_ == address(0) || publisher_ == guardian_) revert InvalidCommitment();\n        asGenesisCommitment = asGenesisCommitment_;\n        anchorIntentCommitment = anchorIntentCommitment_;\n        identityCommitment = identityCommitment_;\n        publisher = publisher_;\n        guardian = guardian_;\n    }\n\n    function head() external view returns (uint64 sequence, bytes32 checkpointCommitment) {\n        return (headSequence, headCommitment);\n    }\n\n    function checkpointAt(uint64 sequence) external view returns (\n        bytes32 checkpointCommitment, bytes32 previousCheckpointCommitment, bytes32 anchorId\n    ) {\n        Checkpoint storage c = checkpoints[sequence];\n        return (c.commitment, c.previous, c.anchorId);\n    }\n\n    function anchor(uint64 sequence, bytes32 checkpointCommitment,\n                    bytes32 previousCheckpointCommitment) external returns (bytes32 anchorId) {\n        if (msg.sender != publisher) revert UnauthorizedPublisher();\n        if (halted) revert Halted();\n        if (sequence == 0 || sequence > 9007199254740991) revert InvalidSequence();\n        if (checkpointCommitment == bytes32(0)) revert InvalidCommitment();\n        if (sequence <= headSequence) {\n            Checkpoint storage saved = checkpoints[sequence];\n            if (saved.commitment != checkpointCommitment || saved.previous != previousCheckpointCommitment)\n                revert ConflictingCheckpoint();\n            return saved.anchorId;\n        }\n        if (sequence != headSequence + 1 || previousCheckpointCommitment != headCommitment)\n            revert InvalidSequence();\n        anchorId = keccak256(abi.encode(\n            keccak256(\"XCIM_AS01_EVM_ANCHOR_V1\"), block.chainid, address(this),\n            anchorIntentCommitment, identityCommitment, asGenesisCommitment,\n            sequence, checkpointCommitment, previousCheckpointCommitment\n        ));\n        checkpoints[sequence] = Checkpoint(checkpointCommitment, previousCheckpointCommitment, anchorId);\n        headSequence = sequence;\n        headCommitment = checkpointCommitment;\n        emit ASCheckpointAnchored(identityCommitment, sequence, checkpointCommitment,\n            previousCheckpointCommitment, asGenesisCommitment, anchorId, publisher);\n    }\n\n    function halt() external {\n        if (msg.sender != guardian) revert UnauthorizedGuardian();\n        if (!halted) {\n            halted = true;\n            emit ASHalted(guardian);\n        }\n    }\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "viaIR": false,
    "evmVersion": "paris",
    "metadata": {
      "bytecodeHash": "none",
      "appendCBOR": false
    },
    "outputSelection": {
      "*": {
        "": [
          "ast"
        ],
        "*": [
          "abi",
          "evm.bytecode.object",
          "evm.deployedBytecode.object",
          "evm.deployedBytecode.immutableReferences"
        ]
      }
    }
  }
}
