openapi: 3.1.0
info:
  title: RUFF Explorer API
  version: 1.1.0
  description: >-
    Public read-only index of RandomnessHub on Arc mainnet (5042), hub
    0x398F839B85DA2945D26EBBD1B3a4784A2F1389AB, starting at block 23355234.
    Proof reports are computed in the background and stored by the explorer. HTTP requests
    never initiate RPC verification. A report records the block and time of its check, not a
    promise about later contract state. The explorer is not a light client.
servers:
  - url: https://explorer.jerdog.xyz/api/v1
paths:
  /status:
    get:
      operationId: getStatus
      summary: Read the index checkpoint and aggregate counts
      responses:
        '200':
          description: Checkpoint; HTTP success alone does not establish freshness.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Status'
        default:
          $ref: '#/components/responses/Error'
  /requests:
    get:
      operationId: listRequests
      summary: List requests in descending sequence order
      description: Unknown or repeated query parameters are rejected.
      parameters:
        - name: before
          in: query
          description: Exclusive sequence cursor, from 1 to 18446744073709551615.
          schema:
            $ref: '#/components/schemas/Sequence'
        - name: consumer
          in: query
          description: Filter by the exact consumer contract address.
          schema:
            $ref: '#/components/schemas/Address'
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 50
            default: 12
      responses:
        '200':
          description: A page and checkpoint read in one database snapshot.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Status'
                  - type: object
                    required: [kind, rows, next]
                    properties:
                      kind:
                        const: list
                      rows:
                        type: array
                        maxItems: 50
                        items:
                          $ref: '#/components/schemas/Row'
                      next:
                        description: Exclusive cursor for the next page, or null at the end.
                        oneOf:
                          - $ref: '#/components/schemas/Sequence'
                          - type: 'null'
        default:
          $ref: '#/components/responses/Error'
  /requests/{sequence}:
    get:
      operationId: getRequest
      summary: Read one indexed request
      parameters:
        - name: sequence
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/Sequence'
      responses:
        '200':
          description: Request with its checkpoint.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Detail'
        default:
          $ref: '#/components/responses/Error'
  /requests/{sequence}/proof:
    get:
      operationId: getStoredProof
      summary: Read a saved verification report without starting work
      parameters:
        - name: sequence
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/Sequence'
      responses:
        '200':
          description: Stored proof state; verification is null before fulfillment.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Snapshot'
                  - type: object
                    required: [kind, sequence, verification]
                    properties:
                      kind:
                        const: proof
                      sequence:
                        $ref: '#/components/schemas/Sequence'
                      verification:
                        $ref: '#/components/schemas/Verification'
        default:
          $ref: '#/components/responses/Error'
  /transactions/{hash}/requests:
    get:
      operationId: findTransactionRequests
      summary: Find requests created, fulfilled or expired by a transaction
      parameters:
        - name: hash
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/Bytes32'
      responses:
        '200':
          description: One detail or multiple matches; more than 100 matches returns 422.
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/Detail'
                  - allOf:
                      - $ref: '#/components/schemas/Snapshot'
                      - type: object
                        required: [kind, rows]
                        properties:
                          kind:
                            const: matches
                          rows:
                            type: array
                            minItems: 2
                            maxItems: 100
                            items:
                              $ref: '#/components/schemas/Row'
        default:
          $ref: '#/components/responses/Error'
components:
  responses:
    Error:
      description: >-
        400 invalid input; 404 not indexed or unknown route; 405 unsupported method;
        422 too many transaction matches; 429 caller limit reached; 503 index unavailable or busy.
        URLs are limited to 512 characters. Encoded paths and request bodies are not accepted.
      headers:
        Retry-After:
          description: Suggested delay in seconds, when supplied for 429 or 503.
          schema:
            type: string
      content:
        application/json:
          schema:
            type: object
            required: [error]
            properties:
              error:
                type: string
        text/plain:
          schema:
            type: string
  schemas:
    Uint:
      type: string
      pattern: '^(0|[1-9][0-9]*)$'
      description: Unsigned integer encoded as decimal text to preserve precision.
    Sequence:
      type: string
      pattern: '^[1-9][0-9]{0,19}$'
      description: uint64 decimal string, from 1 to 18446744073709551615.
    Address:
      type: string
      pattern: '^0x[0-9a-fA-F]{40}$'
    Bytes32:
      type: string
      pattern: '^0x[0-9a-fA-F]{64}$'
    Snapshot:
      type: object
      required: [chainId, hub, block, at, index]
      properties:
        chainId:
          type: integer
          minimum: 1
        hub:
          $ref: '#/components/schemas/Address'
        block:
          $ref: '#/components/schemas/Uint'
        at:
          type: integer
          minimum: 0
          description: Checkpoint time in Unix milliseconds; zero before initialization.
        index:
          type: object
          required: [status, head, lag, error]
          properties:
            status:
              type: string
              enum: [ready, catching_up, stale, unavailable]
            head:
              $ref: '#/components/schemas/Uint'
            lag:
              $ref: '#/components/schemas/Uint'
            error:
              enum: [null, RPC_UNAVAILABLE, INDEX_INCONSISTENT]
        hubConfig:
          type: object
          required: [defaultFee, activeLane, remainingLinks, at]
          properties:
            defaultFee:
              description: Default callback fee in native USDC base units (18 decimals).
              type: [string, 'null']
            activeLane:
              type: [integer, 'null']
            remainingLinks:
              type: [string, 'null']
            at:
              description: Configuration read time in Unix milliseconds, null before the first read.
              type: [integer, 'null']
    Status:
      allOf:
        - $ref: '#/components/schemas/Snapshot'
        - type: object
          required: [total, pending, paused]
          properties:
            total:
              $ref: '#/components/schemas/Uint'
            pending:
              type: integer
              minimum: 0
            paused:
              type: boolean
    Row:
      type: object
      required: [sequence, request, requestedTx]
      properties:
        sequence:
          $ref: '#/components/schemas/Sequence'
        request:
          type: object
          required:
            [consumer, laneId, index, blockNumber, callbackGas, feePaid, userContribution, status, callbackFailed]
          properties:
            consumer:
              $ref: '#/components/schemas/Address'
            laneId:
              type: integer
              minimum: 1
              maximum: 4294967295
            index:
              $ref: '#/components/schemas/Sequence'
            blockNumber:
              $ref: '#/components/schemas/Uint'
            callbackGas:
              type: integer
              minimum: 0
              maximum: 4294967295
            feePaid:
              allOf:
                - $ref: '#/components/schemas/Uint'
              description: Native USDC base units with 18 decimals; not the ERC-20 representation.
            userContribution:
              $ref: '#/components/schemas/Bytes32'
            status:
              type: integer
              enum: [1, 2, 3]
              description: 1 pending, 2 fulfilled, 3 expired.
            callbackFailed:
              type: boolean
        requestedTx:
          $ref: '#/components/schemas/Bytes32'
        random:
          allOf:
            - $ref: '#/components/schemas/Bytes32'
          description: Present only for fulfilled requests. All-zero bytes are a valid result.
        revealedTx:
          $ref: '#/components/schemas/Bytes32'
        fulfilledBlock:
          $ref: '#/components/schemas/Uint'
        expiredTx:
          $ref: '#/components/schemas/Bytes32'
    Detail:
      allOf:
        - $ref: '#/components/schemas/Snapshot'
        - $ref: '#/components/schemas/Row'
        - type: object
          required: [kind]
          properties:
            kind:
              const: detail
            verification:
              $ref: '#/components/schemas/Verification'
    Verification:
      oneOf:
        - type: 'null'
        - type: object
          required: [status, report]
          properties:
            status:
              enum: [pending, verified, failed, incomplete, unavailable]
            report:
              oneOf:
                - type: 'null'
                - type: object
                  required:
                    [
                      schema,
                      verifierVersion,
                      checkedBy,
                      checkedAt,
                      chainId,
                      hub,
                      deploymentBlock,
                      checkedBlock,
                      checkedBlockHash,
                      verification,
                      evidence,
                    ]
                  properties:
                    schema:
                      const: ruff-explorer-proof-v2
                    verifierVersion:
                      const: ruff-hub@0.2.0
                    checkedBy:
                      const: RUFF Explorer
                    checkedAt:
                      type: string
                      format: date-time
                    chainId:
                      type: integer
                    hub:
                      $ref: '#/components/schemas/Address'
                    deploymentBlock:
                      $ref: '#/components/schemas/Uint'
                    checkedBlock:
                      $ref: '#/components/schemas/Uint'
                    checkedBlockHash:
                      $ref: '#/components/schemas/Bytes32'
                    verification:
                      type: object
                      description: Historical ok, complete, commitment and failures, plus a separate currentState check at checkedBlock. Large integers are decimal strings.
                    evidence:
                      type: object
                      description: Raw LanePublished, Requested and Revealed events, their positions and hashes, request block hash and any previously verified anchor. No private RPC credentials.
