openapi: "3.1.0"
info:
  title: H33 Privacy & Commerce API
  version: "1.0.0"
  description: |
    Privacy-preserving proof infrastructure. Verify identity, compliance, eligibility,
    and financial properties without possessing user data.

    Every endpoint returns a 32-byte commitment anchored on Solana devnet,
    signed by three post-quantum signature families (ML-DSA-65, FALCON-512, SLH-DSA-128f).

    The proof replaces disclosure.
  contact:
    name: H33 Engineering
    email: support@h33.ai
    url: https://h33.ai
  license:
    name: Proprietary
    identifier: LicenseRef-H33-Proprietary

servers:
  - url: https://privacy.h33.ai
    description: Production
  - url: https://api.h33.ai
    description: Production (alias)

tags:
  - name: Identity
    description: Age, biometric, and identity attribute proofs
  - name: KYC & Compliance
    description: KYC tier, jurisdiction, accredited investor, and regulatory compliance proofs
  - name: DeFi
    description: Balance range, collateral ratio, and portfolio threshold proofs
  - name: Commerce
    description: Invoice creation, settlement, and payment verification
  - name: Verification
    description: Proof retrieval and commitment verification
  - name: Infrastructure
    description: Health checks and chain connectivity

paths:
  /health:
    get:
      tags: [Infrastructure]
      summary: Service health check
      operationId: getHealth
      responses:
        "200":
          description: Service is healthy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthResponse"

  /api/v1/chain/status:
    get:
      tags: [Infrastructure]
      summary: Multi-chain connectivity status
      operationId: getChainStatus
      description: Returns live block heights and connectivity for all 10 supported chains.
      responses:
        "200":
          description: Chain status for all networks
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChainStatusResponse"

  # ── Identity ──

  /api/v1/privacy/age:
    post:
      tags: [Identity]
      summary: Prove age meets threshold
      operationId: proveAge
      description: |
        Proves a user is at least N years old without revealing their birthdate.
        The birth_timestamp is used to generate the STARK proof but is never stored,
        logged, or included in any output.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AgeProofRequest"
      responses:
        "200":
          description: STARK proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/identity:
    post:
      tags: [Identity]
      summary: Prove identity attributes
      operationId: proveIdentity
      description: |
        Proves identity attributes (biometric binding, DID, MFA factor count,
        trust score) without revealing the underlying personal data.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IdentityProofRequest"
      responses:
        "200":
          description: STARK proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Claim not satisfiable
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # ── KYC & Compliance ──

  /api/v1/privacy/kyc-status:
    post:
      tags: [KYC & Compliance]
      summary: Prove KYC tier achieved
      operationId: proveKycStatus
      description: |
        Proves a user has achieved a KYC verification tier (basic, enhanced, or full)
        without revealing which documents were provided or their contents.
        KYC tier proven, documents hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/KycStatusRequest"
      responses:
        "200":
          description: KYC status proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: KYC claim not satisfied
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/jurisdiction:
    post:
      tags: [KYC & Compliance]
      summary: Prove jurisdiction membership
      operationId: proveJurisdiction
      description: |
        Proves a user's jurisdiction is in an allowed set without revealing
        which jurisdiction they are in. Jurisdiction proven, address hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/JurisdictionRequest"
      responses:
        "200":
          description: Jurisdiction proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/accredited:
    post:
      tags: [KYC & Compliance]
      summary: Prove accredited investor status
      operationId: proveAccredited
      description: |
        Proves accredited investor status via composite proof: age meets minimum,
        jurisdiction is allowed, and net worth or income tier qualifies.
        Accredited status proven, wealth details hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AccreditedInvestorRequest"
      responses:
        "200":
          description: Accredited investor proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Accreditation claim not satisfied
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/compliance:
    post:
      tags: [KYC & Compliance]
      summary: Prove regulatory compliance
      operationId: proveCompliance
      description: |
        Proves a transaction or entity satisfies a compliance policy
        (OFAC, AML, KYC, travel rule) without revealing raw identity data.
        Compliance proven, raw identity minimized.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ComplianceProofRequest"
      responses:
        "200":
          description: Compliance proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Compliance check failed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # ── DeFi ──

  /api/v1/privacy/defi/balance-range:
    post:
      tags: [DeFi]
      summary: Prove balance is within a range
      operationId: proveBalanceRange
      description: |
        Proves a wallet balance falls within [min_balance, max_balance]
        without revealing the exact amount. Balance in range, exact amount hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BalanceRangeRequest"
      responses:
        "200":
          description: Balance range proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Balance not in range
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/defi/collateral:
    post:
      tags: [DeFi]
      summary: Prove collateral ratio meets minimum
      operationId: proveCollateral
      description: |
        Proves collateral-to-debt ratio meets a protocol's minimum requirement
        without revealing the collateral or debt values.
        Ratio proven, values hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CollateralRatioRequest"
      responses:
        "200":
          description: Collateral ratio proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Collateral ratio insufficient
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/privacy/defi/portfolio-threshold:
    post:
      tags: [DeFi]
      summary: Prove portfolio exceeds threshold
      operationId: provePortfolioThreshold
      description: |
        Proves portfolio value tier exceeds a minimum threshold without revealing
        holdings, composition, or exact value.
        Portfolio qualifies, holdings hidden.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PortfolioThresholdRequest"
      responses:
        "200":
          description: Portfolio threshold proof generated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShieldProofResponse"
        "400":
          description: Portfolio does not meet threshold
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  # ── Commerce ──

  /api/v1/commerce/health:
    get:
      tags: [Commerce]
      summary: Commerce service health
      operationId: getCommerceHealth
      responses:
        "200":
          description: Commerce service status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceHealthResponse"

  /api/v1/commerce/invoice:
    post:
      tags: [Commerce]
      summary: Create an invoice
      operationId: createInvoice
      description: |
        Creates a PQ-signed invoice with a QR payload for display.
        The customer scans and pays. The merchant never sees customer identity.
      security:
        - ApiKeyAuth: []
      parameters:
        - name: X-Idempotency-Key
          in: header
          schema:
            type: string
          description: Prevents duplicate invoice creation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateInvoiceRequest"
      responses:
        "200":
          description: Invoice created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/InvoiceResponse"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "401":
          description: Invalid API key
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /api/v1/commerce/settlement/{commitment}:
    get:
      tags: [Commerce]
      summary: Check settlement status
      operationId: getSettlement
      security:
        - ApiKeyAuth: []
      parameters:
        - name: commitment
          in: path
          required: true
          schema:
            type: string
          description: 32-byte invoice commitment (hex)
      responses:
        "200":
          description: Settlement status
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SettlementResponse"
        "404":
          description: Invoice not found

  /api/v1/commerce/verify:
    post:
      tags: [Verification]
      summary: Verify a commerce payment attestation
      operationId: verifyCommerce
      description: No API key required. Anyone can verify.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VerifyRequest"
      responses:
        "200":
          description: Verification result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CommerceVerifyResponse"

  # ── Proof Retrieval & Verification ──

  /api/v1/privacy/proof/{id}:
    get:
      tags: [Verification]
      summary: Retrieve a cached proof
      operationId: getProof
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: Hex-encoded 32-byte cachee key
      responses:
        "200":
          description: Proof details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProofRetrievalResponse"
        "404":
          description: Proof not found

  /api/v1/privacy/verify:
    post:
      tags: [Verification]
      summary: Verify a privacy commitment
      operationId: verifyPrivacy
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VerifyRequest"
      responses:
        "200":
          description: Verification result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PrivacyVerifyResponse"

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: H33 API key (required for commerce invoice/settlement endpoints)

  schemas:
    # ── Responses ──

    ShieldProofResponse:
      type: object
      description: Universal proof response. Same shape for all privacy endpoints.
      required: [commitment, claim_satisfied, attestation_type, expires_at, cachee_key, proof_size_bytes, solana_program_id, chain]
      properties:
        commitment:
          type: string
          description: 32-byte commitment (hex). The on-chain anchor.
          example: "8c086a145a088efa760ce35a10f564d07c4d6eaf0906fc8458bc81c6fc38cba3"
        claim_satisfied:
          type: boolean
          description: Whether the underlying claim was satisfied
          example: true
        attestation_type:
          type: string
          description: H33-74 computation type
          enum: ["0x60", "0x61", "0x62", "0x63"]
          example: "0x61"
        expires_at:
          type: integer
          format: int64
          description: Unix timestamp when this attestation expires
        cachee_key:
          type: string
          description: 32-byte Cachee retrieval key (hex)
        proof_size_bytes:
          type: integer
          description: Size of the STARK proof in bytes
        solana_program_id:
          type: string
          description: Solana program ID for on-chain verification
          example: "5eAwAv59YqpnSBMj59KeXhDdLqmn99HBYSjrb6jcLbC5"
        solscan_url:
          type: string
          format: uri
          description: Solscan explorer link
        chain:
          type: string
          description: Target chain
          example: "solana-devnet"

    HealthResponse:
      type: object
      properties:
        service:
          type: string
          example: "h33-xeon-api"
        status:
          type: string
          example: "healthy"

    CommerceHealthResponse:
      type: object
      properties:
        status:
          type: string
          example: "healthy"
        service:
          type: string
          example: "h33-commerce"
        circuits:
          type: integer
          example: 35
        tests_passing:
          type: integer
          example: 113
        pending_invoices:
          type: integer
        completed_payments:
          type: integer

    ChainStatusResponse:
      type: object
      properties:
        chains:
          type: array
          items:
            type: object
            properties:
              chain:
                type: string
                example: "Solana"
              chain_id:
                type: integer
                example: 501
              block_height:
                type: integer
                nullable: true
              connected:
                type: boolean
              timestamp:
                type: string
                format: date-time
              rpc_type:
                type: string
                example: "quicknode"
        total:
          type: integer
          example: 10
        connected:
          type: integer
          example: 8
        timestamp:
          type: string
          format: date-time

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          example: "invalid_request"
        message:
          type: string
          example: "KYC claim not satisfied: tier=1 (min=2)"

    ProofRetrievalResponse:
      type: object
      properties:
        commitment:
          type: string
        claim_satisfied:
          type: boolean
        attestation_type:
          type: string
        expires_at:
          type: integer
          format: int64
        proof_size_bytes:
          type: integer
        substrate_hex:
          type: string
          description: 58-byte H33-74 substrate (hex)

    PrivacyVerifyResponse:
      type: object
      properties:
        valid:
          type: boolean
        claim_satisfied:
          type: boolean
        expired:
          type: boolean
        expires_at:
          type: integer
          format: int64
        attestation_type:
          type: string

    CommerceVerifyResponse:
      type: object
      properties:
        valid:
          type: boolean
        approved:
          type: boolean
        compliance_valid:
          type: boolean
        attestation_commitment:
          type: string
        verified_at:
          type: integer
          format: int64

    # ── Request Bodies ──

    AgeProofRequest:
      type: object
      required: [birth_timestamp, min_age_years]
      properties:
        birth_timestamp:
          type: integer
          format: int64
          description: Unix timestamp of birthdate (private — never stored)
          example: 946684800
        min_age_years:
          type: integer
          description: Minimum age in years
          example: 21
        epoch_seconds:
          type: integer
          description: Attestation validity duration in seconds
          default: 7776000

    IdentityProofRequest:
      type: object
      required: [biometric_commitment, did_binding, mfa_factor_count, trust_score, expected_identity_hash, min_trust_score]
      properties:
        biometric_commitment:
          type: integer
          format: int64
        did_binding:
          type: integer
          format: int64
        mfa_factor_count:
          type: integer
        trust_score:
          type: integer
          description: "0-10000"
        expected_identity_hash:
          type: integer
          format: int64
        min_trust_score:
          type: integer
        epoch_seconds:
          type: integer
          default: 7776000

    KycStatusRequest:
      type: object
      required: [document_hash, provider_binding, verified_document_count, kyc_tier, min_kyc_tier]
      properties:
        document_hash:
          type: integer
          format: int64
          description: Hash of KYC documents (private)
        provider_binding:
          type: integer
          format: int64
          description: Verification provider binding
        verified_document_count:
          type: integer
          description: Number of verified document types
        kyc_tier:
          type: integer
          description: "Tier achieved (1=basic, 2=enhanced, 3=full)"
          example: 3
        min_kyc_tier:
          type: integer
          description: Minimum tier required
          example: 2
        epoch_seconds:
          type: integer
          default: 7776000

    JurisdictionRequest:
      type: object
      required: [jurisdiction_hash, allowed_set_root, jurisdiction_index, jurisdiction_count]
      properties:
        jurisdiction_hash:
          type: integer
          format: int64
          description: Hash of user's jurisdiction (private)
        allowed_set_root:
          type: integer
          format: int64
          description: Merkle root of allowed jurisdiction set
        jurisdiction_index:
          type: integer
        jurisdiction_count:
          type: integer
        epoch_seconds:
          type: integer
          default: 7776000

    AccreditedInvestorRequest:
      type: object
      required: [birth_timestamp, min_age_years, jurisdiction_hash, allowed_set_root, net_worth_tier, min_net_worth_tier, income_tier, min_income_tier]
      properties:
        birth_timestamp:
          type: integer
          format: int64
        min_age_years:
          type: integer
          example: 18
        jurisdiction_hash:
          type: integer
          format: int64
        allowed_set_root:
          type: integer
          format: int64
        net_worth_tier:
          type: integer
          description: "1=<100k, 2=100k-1M, 3=>1M"
        min_net_worth_tier:
          type: integer
          example: 3
        income_tier:
          type: integer
          description: "1=<100k, 2=100k-200k, 3=>200k"
        min_income_tier:
          type: integer
          description: "0 if net worth alone qualifies"
        epoch_seconds:
          type: integer
          default: 31536000

    ComplianceProofRequest:
      type: object
      required: [policy_hash, rule_count, rule_results, framework]
      properties:
        policy_hash:
          type: string
          description: Hex-encoded policy identifier
        rule_count:
          type: integer
        rule_results:
          type: array
          items:
            type: boolean
          description: Per-rule pass/fail (true = passed)
        framework:
          type: string
          description: Compliance framework
          enum: [OFAC, AML, KYC, TRAVEL_RULE]
        epoch_seconds:
          type: integer
          default: 86400

    BalanceRangeRequest:
      type: object
      required: [balance_commitment, min_balance, max_balance]
      properties:
        balance_commitment:
          type: integer
          format: int64
          description: Actual balance (private — used for proof, never stored)
        min_balance:
          type: integer
          format: int64
          description: Lower bound (public)
        max_balance:
          type: integer
          format: int64
          description: Upper bound (public)
        epoch_seconds:
          type: integer
          default: 86400

    CollateralRatioRequest:
      type: object
      required: [collateral_commitment, debt_commitment, min_ratio_bps, actual_ratio_bps]
      properties:
        collateral_commitment:
          type: integer
          format: int64
          description: Hash of collateral value (private)
        debt_commitment:
          type: integer
          format: int64
          description: Hash of debt value (private)
        min_ratio_bps:
          type: integer
          description: "Minimum ratio in basis points (e.g., 15000 = 150%)"
          example: 15000
        actual_ratio_bps:
          type: integer
          description: Actual ratio in basis points (private)
          example: 18000
        epoch_seconds:
          type: integer
          default: 86400

    PortfolioThresholdRequest:
      type: object
      required: [portfolio_commitment, min_threshold, actual_tier, asset_count]
      properties:
        portfolio_commitment:
          type: integer
          format: int64
          description: Hash of portfolio value (private)
        min_threshold:
          type: integer
          description: Minimum tier required (public)
        actual_tier:
          type: integer
          description: Actual value tier (private)
        asset_count:
          type: integer
          description: Number of distinct holdings (private)
        epoch_seconds:
          type: integer
          default: 86400

    CreateInvoiceRequest:
      type: object
      required: [amount_cents, currency]
      properties:
        amount_cents:
          type: integer
          description: Amount in cents
          example: 5013
        tax_cents:
          type: integer
          default: 0
        currency:
          type: string
          example: "USD"
        items:
          type: array
          items:
            type: object
            properties:
              description:
                type: string
              quantity:
                type: integer
              unit_price_cents:
                type: integer
              category:
                type: string
        expires_in_seconds:
          type: integer
          default: 3600

    InvoiceResponse:
      type: object
      properties:
        invoice_id:
          type: string
          example: "INV-1716400000-a1b2c3d4"
        commitment:
          type: string
          description: 32-byte commitment (hex)
        total_cents:
          type: integer
        currency:
          type: string
        expires_at:
          type: integer
          format: int64
        qr_payload:
          type: object
          properties:
            commitment:
              type: string
            merchant_id:
              type: string
            total:
              type: number
            currency:
              type: string
            substrate_hex:
              type: string
            expires_at:
              type: integer

    SettlementResponse:
      type: object
      properties:
        invoice_id:
          type: string
        approved:
          type: boolean
        settlement_status:
          type: string
          enum: [pending, completed, failed]
        compliance_valid:
          type: boolean
        attestation_commitment:
          type: string
        verified_at:
          type: integer
          format: int64
        proof_key:
          type: string

    VerifyRequest:
      type: object
      required: [commitment]
      properties:
        commitment:
          type: string
          description: 32-byte commitment (hex) or invoice_commitment
