openapi: 3.1.0
info:
  title: TetraFi API
  version: 1.0.0
  description: |
    TetraFi is a non-custodial settlement protocol for institutional stablecoin OTC trading.
    This API enables programmatic access to RFQ submission, quote management, settlement execution,
    compliance verification, and audit trail retrieval.
  contact:
    name: TetraFi Developer Support
    email: dev@tetrafi.io
    url: https://tetrafi.io/docs
  license:
    name: Proprietary
    url: https://tetrafi.io/terms

servers:
  - url: https://api.tetrafi.io/v1
    description: Production
  - url: https://sandbox.tetrafi.io/v1
    description: Sandbox (no real funds)

security:
  - bearerAuth: []

tags:
  - name: RFQ
    description: Request for Quote operations
  - name: Quotes
    description: Quote management
  - name: Settlement
    description: Settlement execution and monitoring
  - name: Compliance
    description: Compliance verification
  - name: Audit
    description: WORM audit trail
  - name: Solver
    description: Solver onboarding and management

paths:
  /rfq:
    post:
      operationId: submitRFQ
      summary: Submit RFQ
      description: Broadcast a Request for Quote to competing solvers. Solvers respond with sealed pricing bids within the auction window.
      tags: [RFQ]
      x-codeSamples:
        - lang: TypeScript
          source: |
            const rfq = await tetrafi.rfq.create({
              pair: "USDC/USDT",
              side: "buy",
              amount: "1000000.00",
              corridor: "ethereum-optimism",
            });
        - lang: Python
          source: |
            rfq = client.rfq.create(
                pair="USDC/USDT",
                side="buy",
                amount="1000000.00",
            )
        - lang: cURL
          source: |
            curl -X POST https://api.tetrafi.io/v1/rfq \
              -H "Authorization: Bearer sk_live_..." \
              -d '{"pair":"USDC/USDT","side":"buy","amount":"1000000.00"}'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [pair, side, amount]
              properties:
                pair:
                  type: string
                  example: "USDC/USDT"
                  description: Trading pair
                side:
                  type: string
                  enum: [buy, sell]
                  example: "buy"
                  description: Trade direction
                amount:
                  type: string
                  example: "1000000.00"
                  description: Amount in base currency (decimal string)
                corridor:
                  type: string
                  example: "ethereum-optimism"
                  description: Settlement corridor (chain pair)
                maxSlippage:
                  type: number
                  example: 0.001
                  description: Maximum acceptable slippage (0.001 = 0.1%)
                complianceAttestation:
                  type: string
                  description: Hex-encoded compliance attestation hash
            example:
              pair: "USDC/USDT"
              side: "buy"
              amount: "1000000.00"
              corridor: "ethereum-optimism"
              maxSlippage: 0.001
      responses:
        "201":
          description: RFQ created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RFQ"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

  /quotes/{rfqId}:
    get:
      operationId: getQuotes
      summary: Get Quotes
      description: Retrieve all competing solver quotes for a given RFQ. Includes price, fill confidence, and time-to-live.
      tags: [Quotes]
      x-codeSamples:
        - lang: TypeScript
          source: |
            const quotes = await tetrafi.rfq.getQuotes("rfq_abc123");
            quotes.forEach(q => console.log(`${q.solverId}: ${q.price}`));
        - lang: Python
          source: |
            quotes = client.rfq.get_quotes("rfq_abc123")
            for q in quotes:
                print(f"{q.solver_id}: {q.price}")
      parameters:
        - name: rfqId
          in: path
          required: true
          schema:
            type: string
          description: RFQ identifier
      responses:
        "200":
          description: Quotes retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  quotes:
                    type: array
                    items:
                      $ref: "#/components/schemas/Quote"
        "404":
          $ref: "#/components/responses/NotFound"

  /quotes/{quoteId}/accept:
    post:
      operationId: acceptQuote
      summary: Accept Quote
      description: Accept a solver's quote and trigger escrow creation on the origin chain. Initiates the DvP settlement flow.
      tags: [Settlement]
      x-codeSamples:
        - lang: TypeScript
          source: |
            const settlement = await tetrafi.quotes.accept("qt_xyz789");
            console.log("Settlement:", settlement.id, settlement.status);
      parameters:
        - name: quoteId
          in: path
          required: true
          schema:
            type: string
          description: Quote identifier
      responses:
        "200":
          description: Quote accepted, settlement initiated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Settlement"
        "409":
          description: Quote expired or already accepted

  /settlements/{id}:
    get:
      operationId: getSettlement
      summary: Settlement Details
      description: Retrieve settlement details including escrow status, cross-chain proof, and final transaction hashes.
      tags: [Settlement]
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Settlement identifier
      responses:
        "200":
          description: Settlement details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Settlement"
        "404":
          $ref: "#/components/responses/NotFound"

  /compliance/status:
    get:
      operationId: getComplianceStatus
      summary: Compliance Status
      description: Check the compliance status of the authenticated participant. Returns KYC/KYB verification, sanctions screening, and Travel Rule readiness.
      tags: [Compliance]
      responses:
        "200":
          description: Compliance status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ComplianceStatus"

  /audit/{tradeId}:
    get:
      operationId: getAuditTrail
      summary: Audit Trail
      description: Retrieve the complete WORM evidence ledger for a trade - compliance checks, quotes, execution, and settlement proof.
      tags: [Audit]
      parameters:
        - name: tradeId
          in: path
          required: true
          schema:
            type: string
          description: Trade identifier
      responses:
        "200":
          description: Audit entries
          content:
            application/json:
              schema:
                type: object
                properties:
                  entries:
                    type: array
                    items:
                      $ref: "#/components/schemas/AuditEntry"

  /solver/register:
    post:
      operationId: registerSolver
      summary: Register as Solver
      description: Submit solver registration with KYB details and pricing engine configuration. Triggers compliance verification.
      tags: [Solver]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, supportedPairs, walletAddress]
              properties:
                name:
                  type: string
                  example: "Acme Market Making"
                supportedPairs:
                  type: array
                  items:
                    type: string
                  example: ["USDC/USDT", "USDC/EURC"]
                minTradeSize:
                  type: string
                  example: "10000"
                maxTradeSize:
                  type: string
                  example: "10000000"
                walletAddress:
                  type: string
                  example: "0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18"
      responses:
        "201":
          description: Registration submitted
          content:
            application/json:
              schema:
                type: object
                properties:
                  solverId:
                    type: string
                    example: "solver_abc123"
                  status:
                    type: string
                    enum: [pending_review, approved, rejected]
                    example: "pending_review"
                  estimatedApproval:
                    type: string
                    example: "2-5 business days"

  /ws/solver/stream:
    get:
      operationId: solverStream
      summary: Solver Quote Stream (WebSocket)
      description: |
        WebSocket endpoint for solvers to receive real-time RFQ broadcasts.
        Connect, authenticate, subscribe to channels, and receive events.

        **Connection flow:**
        1. Connect to `wss://api.tetrafi.io/v1/ws/solver/stream`
        2. Send auth: `{ "type": "auth", "token": "sk_live_..." }`
        3. Subscribe: `{ "type": "subscribe", "channels": ["rfq.*"] }`
        4. Receive RFQ events and submit quotes
      tags: [Solver]
      responses:
        "101":
          description: WebSocket upgrade successful

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: "API key with `sk_live_` (production) or `sk_test_` (sandbox) prefix"

  schemas:
    RFQ:
      type: object
      properties:
        id:
          type: string
          example: "rfq_abc123"
        pair:
          type: string
          example: "USDC/USDT"
        side:
          type: string
          enum: [buy, sell]
          example: "buy"
        amount:
          type: string
          example: "1000000.00"
        corridor:
          type: string
          example: "ethereum-optimism"
        status:
          type: string
          enum: [pending, quoting, accepted, expired]
          example: "quoting"
        createdAt:
          type: string
          format: date-time
          example: "2026-04-03T10:00:00Z"
        expiresAt:
          type: string
          format: date-time
          example: "2026-04-03T10:00:05Z"

    Quote:
      type: object
      properties:
        id:
          type: string
          example: "qt_xyz789"
        rfqId:
          type: string
          example: "rfq_abc123"
        solverId:
          type: string
          example: "solver_a"
        price:
          type: string
          example: "0.9997"
        ttl:
          type: integer
          example: 30
          description: Time-to-live in seconds
        confidence:
          type: number
          example: 0.99
          description: Fill confidence (0-1)
        createdAt:
          type: string
          format: date-time

    Settlement:
      type: object
      properties:
        id:
          type: string
          example: "stl_def456"
        rfqId:
          type: string
          example: "rfq_abc123"
        quoteId:
          type: string
          example: "qt_xyz789"
        status:
          type: string
          enum: [pending, escrow_locked, filling, complete, failed, refunded]
          example: "complete"
        originTxHash:
          type: string
          example: "0x1234...abcd"
        destinationTxHash:
          type: string
          example: "0x5678...efgh"
        settledAt:
          type: string
          format: date-time

    ComplianceStatus:
      type: object
      properties:
        address:
          type: string
          example: "0x742d35Cc..."
        isCompliant:
          type: boolean
          example: true
        attestationHash:
          type: string
          example: "0xabcd..."
        kycStatus:
          type: string
          enum: [pending, verified, expired, rejected]
          example: "verified"
        travelRuleReady:
          type: boolean
          example: true
        expiresAt:
          type: string
          format: date-time

    AuditEntry:
      type: object
      properties:
        tradeId:
          type: string
          example: "rfq_abc123"
        type:
          type: string
          enum: [compliance_check, quote_submitted, quote_accepted, escrow_locked, settlement_complete]
          example: "settlement_complete"
        timestamp:
          type: string
          format: date-time
        data:
          type: object
          description: Event-specific payload
        hash:
          type: string
          example: "0x9876..."
          description: WORM evidence hash

    Error:
      type: object
      properties:
        type:
          type: string
          enum: [invalid_request, authentication_error, rate_limit_error, api_error]
          example: "invalid_request"
        code:
          type: string
          example: "pair_not_supported"
        message:
          type: string
          example: "The trading pair DOGE/SHIB is not supported."
        param:
          type: string
          example: "pair"
        doc_url:
          type: string
          example: "https://tetrafi.io/docs/errors#pair_not_supported"

  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                $ref: "#/components/schemas/Error"
    RateLimited:
      description: Rate limit exceeded
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds to wait before retrying
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                $ref: "#/components/schemas/Error"
