{
  "openapi": "3.0.0",
  "info": {
    "title": "solrisk | Solana Risk Scoring",
    "description": "Production-ready dual-mode x402 seller: wallet screening (v1.2.0) and subscription JWT on the exact rail. Token-risk is beta. tx-risk is reserved (501, not billed).",
    "version": "0.2.2",
    "contact": { "name": "Miraland Labs", "url": "https://miraland.io" }
  },
  "servers": [
    { "url": "https://solrisk.signer-payer.me", "description": "Production (Mainnet)" },
    { "url": "https://preview.solrisk.signer-payer.me", "description": "Preview (Devnet)" }
  ],
  "paths": {
    "/api/v1/wallet-risk": {
      "get": {
        "summary": "Score a Solana wallet's risk",
        "operationId": "getWalletRisk",
        "parameters": [
          { "name": "wallet", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "Authorization", "in": "header", "required": false, "description": "Bearer subscription JWT", "schema": { "type": "string" } },
          { "name": "PAYMENT-SIGNATURE", "in": "header", "required": false, "description": "x402 v2 per-call payment proof", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Risk score", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WalletRiskResponse" } } } },
          "401": { "description": "Invalid/expired JWT", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "402": { "description": "Payment required (per-call)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentRequired" } } } },
          "429": { "description": "Rate limit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "503": { "description": "Chain data unavailable after retries. If payment was settled (settle-before-work), includes settlement_sig and PAYMENT-RESPONSE header for reconciliation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/v1/token-risk": {
      "get": {
        "summary": "Score a token mint rug-pull risk",
        "operationId": "getTokenRisk",
        "parameters": [
          { "name": "mint", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "Authorization", "in": "header", "required": false, "schema": { "type": "string" } },
          { "name": "PAYMENT-SIGNATURE", "in": "header", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "Token risk score", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TokenRiskResponse" } } } },
          "402": { "description": "Payment required", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentRequired" } } } },
          "503": { "description": "Chain data unavailable after retries. If payment was settled (settle-before-work), includes settlement_sig and PAYMENT-RESPONSE header for reconciliation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/v1/tx-risk": {
      "get": {
        "summary": "Transaction risk (planned v2.1 — not billed)",
        "operationId": "getTxRisk",
        "parameters": [
          { "name": "signature", "in": "query", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "501": { "description": "Not implemented", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }
        }
      }
    },
    "/api/v1/subscribe": {
      "post": {
        "summary": "Purchase subscription (x402 gate)",
        "operationId": "postSubscribe",
        "parameters": [
          { "name": "tier", "in": "query", "required": true, "schema": { "type": "string", "enum": ["hourly", "daily", "monthly"] } },
          { "name": "PAYMENT-SIGNATURE", "in": "header", "required": false, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": { "description": "JWT issued", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SubscribeResponse" } } } },
          "402": { "description": "Payment required (JSON body only)", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentRequired" } } } }
        }
      }
    },
    "/api/v1/subscribe/info": {
      "get": {
        "summary": "Subscription tier catalog",
        "operationId": "getSubscribeInfo",
        "responses": {
          "200": { "description": "Tier list and persistence hint", "content": { "application/json": { "schema": { "type": "object" } } } }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Service health",
        "responses": { "200": { "description": "OK" } }
      }
    }
  },
  "components": {
    "schemas": {
      "WalletRiskResponse": {
        "type": "object",
        "properties": {
          "api_version": { "type": "integer", "const": 2 },
          "wallet": { "type": "string" },
          "risk_score": { "type": "integer" },
          "risk_band": { "type": "string" },
          "signal_quality": { "type": "string", "enum": ["high", "medium", "low"] },
          "recommendation": { "type": "string", "enum": ["ALLOW", "REVIEW", "BLOCK"] },
          "cluster": { "type": "string", "enum": ["mainnet", "devnet"] },
          "cache_hit": { "type": "boolean" },
          "cached_at": { "type": "string", "format": "date-time" },
          "scoring_version": { "type": "string", "example": "1.2.0" },
          "signals": { "type": "object", "description": "Raw chain signals. unique_counterparties_30d and program_diversity_30d are null until derived from parsed transactions (see counterparty_metrics_estimated) — never synthesized" }
        }
      },
      "TokenRiskResponse": {
        "type": "object",
        "properties": {
          "api_version": { "type": "integer" },
          "mint": { "type": "string" },
          "risk_domain": { "type": "string", "const": "token" },
          "risk_score": { "type": "integer" },
          "recommendation": { "type": "string", "enum": ["ALLOW", "REVIEW", "BLOCK"] },
          "cluster": { "type": "string", "enum": ["mainnet", "devnet"] },
          "cache_hit": { "type": "boolean" },
          "cached_at": { "type": "string", "format": "date-time" },
          "scoring_version": { "type": "string", "example": "1.0.0" }
        }
      },
      "TxRiskResponse": {
        "type": "object",
        "properties": {
          "api_version": { "type": "integer" },
          "signature": { "type": "string" },
          "risk_domain": { "type": "string", "const": "tx" },
          "risk_score": { "type": "integer" },
          "scoring_version": { "type": "string", "example": "1.0.0" }
        }
      },
      "SubscribeResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "token": { "type": "string" },
          "tier": { "type": "string" },
          "expiresAt": { "type": "string", "format": "date-time" },
          "persistenceHint": { "type": "string" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": { "type": "string" },
          "message": { "type": "string" },
          "code": { "type": "string" },
          "api_version": { "type": "integer" },
          "settlement_sig": { "type": "string", "description": "Present on post-settlement failures (503 RPC_ERROR with per-call payment): the on-chain settlement signature, for reconciling paid-but-not-served calls" }
        }
      },
      "PaymentRequired": {
        "type": "object",
        "properties": {
          "x402Version": { "type": "integer", "const": 2 },
          "resource": { "type": "object" },
          "accepts": { "type": "array" },
          "extensions": { "type": "object" }
        }
      }
    }
  }
}
