asyncapi: 3.0.0

info:
  title: Tripport — Solana Stream WS (fixed non-vote transaction feed)
  version: 0.3.0-e15-measured
  description: |
    Push-only Solana transaction feed. Triport holds one upstream Yellowstone
    subscription for non-vote transactions and forwards every transaction to
    every connected client as a compact JSON frame, plus a stats frame once
    per second.

    The server applies no per-client filter. Client messages are read only
    to detect that the connection closed; their content is ignored, and a
    message larger than 1 KiB closes the connection. Measured 2026-09-22: a
    client that sent a Yellowstone `SubscribeRequest` for `slots` received a
    transaction frame.

    Delivery is at-most-once with no replay; a slow client's frames are
    dropped when its buffer is full. The server sends a WebSocket ping every
    30 s.

    Error envelope: WSErrorFrame from `_shared.yaml`; a key without the pro
    tier gets one error frame and close code 4003 after the upgrade, an
    expired trial gets 4030. A missing or unknown key is refused with HTTP 401
    before the upgrade.

x-tier-vector-version: 1
x-ws-close-codes:
  $ref: '_shared.yaml#/x-ws-close-codes'

defaultContentType: application/json

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

channels:

  /ws/sol-stream:
    address: /ws/sol-stream
    description: |
      Push-only feed. Open the connection with an API key; `tx` and `stats`
      frames start arriving without any client message. Every client
      receives the same feed.
    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 on upgrade.
    messages:
      TxFrame:     {$ref: '#/components/messages/TxFrame'}
      StatsFrame:  {$ref: '#/components/messages/StatsFrame'}
      WSError:     {$ref: '_shared.yaml#/components/messages/WSError'}

operations:

  receiveFeed:
    action: receive
    channel: {$ref: '#/channels/~1ws~1sol-stream'}
    summary: Server-pushed transaction and stats frames.
    description: |
      Server → client. One `tx` frame per non-vote transaction received from
      upstream and one `stats` frame per second. There is no client → server
      operation: the server does not apply subscription or filter messages.
    x-tier-required: pro
    x-tier-category: sol_yellowstone
    messages:
      - {$ref: '#/channels/~1ws~1sol-stream/messages/TxFrame'}
      - {$ref: '#/channels/~1ws~1sol-stream/messages/StatsFrame'}
      - {$ref: '#/channels/~1ws~1sol-stream/messages/WSError'}

components:

  schemas:

    TxFramePayload:
      type: object
      required: [t, l, s]
      properties:
        t:    {type: string, const: tx}
        l:    {type: integer, format: int64, description: Slot of the transaction.}
        s:    {type: string, description: Transaction signature, base58.}
        f:    {type: integer, format: int64, description: Fee in lamports; omitted when zero or unknown.}
        e:    {type: boolean, description: Present and true only for a failed transaction.}
        urps: {type: number, description: Always 0 on tx frames.}
        brps: {type: number, description: Always 0 on tx frames.}
        drop: {type: number, description: Always 0 on tx frames.}
        cc:   {type: integer, description: Always 0 on tx frames.}

    StatsFramePayload:
      type: object
      required: [t, urps, brps, drop, cc]
      properties:
        t:    {type: string, const: stats}
        urps: {type: number, description: Transactions received from upstream in the last second.}
        brps: {type: number, description: Frames broadcast in the last second.}
        drop: {type: number, description: Share of frames dropped for slow clients in the last second, percent.}
        cc:   {type: integer, description: Clients connected to the hub.}

  messages:

    TxFrame:
      title: Transaction frame
      summary: One non-vote transaction (slot, signature, fee).
      payload:
        $ref: '#/components/schemas/TxFramePayload'

    StatsFrame:
      title: Stats frame
      summary: Hub throughput counters, once per second.
      payload:
        $ref: '#/components/schemas/StatsFramePayload'
