asyncapi: 3.0.0

info:
  title: Tripport — Solana JSON-RPC Pub/Sub WS
  version: 0.2.0-api-vector-s3
  description: |
    Solana JSON-RPC over WebSocket — 9 subscribe methods covered:
      accountSubscribe / signatureSubscribe / logsSubscribe / programSubscribe /
      slotSubscribe / rootSubscribe / blockSubscribe / voteSubscribe /
      slotsUpdatesSubscribe

    Subscribe envelope, server-push envelope and error frames mirror those
    in `_shared.yaml`. WS close codes 4001/4003/4029/4030 are emitted per
    PLAN_TECH §11.

    Source of truth for tier annotations: `proxy-agg/config/tier-matrix.yaml`
    (gen-tier-extensions will eventually wire `x-tier-required` /
    `x-rate-limit-rps` per operation).

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:
    address: /ws/sol
    description: |
      Single WebSocket endpoint for Solana JSON-RPC Pub/Sub. The `method`
      field on each frame disambiguates subscribe vs. notify across the 9
      supported method families.
    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:
      AccountSubscribe:           {$ref: '#/components/messages/AccountSubscribe'}
      SignatureSubscribe:         {$ref: '#/components/messages/SignatureSubscribe'}
      LogsSubscribe:              {$ref: '#/components/messages/LogsSubscribe'}
      ProgramSubscribe:           {$ref: '#/components/messages/ProgramSubscribe'}
      SlotSubscribe:              {$ref: '#/components/messages/SlotSubscribe'}
      RootSubscribe:              {$ref: '#/components/messages/RootSubscribe'}
      BlockSubscribe:             {$ref: '#/components/messages/BlockSubscribe'}
      VoteSubscribe:              {$ref: '#/components/messages/VoteSubscribe'}
      SlotsUpdatesSubscribe:      {$ref: '#/components/messages/SlotsUpdatesSubscribe'}
      AccountUnsubscribe:         {$ref: '#/components/messages/AccountUnsubscribe'}
      SignatureUnsubscribe:       {$ref: '#/components/messages/SignatureUnsubscribe'}
      LogsUnsubscribe:            {$ref: '#/components/messages/LogsUnsubscribe'}
      ProgramUnsubscribe:         {$ref: '#/components/messages/ProgramUnsubscribe'}
      SlotUnsubscribe:            {$ref: '#/components/messages/SlotUnsubscribe'}
      RootUnsubscribe:            {$ref: '#/components/messages/RootUnsubscribe'}
      BlockUnsubscribe:           {$ref: '#/components/messages/BlockUnsubscribe'}
      VoteUnsubscribe:            {$ref: '#/components/messages/VoteUnsubscribe'}
      SlotsUpdatesUnsubscribe:    {$ref: '#/components/messages/SlotsUpdatesUnsubscribe'}
      AccountNotification:        {$ref: '#/components/messages/AccountNotification'}
      SignatureNotification:      {$ref: '#/components/messages/SignatureNotification'}
      LogsNotification:           {$ref: '#/components/messages/LogsNotification'}
      ProgramNotification:        {$ref: '#/components/messages/ProgramNotification'}
      SlotNotification:           {$ref: '#/components/messages/SlotNotification'}
      RootNotification:           {$ref: '#/components/messages/RootNotification'}
      BlockNotification:          {$ref: '#/components/messages/BlockNotification'}
      VoteNotification:           {$ref: '#/components/messages/VoteNotification'}
      SlotsUpdatesNotification:   {$ref: '#/components/messages/SlotsUpdatesNotification'}
      SubscribeAck:               {$ref: '_shared.yaml#/components/messages/SubscribeAck'}
      WSError:                    {$ref: '_shared.yaml#/components/messages/WSError'}

operations:

  sendSubscribe:
    action: send
    channel: {$ref: '#/channels/~1ws~1sol'}
    summary: Send a Subscribe request (one of 9 sol pub/sub methods).
    description: |
      Client → server. Server responds with `SubscribeAck` carrying the
      subscription id. Per-method tier requirements are annotated on the
      individual `*Subscribe` message components (`x-tier-required`),
      mirroring `tier-matrix.yaml::sol_ws_pubsub.allowed_methods` at the
      lowest unlocking tier: free covers 2 families (account, signature);
      basic adds 4 more (logs, program, slot, root); pro+ unlocks the
      remaining 3 (block, vote, slotsUpdates). An attempt below the
      required tier yields WS close 4003 with the canonical `forbidden`
      error frame (see `_shared.yaml::WSErrorFrame`).
    x-tier-category: sol_ws_pubsub
    x-tier-method-allowlist-ref: proxy-agg/config/tier-matrix.yaml#/tiers/*/features/sol_ws_pubsub/allowed_methods
    messages:
      - {$ref: '#/channels/~1ws~1sol/messages/AccountSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SignatureSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/LogsSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/ProgramSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/RootSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/BlockSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/VoteSubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotsUpdatesSubscribe'}

  sendUnsubscribe:
    action: send
    channel: {$ref: '#/channels/~1ws~1sol'}
    summary: Send an Unsubscribe request — releases the subscription id.
    description: 'Client → server. Server replies with `{"result": true}` (encoded as `SubscribeAck`).'
    messages:
      - {$ref: '#/channels/~1ws~1sol/messages/AccountUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SignatureUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/LogsUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/ProgramUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/RootUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/BlockUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/VoteUnsubscribe'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotsUpdatesUnsubscribe'}

  receiveNotification:
    action: receive
    channel: {$ref: '#/channels/~1ws~1sol'}
    summary: Server-pushed notification frames for active subscriptions.
    description: |
      Server → client. Push interval / payload shape are per-method (see
      each message's payload schema). WSError may interrupt with one of the
      canonical close codes before the connection ends.
    messages:
      - {$ref: '#/channels/~1ws~1sol/messages/AccountNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/SignatureNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/LogsNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/ProgramNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/RootNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/BlockNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/VoteNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/SlotsUpdatesNotification'}
      - {$ref: '#/channels/~1ws~1sol/messages/WSError'}

components:

  schemas:

    SolSubscribeParams:
      type: object
      description: Common Solana pubsub subscribe params (commitment + optional filters).
      properties:
        commitment:
          type: string
          enum: [processed, confirmed, finalized]
          default: confirmed
        encoding:
          type: string
          enum: [base58, base64, base64+zstd, jsonParsed]

  messages:

    # ─── account ───
    AccountSubscribe:
      title: accountSubscribe
      x-tier-required: free
      x-tier-category: sol_ws_pubsub
      summary: Subscribe to account changes by pubkey.
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: accountSubscribe}
              params:
                type: array
                minItems: 1
                maxItems: 2
                items:
                  oneOf:
                    - {type: string, description: "base58 pubkey"}
                    - {$ref: '#/components/schemas/SolSubscribeParams'}

    AccountUnsubscribe:
      title: accountUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: accountUnsubscribe}

    AccountNotification:
      title: accountNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: accountNotification}

    # ─── signature ───
    SignatureSubscribe:
      title: signatureSubscribe
      x-tier-required: free
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: signatureSubscribe}

    SignatureUnsubscribe:
      title: signatureUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: signatureUnsubscribe}

    SignatureNotification:
      title: signatureNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: signatureNotification}

    # ─── logs ───
    LogsSubscribe:
      title: logsSubscribe
      x-tier-required: basic
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: logsSubscribe}

    LogsUnsubscribe:
      title: logsUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: logsUnsubscribe}

    LogsNotification:
      title: logsNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: logsNotification}

    # ─── program ───
    ProgramSubscribe:
      title: programSubscribe
      x-tier-required: basic
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: programSubscribe}

    ProgramUnsubscribe:
      title: programUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: programUnsubscribe}

    ProgramNotification:
      title: programNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: programNotification}

    # ─── slot ───
    SlotSubscribe:
      title: slotSubscribe
      x-tier-required: basic
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: slotSubscribe}

    SlotUnsubscribe:
      title: slotUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: slotUnsubscribe}

    SlotNotification:
      title: slotNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: slotNotification}

    # ─── root ───
    RootSubscribe:
      title: rootSubscribe
      x-tier-required: basic
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: rootSubscribe}

    RootUnsubscribe:
      title: rootUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: rootUnsubscribe}

    RootNotification:
      title: rootNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: rootNotification}

    # ─── block ───
    BlockSubscribe:
      title: blockSubscribe
      x-tier-required: pro
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: blockSubscribe}

    BlockUnsubscribe:
      title: blockUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: blockUnsubscribe}

    BlockNotification:
      title: blockNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: blockNotification}

    # ─── vote ───
    VoteSubscribe:
      title: voteSubscribe
      x-tier-required: pro
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: voteSubscribe}

    VoteUnsubscribe:
      title: voteUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: voteUnsubscribe}

    VoteNotification:
      title: voteNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: voteNotification}

    # ─── slotsUpdates ───
    SlotsUpdatesSubscribe:
      title: slotsUpdatesSubscribe
      x-tier-required: pro
      x-tier-category: sol_ws_pubsub
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/SubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: slotsUpdatesSubscribe}

    SlotsUpdatesUnsubscribe:
      title: slotsUpdatesUnsubscribe
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/UnsubscribeRequest'
          - type: object
            properties:
              method: {type: string, const: slotsUpdatesUnsubscribe}

    SlotsUpdatesNotification:
      title: slotsUpdatesNotification
      payload:
        allOf:
          - $ref: '_shared.yaml#/components/schemas/StreamEvent'
          - type: object
            properties:
              method: {type: string, const: slotsUpdatesNotification}
