openapi: 3.1.0
info:
  title: Approval Revoke MCP (x402)
  version: 0.1.0
  description: |
    Pay-per-call EVM token-approval service. Three primitives:
    (1) list_approvals enumerates active ERC-20 + ERC-721/1155 approvals for a
    wallet via eth_getLogs + on-chain allowance/isApprovedForAll confirmation;
    (2) approvals_risk scores a wallet 0–100 weighted on unlimited approvals,
    known-malicious spenders, unverified spenders;
    (3) spender_reputation vets a single spender against bundled known-good +
    known-malicious dictionaries and detects EOA via eth_getCode.
    Multichain (ethereum/base/arbitrum/optimism/polygon). Settle USDC on Base
    via x402. No signup, no API key.
servers:
  - url: https://approval-revoke-mcp.mtree.workers.dev
x-pricing:
  - path: /v1/wallet/approvals
    method: POST
    price: $0.10
    amount: "0.10"
    asset: USDC
    network: base
  - path: /v1/wallet/approvals_risk
    method: POST
    price: $0.20
    amount: "0.20"
    asset: USDC
    network: base
  - path: /v1/spender/reputation
    method: POST
    price: $0.05
    amount: "0.05"
    asset: USDC
    network: base
paths:
  /healthz:
    get:
      summary: Service health
      responses:
        "200":
          description: OK
  /v1/wallet/approvals:
    post:
      summary: List active token approvals for a wallet
      description: |
        $0.10 USDC on Base via x402. Scans recent ERC-20 Approval and
        ERC-721/1155 ApprovalForAll events for the wallet via eth_getLogs,
        then confirms each (token, spender) pair is still active by reading
        allowance() / isApprovedForAll() on-chain. Returns per-chain summary
        plus a flat list of active approvals with spender labels where known.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [address]
              properties:
                address:
                  type: string
                  description: EVM wallet address (0x… 20 bytes)
                chains:
                  type: array
                  items:
                    type: string
                    enum: [ethereum, base, arbitrum, optimism, polygon]
                  description: Subset of supported chains. Default all five.
                include_revoked:
                  type: boolean
                  description: Include approvals that were emitted in the window but are now zero. Default false.
      responses:
        "402":
          description: Payment required (x402 envelope returned)
        "200":
          description: Wallet approvals payload
  /v1/wallet/approvals_risk:
    post:
      summary: Composite 0–100 approval-risk score for a wallet
      description: |
        $0.20 USDC on Base via x402. Runs the full approvals scan, then weights:
        +30 per unlimited approval (cap +60), +20 if any known-malicious spender
        flagged, +5 per unverified/unknown spender (cap +30), -10 cleanliness
        credit if zero unlimited and zero flagged. Returns risk_score, risk_band
        (clean/low/medium/high/critical), top-10 risk-ranked approvals, and
        human-readable reasons.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [address]
              properties:
                address:
                  type: string
                  description: EVM wallet address (0x… 20 bytes)
                chains:
                  type: array
                  items:
                    type: string
                    enum: [ethereum, base, arbitrum, optimism, polygon]
                  description: Subset of supported chains. Default all five.
      responses:
        "402":
          description: Payment required (x402 envelope returned)
        "200":
          description: Wallet approval-risk payload
  /v1/spender/reputation:
    post:
      summary: Single-spender reputation lookup
      description: |
        $0.05 USDC on Base via x402. Checks the spender against bundled
        known-spenders (~30 major routers/aggregators/marketplaces) +
        known-malicious dictionaries, and reads on-chain code via eth_getCode
        to detect EOA. Returns label, category, is_known_malicious, is_eoa, and
        recommendation (trusted / caution / do-not-approve).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [spender]
              properties:
                spender:
                  type: string
                  description: EVM spender address (0x… 20 bytes)
                chain:
                  type: string
                  enum: [ethereum, base, arbitrum, optimism, polygon]
                  default: ethereum
      responses:
        "402":
          description: Payment required (x402 envelope returned)
        "200":
          description: Spender reputation payload
