asyncapi: 3.0.0

info:
  title: Tripport — BSC JSON-RPC Pub/Sub WS
  version: 0.1.0-n4-bsc-02
  description: |
    BSC JSON-RPC over WebSocket. The measured surface contains exactly
    three subscription types: `newHeads`, `logs`, and
    `newPendingTransactions`. Client requests use `eth_subscribe` and
    `eth_unsubscribe`; notifications use `eth_subscription`.

    Availability evidence is the per-host BSC matrix. HTTP `eth_getLogs`
    range limits do not apply to the independent `logs` subscription.

defaultContentType: application/json

servers:
  production:
    $ref: '_shared.yaml#/servers/production'
  staging:
    $ref: '_shared.yaml#/servers/staging'

channels:
  /ws/bsc:
    address: /ws/bsc
    description: BSC WebSocket JSON-RPC pub/sub.
    bindings:
      ws:
        bindingVersion: 0.1.0
        query:
          type: object
          properties:
            api-key:
              type: string
              description: Legacy static API key; the `x-token` header is the primary form.
    messages:
      BscSubscribe:             {$ref: '#/components/messages/BscSubscribe'}
      BscUnsubscribe:           {$ref: '#/components/messages/BscUnsubscribe'}
      BscSubscriptionAck:       {$ref: '#/components/messages/BscSubscriptionAck'}
      NewHeadsNotification:     {$ref: '#/components/messages/NewHeadsNotification'}
      LogsNotification:         {$ref: '#/components/messages/LogsNotification'}
      NewPendingTxNotification: {$ref: '#/components/messages/NewPendingTxNotification'}
      WSError:                  {$ref: '_shared.yaml#/components/messages/WSError'}

operations:
  sendSubscribe:
    action: send
    channel: {$ref: '#/channels/~1ws~1bsc'}
    summary: Send eth_subscribe for one of the three measured subscription types.
    messages:
      - {$ref: '#/channels/~1ws~1bsc/messages/BscSubscribe'}

  sendUnsubscribe:
    action: send
    channel: {$ref: '#/channels/~1ws~1bsc'}
    summary: Send eth_unsubscribe to release a subscription id.
    messages:
      - {$ref: '#/channels/~1ws~1bsc/messages/BscUnsubscribe'}

  receiveNotification:
    action: receive
    channel: {$ref: '#/channels/~1ws~1bsc'}
    summary: Receive subscription acknowledgements, notifications, and errors.
    messages:
      - {$ref: '#/channels/~1ws~1bsc/messages/BscSubscriptionAck'}
      - {$ref: '#/channels/~1ws~1bsc/messages/NewHeadsNotification'}
      - {$ref: '#/channels/~1ws~1bsc/messages/LogsNotification'}
      - {$ref: '#/channels/~1ws~1bsc/messages/NewPendingTxNotification'}
      - {$ref: '#/channels/~1ws~1bsc/messages/WSError'}

components:
  schemas:
    BscSubscriptionType:
      type: string
      enum: [newHeads, logs, newPendingTransactions]

    LogsFilter:
      type: object
      description: Optional filter passed after `logs`.
      properties:
        address:
          oneOf:
            - {type: string, description: single contract}
            - {type: array, items: {type: string}, description: multiple contracts}
        topics:
          type: array
          description: Up to four indexed-topic slots; null is a wildcard.
          items:
            oneOf:
              - {type: string}
              - {type: array, items: {type: string}}
              - {type: 'null'}

    NewPendingTxOptions:
      type: object
      description: Optional pending-transaction delivery options.
      properties:
        includeFullTx:
          type: boolean
          default: false
          description: When true, request full transaction bodies instead of hashes.

    BscSubscribeRequest:
      type: object
      required: [jsonrpc, id, method, params]
      properties:
        jsonrpc: {type: string, const: '2.0'}
        id:
          oneOf: [{type: integer}, {type: string}]
        method: {type: string, const: eth_subscribe}
        params:
          type: array
          minItems: 1
          maxItems: 2
          items:
            oneOf:
              - {$ref: '#/components/schemas/BscSubscriptionType'}
              - {$ref: '#/components/schemas/LogsFilter'}
              - {$ref: '#/components/schemas/NewPendingTxOptions'}

    BscUnsubscribeRequest:
      type: object
      required: [jsonrpc, id, method, params]
      properties:
        jsonrpc: {type: string, const: '2.0'}
        id:
          oneOf: [{type: integer}, {type: string}]
        method: {type: string, const: eth_unsubscribe}
        params:
          type: array
          minItems: 1
          maxItems: 1
          items: {type: string, description: subscription id}

    BscSubscriptionAckPayload:
      type: object
      required: [jsonrpc, id, result]
      properties:
        jsonrpc: {type: string, const: '2.0'}
        id:
          oneOf: [{type: integer}, {type: string}]
        result: {type: string, description: subscription id}

    BscBlockHeader:
      type: object
      description: Block header pushed by `newHeads`.
      properties:
        number:           {type: string, description: hex block height}
        hash:             {type: string}
        parentHash:       {type: string}
        nonce:            {type: string}
        sha3Uncles:       {type: string}
        logsBloom:        {type: string}
        transactionsRoot: {type: string}
        stateRoot:        {type: string}
        receiptsRoot:     {type: string}
        miner:            {type: string}
        difficulty:       {type: string}
        extraData:        {type: string}
        gasLimit:         {type: string}
        gasUsed:          {type: string}
        timestamp:        {type: string}
        baseFeePerGas:    {type: [string, 'null']}

    BscLog:
      type: object
      description: Event log pushed by a `logs` subscription.
      properties:
        address:          {type: string}
        topics:           {type: array, items: {type: string}}
        data:             {type: string}
        blockNumber:      {type: string}
        transactionHash:  {type: string}
        transactionIndex: {type: string}
        blockHash:        {type: string}
        logIndex:         {type: string}
        removed:          {type: boolean}

    NotificationEnvelope:
      type: object
      required: [jsonrpc, method, params]
      properties:
        jsonrpc: {type: string, const: '2.0'}
        method: {type: string, const: eth_subscription}
        params:
          type: object
          required: [subscription, result]
          properties:
            subscription: {type: string}
            result: {}

  messages:
    BscSubscribe:
      title: eth_subscribe
      summary: Subscribe to newHeads, logs, or newPendingTransactions.
      payload:
        $ref: '#/components/schemas/BscSubscribeRequest'

    BscUnsubscribe:
      title: eth_unsubscribe
      summary: Unsubscribe by subscription id.
      payload:
        $ref: '#/components/schemas/BscUnsubscribeRequest'

    BscSubscriptionAck:
      title: eth_subscribe response
      summary: Returns the subscription id.
      payload:
        $ref: '#/components/schemas/BscSubscriptionAckPayload'

    NewHeadsNotification:
      title: newHeads notification
      summary: Server-pushed block header.
      payload:
        allOf:
          - $ref: '#/components/schemas/NotificationEnvelope'
          - type: object
            properties:
              params:
                type: object
                properties:
                  result: {$ref: '#/components/schemas/BscBlockHeader'}

    LogsNotification:
      title: logs notification
      summary: Server-pushed matching event log.
      payload:
        allOf:
          - $ref: '#/components/schemas/NotificationEnvelope'
          - type: object
            properties:
              params:
                type: object
                properties:
                  result: {$ref: '#/components/schemas/BscLog'}

    NewPendingTxNotification:
      title: newPendingTransactions notification
      summary: Server-pushed pending transaction hash or body.
      payload:
        allOf:
          - $ref: '#/components/schemas/NotificationEnvelope'
          - type: object
            properties:
              params:
                type: object
                properties:
                  result:
                    oneOf:
                      - {type: string, description: transaction hash}
                      - {type: object, description: full transaction body}
