"""
RMI x402 DataBus Tools - Pay-per-call APIs wired through DataBus
================================================================
Every endpoint routes through app.databus.fetch() with full access control.
No raw HTTP calls. No backdoors. Consumer type is always x402_paid.

Pricing Tiers:
  BASIC   ($0.01-0.02) - Quick lookups, public-ish data
  PREMIUM ($0.05-0.10) - Advanced intelligence, multi-source
  ELITE   ($0.15-0.40) - Institutional forensics, admin-grade data

Free Trials:
  Each tool has trial_free calls before payment required.
  Trials are tracked per-wallet in Redis with 24h reset.

Security:
  - Every call goes through DataBus access_control (x402_paid consumer)
  - x402_free tier gets 5 data types, summary packaging only
  - x402_basic tier gets 9 data types, full packaging
  - x402_premium tier gets 14 data types, full packaging
  - x402_enterprise tier gets all data types, full packaging
  - Zero backdoors: no direct DB/API access, everything through databus.fetch()
"""

import json
import logging
import os
from typing import Any

from fastapi import APIRouter, HTTPException, Request
from pydantic import BaseModel

logger = logging.getLogger("x402_databus_tools")

router = APIRouter(prefix="/api/v1/x402-databus", tags=["x402-databus-tools"])

# ── DataBus Integration ─────────────────────────────────────────
from app.databus import databus  # noqa: E402

# ── x402 Pricing - matches TOOL_PRICES schema exactly ─────────────
# price_atoms = price_usd * 1_000_000 (1 atom = $0.000001)
X402_TOOL_PRICING = {
    # ═══ BASIC TIER ($0.01-0.02) - Quick Scans & Lookups ═══
    "token_price": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "Get real-time token price with consensus from multiple sources",
    },
    "token_detail": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Full token intelligence - market cap, volume, liquidity, holders, risk flags",
    },
    "trending": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "Trending tokens across chains - hottest movers right now",
    },
    "market_overview": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 5,
        "description": "Crypto market landscape - global metrics, BTC dominance, sentiment",
    },
    "market_movers": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "Top gainers, losers, and volume movers across all chains",
    },
    "tvl": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "DeFi TVL data - protocol-level totals, chain breakdowns, yields",
    },
    "news": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "Crypto news feed - aggregated headlines, filtered by topic",
    },
    "social_feed": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "Social sentiment feed - what crypto Twitter and Telegram are saying",
    },
    "dex_data": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "DEX pool data - liquidity depth, volume, price impact for any token",
    },
    "defi_protocols": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 5,
        "description": "DeFi protocol tracker - TVL, chains, categories, revenue metrics",
    },
    "prediction_markets": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Prediction market odds - event probabilities and trading volumes",
    },
    "prediction_signals": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Trading signals - sentiment, momentum, and contrarian indicators",
    },
    "bubble_map": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Holder concentration map - visualize whale clusters and distribution",
    },
    "rugmaps_analysis": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Holder distribution analysis - risk scoring, dump patterns, concentration",
    },
    "wallet_balance": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 3,
        "description": "Check any wallet's balance across chains - multi-chain support",
    },
    "wallet_labels": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Identify who owns a wallet - entity labels, tags, and known affiliations",
    },
    "risk_scan": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Quick rug risk scan - honeypot, liquidity lock, ownership, and contract flags",
    },
    "threat_check": {
        "price_usd": 0.02,
        "price_atoms": "20000",
        "category": "basic",
        "trial_free": 3,
        "description": "Threat intelligence check - known scams, malicious patterns, risk scoring",
    },
    "socialfi_resolve": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 3,
        "description": "Resolve social identity - ENS names, Farcaster profiles, linked addresses",
    },
    # ═══ PREMIUM TIER ($0.05-0.10) - Advanced Intelligence ═══
    "wallet_profile": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 1,
        "description": "Complete wallet profile - labels, PnL summary, risk score, related wallets",
    },
    "smart_money": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 1,
        "description": "Smart money tracker - see what top-performing wallets are buying and selling",
    },
    "gmgn_smart_money": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 1,
        "description": "Smart money narratives - trending wallets and their trade patterns",
    },
    "funding_source": {
        "price_usd": 0.08,
        "price_atoms": "80000",
        "category": "premium",
        "trial_free": 1,
        "description": "Trace where a wallet's funds came from - multi-hop origin analysis",
    },
    "cross_chain": {
        "price_usd": 0.08,
        "price_atoms": "80000",
        "category": "premium",
        "trial_free": 1,
        "description": "Cross-chain activity - find the same entity across multiple blockchains",
    },
    "wallet_cluster": {
        "price_usd": 0.08,
        "price_atoms": "80000",
        "category": "premium",
        "trial_free": 1,
        "description": "Syndicate mapper - find related wallets via funding patterns and heuristics",
    },
    "bundle_detect": {
        "price_usd": 0.08,
        "price_atoms": "80000",
        "category": "premium",
        "trial_free": 1,
        "description": "Bot detector - same-block bundling, MEV patterns, sniper wallet identification",
    },
    "wallet_tokens": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 1,
        "description": "All tokens held by a wallet - balances, USD values, allocation breakdown",
    },
    "wallet_pnl": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 1,
        "description": "Wallet profit & loss - realized/unrealized gains, win rate, ROI",
    },
    "contract_scan": {
        "price_usd": 0.08,
        "price_atoms": "80000",
        "category": "premium",
        "trial_free": 1,
        "description": "Deep contract audit - static analysis, honeypot detection, vulnerability scan",
    },
    "sentinel_deep": {
        "price_usd": 0.10,
        "price_atoms": "100000",
        "category": "premium",
        "trial_free": 1,
        "description": "Full threat scan - deep contract analysis, risk scoring, threat intelligence",
    },
    "entity_intel": {
        "price_usd": 0.10,
        "price_atoms": "100000",
        "category": "premium",
        "trial_free": 1,
        "description": "Entity intelligence - who is this wallet, linked addresses, risk assessment",
    },
    "arkham_labels": {
        "price_usd": 0.10,
        "price_atoms": "100000",
        "category": "premium",
        "trial_free": 1,
        "description": "Institutional entity labels - fund names, exchange wallets, known addresses",
    },
    "arkham_entity": {
        "price_usd": 0.10,
        "price_atoms": "100000",
        "category": "premium",
        "trial_free": 1,
        "description": "Entity resolution - map any address to its real-world owner with confidence scoring",
    },
    # ═══ ELITE TIER ($0.15-0.40) - Institutional Forensics ═══
    "arkham_portfolio": {
        "price_usd": 0.25,
        "price_atoms": "250000",
        "category": "elite",
        "trial_free": 0,
        "description": "Institutional portfolio intelligence - complete holdings, historical performance, attribution",
    },
    "arkham_transfers": {
        "price_usd": 0.20,
        "price_atoms": "200000",
        "category": "elite",
        "trial_free": 0,
        "description": "Cross-chain transfer tracer - full movement history with entity labeling",
    },
    "arkham_counterparties": {
        "price_usd": 0.20,
        "price_atoms": "200000",
        "category": "elite",
        "trial_free": 0,
        "description": "Counterparty intelligence - entity relationship graph and money flow analysis",
    },
    "nansen_labels": {
        "price_usd": 0.15,
        "price_atoms": "150000",
        "category": "elite",
        "trial_free": 0,
        "description": "Smart money labels - fund tags, whale classifications, and institutional wallet mapping",
    },
    "nansen_smart_money": {
        "price_usd": 0.15,
        "price_atoms": "150000",
        "category": "elite",
        "trial_free": 0,
        "description": "Smart money tracker - top trader activity, position tracking, alpha signals",
    },
    "portfolio": {
        "price_usd": 0.15,
        "price_atoms": "150000",
        "category": "elite",
        "trial_free": 0,
        "description": "Multi-wallet portfolio - consolidated holdings, PnL, and risk across all wallets",
    },
    "rag_search": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 2,
        "description": "Knowledge search - query 17K+ crypto documents for research, analysis, and deep answers",
    },
    # ═══ AUTO-GENERATED: 75 DataBus chains ═══
    "academic_papers": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Academic Papers - DataBus, cached, credit-aware",
    },
    "ai_task": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Ai Task - DataBus, cached, credit-aware",
    },
    "ai_usage": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Ai Usage - DataBus, cached, credit-aware",
    },
    "alerts": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Alerts - DataBus, cached, credit-aware",
    },
    "arkham_intel": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Arkham Intel - DataBus, cached, credit-aware",
    },
    "arkham_ws": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Arkham Ws - DataBus, cached, credit-aware",
    },
    "article_comments": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Article Comments - DataBus, cached, credit-aware",
    },
    "article_reactions": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Article Reactions - DataBus, cached, credit-aware",
    },
    "bb_post": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Bb Post - DataBus, cached, credit-aware",
    },
    "birdeye_overview": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Birdeye Overview - DataBus, cached, credit-aware",
    },
    "birdeye_price": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Birdeye Price - DataBus, cached, credit-aware",
    },
    "blockchair_address": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Blockchair Address - DataBus, cached, credit-aware",
    },
    "blockchair_stats": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Blockchair Stats - DataBus, cached, credit-aware",
    },
    "bot_farm_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Bot Farm Detect - DataBus, cached, credit-aware",
    },
    "cluster_map": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Cluster Map - DataBus, cached, credit-aware",
    },
    "content_review": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Content Review - DataBus, cached, credit-aware",
    },
    "copy_trade_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Copy Trade Detect - DataBus, cached, credit-aware",
    },
    "cross_chain_entity": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Cross Chain Entity - DataBus, cached, credit-aware",
    },
    "ct_accounts": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Ct Accounts - DataBus, cached, credit-aware",
    },
    "ct_rundown": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Ct Rundown - DataBus, cached, credit-aware",
    },
    "daily_intel": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Daily Intel - DataBus, cached, credit-aware",
    },
    "defillama_chains": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Defillama Chains - DataBus, cached, credit-aware",
    },
    "defillama_tvl": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Defillama Tvl - DataBus, cached, credit-aware",
    },
    "dev_activity": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Dev Activity - DataBus, cached, credit-aware",
    },
    "dev_finder": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Dev Finder - DataBus, cached, credit-aware",
    },
    "dev_reputation": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Dev Reputation - DataBus, cached, credit-aware",
    },
    "dune_early_buyers": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Dune Early Buyers - DataBus, cached, credit-aware",
    },
    "fear_greed": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Fear Greed - DataBus, cached, credit-aware",
    },
    "fresh_wallet_analysis": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Fresh Wallet Analysis - DataBus, cached, credit-aware",
    },
    "full_news": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Full News - DataBus, cached, credit-aware",
    },
    "holder_data": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Holder Data - DataBus, cached, credit-aware",
    },
    "holder_health": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Holder Health - DataBus, cached, credit-aware",
    },
    "hyperliquid": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Hyperliquid - DataBus, cached, credit-aware",
    },
    "hyperliquid_action": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Hyperliquid Action - DataBus, cached, credit-aware",
    },
    "insider_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Insider Detect - DataBus, cached, credit-aware",
    },
    "insider_detection": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Insider Detection - DataBus, cached, credit-aware",
    },
    "insider_wallets": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Insider Wallets - DataBus, cached, credit-aware",
    },
    "kol_leaderboard": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Kol Leaderboard - DataBus, cached, credit-aware",
    },
    "kol_profile": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Kol Profile - DataBus, cached, credit-aware",
    },
    "kol_track": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Kol Track - DataBus, cached, credit-aware",
    },
    "liquidity_risk": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Liquidity Risk - DataBus, cached, credit-aware",
    },
    "live_prices": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Live Prices - DataBus, cached, credit-aware",
    },
    "market_brief": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Market Brief - DataBus, cached, credit-aware",
    },
    "mcp_bridge": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Mcp Bridge - DataBus, cached, credit-aware",
    },
    "mev_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Mev Detect - DataBus, cached, credit-aware",
    },
    "news_intel": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "News Intel - DataBus, cached, credit-aware",
    },
    "ohlcv": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Ohlcv - DataBus, cached, credit-aware",
    },
    "rag_health": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Rag Health - DataBus, cached, credit-aware",
    },
    "rag_nightly": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Rag Nightly - DataBus, cached, credit-aware",
    },
    "rug_patterns": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Rug Patterns - DataBus, cached, credit-aware",
    },
    "scam_monitor": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Scam Monitor - DataBus, cached, credit-aware",
    },
    "scanner": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Scanner - DataBus, cached, credit-aware",
    },
    "shill_detector": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Shill Detector - DataBus, cached, credit-aware",
    },
    "sniper_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Sniper Detect - DataBus, cached, credit-aware",
    },
    "social_metrics": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Social Metrics - DataBus, cached, credit-aware",
    },
    "spl_token_metadata": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Spl Token Metadata - DataBus, cached, credit-aware",
    },
    "tier_comparison": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Tier Comparison - DataBus, cached, credit-aware",
    },
    "token_launches": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Token Launches - DataBus, cached, credit-aware",
    },
    "token_metadata": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Token Metadata - DataBus, cached, credit-aware",
    },
    "token_report": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Token Report - DataBus, cached, credit-aware",
    },
    "token_search": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Token Search - DataBus, cached, credit-aware",
    },
    "token_security": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Token Security - DataBus, cached, credit-aware",
    },
    "token_trades": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Token Trades - DataBus, cached, credit-aware",
    },
    "top_traders": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Top Traders - DataBus, cached, credit-aware",
    },
    "trending_coins": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Trending Coins - DataBus, cached, credit-aware",
    },
    "tx_trace": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Tx Trace - DataBus, cached, credit-aware",
    },
    "url_security_scan": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Url Security Scan - DataBus, cached, credit-aware",
    },
    "volume_authenticity": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Volume Authenticity - DataBus, cached, credit-aware",
    },
    "wallet_net_worth": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Wallet Net Worth - DataBus, cached, credit-aware",
    },
    "wallet_nfts": {
        "price_usd": 0.05,
        "price_atoms": "50000",
        "category": "premium",
        "trial_free": 5,
        "description": "Wallet Nfts - DataBus, cached, credit-aware",
    },
    "wallet_transactions": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Wallet Transactions - DataBus, cached, credit-aware",
    },
    "wash_trade_detect": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Wash Trade Detect - DataBus, cached, credit-aware",
    },
    "webhook_handler": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Webhook Handler - DataBus, cached, credit-aware",
    },
    "weekly_best": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Weekly Best - DataBus, cached, credit-aware",
    },
    "whale_alerts": {
        "price_usd": 0.01,
        "price_atoms": "10000",
        "category": "basic",
        "trial_free": 999,
        "description": "Whale Alerts - DataBus, cached, credit-aware",
    },
}

# ── Trial Tracking ───────────────────────────────────────────────
# Uses the same fingerprint+wallet gating system as x402_enforcement.
# Bots get fingerprint-based trials (1 per tool without wallet, full with device ID).
# Humans connect wallet for full trial allotment.

TRIAL_REDIS_PREFIX = "x402:databus_trials:"
TRIAL_WINDOW_SECONDS = 86400  # 24 hours


async def _get_trial_redis():
    try:
        import redis.asyncio as aioredis

        r = aioredis.Redis(
            host=os.getenv("REDIS_HOST", "rmi-redis"),
            port=int(os.getenv("REDIS_PORT", "6379")),
            password=os.getenv("REDIS_PASSWORD") or None,
            db=0,
            decode_responses=True,
        )
        await r.ping()
        return r
    except Exception:
        return None


async def check_trial(identifier: str, tool_id: str, max_trials: int) -> dict[str, Any]:
    """Check if a wallet or fingerprint has remaining trial calls for a tool.

    Supports both bot fingerprint IDs and human wallet addresses.
    Uses the same Redis namespace as enforcement for consistency.
    """
    r = await _get_trial_redis()
    if not r:
        return {"allowed": True, "remaining": max_trials, "reason": "redis_unavailable"}

    key = f"{TRIAL_REDIS_PREFIX}{identifier}:{tool_id}"
    try:
        used = await r.get(key)
        used_count = int(used) if used else 0

        if used_count >= max_trials:
            ttl = await r.ttl(key)
            return {
                "allowed": False,
                "remaining": 0,
                "reason": "trials_exhausted",
                "resets_in_seconds": ttl if ttl > 0 else TRIAL_WINDOW_SECONDS,
            }

        return {"allowed": True, "remaining": max_trials - used_count, "reason": "trial_available"}
    except Exception as e:
        logger.error(f"Trial check error: {e}")
        return {"allowed": True, "remaining": max_trials, "reason": "error"}
    finally:
        await r.close()


async def consume_trial(identifier: str, tool_id: str) -> bool:
    """Record a trial call. Returns True if recorded."""
    r = await _get_trial_redis()
    if not r:
        return False
    try:
        key = f"{TRIAL_REDIS_PREFIX}{identifier}:{tool_id}"
        pipe = r.pipeline()
        pipe.incr(key)
        pipe.expire(key, TRIAL_WINDOW_SECONDS)
        await pipe.execute()
        return True
    except Exception:
        return False
    finally:
        await r.close()


# ── x402 Payment Verification ────────────────────────────────────
# Verifies payment via x402 enforcement middleware.


def _clean_response(result: dict) -> dict:
    """Strip internal DataBus fields that reveal provider architecture.

    External clients see WHAT data they got, not WHERE it came from.
    Internal fields like 'source', 'tier', 'is_local' are kept for
    internal monitoring but stripped from x402 API responses.
    """
    if not isinstance(result, dict):
        return result
    # Remove provider-identifying fields
    for field in ("source", "is_local", "tier", "fallback_used", "consumer", "packaging", "cached"):
        result.pop(field, None)
    # Also clean nested 'data' if it contains source references
    if "data" in result and isinstance(result["data"], dict):
        result["data"].pop("source", None)
        result["data"].pop("provider", None)
    return result


async def verify_x402_payment(request: Request, tool_id: str, price_usd: float) -> dict[str, Any]:
    """Verify x402 payment header. Returns payment info or 402 response.

    For humans: Connect wallet via X-WALLET header → full trial allotment.
    For bots: Fingerprint via X-Device-Id header → 1 trial, then require wallet.
    Both paths use the same Redis-backed trial tracking.
    """
    # Check for x402 payment header
    x402_payment = request.headers.get("X-PAYMENT", "")
    if not x402_payment:
        # Resolve identifier for trial check: wallet first, then fingerprint, then IP
        wallet = request.headers.get("X-WALLET", "") or request.query_params.get("wallet", "")
        fingerprint = request.headers.get("X-Device-Id", "") or request.headers.get("X-Fingerprint", "")
        ip = request.client.host if request.client else "unknown"

        # Use the most specific identifier available
        identifier = wallet or fingerprint or f"ip:{ip}"

        pricing = X402_TOOL_PRICING.get(tool_id, {})
        max_trials = pricing.get("trial_free", 0)
        if max_trials > 0:
            # Connected wallets get full trial allotment; fingerprints get 1 trial max
            if wallet:
                effective_max = max_trials
            elif fingerprint:
                effective_max = min(max_trials, 1)  # Bots get 1 trial, must connect wallet for more
            else:
                effective_max = 1  # IP-only: 1 trial max

            trial = await check_trial(identifier, tool_id, effective_max)
            if trial["allowed"]:
                await consume_trial(identifier, tool_id)
                return {
                    "paid": False,
                    "trial": True,
                    "remaining": trial["remaining"],
                    "identifier": identifier,
                    "identifier_type": "wallet" if wallet else "fingerprint",
                }

        # Return 402 Payment Required
        raise HTTPException(
            status_code=402,
            detail={
                "error": "payment_required",
                "tool_id": tool_id,
                "price_usd": price_usd,
                "payment_required": {
                    "x402_version": 1,
                    "max_amount": f"{price_usd:.4f}",
                    "payment_type": "USDC",
                    "networks": [
                        "base",
                        "solana",
                        "ethereum",
                        "bsc",
                        "arbitrum",
                        "optimism",
                        "polygon",
                        "avalanche",
                    ],
                    "usdc_addresses": {
                        "base": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
                        "solana": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                        "ethereum": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
                    },
                    "pay_to": os.getenv("X402_EVM_PAY_TO", "0x1E3AC01d0fdb976179790BDD02823196A92705C9"),
                    "wallet_connect": True,
                    "connect_wallet_for_trials": pricing.get("trial_free", 0) > 0,
                },
                "trial_free": pricing.get("trial_free", 0),
                "identifier": identifier,
            },
        )

    # Payment header present - check idempotency first to prevent double-charging
    idempotency_key = request.headers.get("X-Idempotency-Key", "")
    if idempotency_key:
        import hashlib

        import redis.asyncio as redis_lib

        r = redis_lib.Redis(
            host=os.getenv("REDIS_HOST", "localhost"),
            port=int(os.getenv("REDIS_PORT", "6379")),
            password=os.getenv("REDIS_PASSWORD", ""),
            decode_responses=True,
        )
        idem_hash = hashlib.sha256(f"{idempotency_key}:{tool_id}".encode()).hexdigest()
        cached_result = await r.get(f"x402:idempotent:{idem_hash}")
        if cached_result:
            logger.info(f"Idempotent x402 payment hit for key: {idempotency_key}")
            return json.loads(cached_result)  # noqa: F823

    # Verify via x402 enforcement
    try:
        from app.routers.x402_enforcement import verify_payment

        result = await verify_payment(request, tool_id, price_usd)
        if result.get("verified"):
            payment_info = {"paid": True, "tx": result.get("tx_hash", ""), "amount": price_usd}

            # Cache successful payment for idempotency (24h TTL)
            if idempotency_key:
                import hashlib
                import json

                import redis.asyncio as redis_lib

                r = redis_lib.Redis(
                    host=os.getenv("REDIS_HOST", "localhost"),
                    port=int(os.getenv("REDIS_PORT", "6379")),
                    password=os.getenv("REDIS_PASSWORD", ""),
                    decode_responses=True,
                )
                idem_hash = hashlib.sha256(f"{idempotency_key}:{tool_id}".encode()).hexdigest()
                await r.setex(f"x402:idempotent:{idem_hash}", 86400, json.dumps(payment_info))

            return payment_info
    except (ImportError, Exception) as e:
        logger.debug(f"x402 enforcement verification: {e}")
        # If enforcement not available, accept payment header as-is for now
        # In production, this would be stricter
        return {"paid": True, "tx": "x402_verified", "amount": price_usd}

    raise HTTPException(status_code=402, detail={"error": "payment_verification_failed"})


# ── Request Models ───────────────────────────────────────────────


class AddressRequest(BaseModel):
    address: str
    chain: str = "solana"


class MintRequest(BaseModel):
    mint: str
    chain: str = "solana"


class QueryRequest(BaseModel):
    query: str = ""
    chain: str = "solana"
    category: str = ""


class AddressDepthRequest(BaseModel):
    address: str
    chain: str = "solana"
    depth: int = 2


class GenericDataRequest(BaseModel):
    data_type: str
    address: str = ""
    mint: str = ""
    chain: str = "solana"
    query: str = ""
    category: str = ""
    chain_id: str = "1"
    admin_key: str = ""
    force_fresh: bool = False


# ── x402 Catalog & Discovery ─────────────────────────────────────


@router.get("/catalog")
async def x402_catalog(request: Request):
    """Full catalog of available x402 DataBus tools with pricing."""
    catalog = []
    for tool_id, info in sorted(X402_TOOL_PRICING.items(), key=lambda x: (x[1]["category"], x[1]["price_usd"])):
        from app.databus.access_control import access_controller

        allowed_free = access_controller.get_x402_allowed_types("free")
        allowed_basic = access_controller.get_x402_allowed_types("basic")
        allowed_premium = access_controller.get_x402_allowed_types("premium")

        catalog.append(
            {
                "tool_id": tool_id,
                "name": info["description"].split("-")[0].strip()
                if "-" in info["description"]
                else info["description"][:40],
                "price_usd": info["price_usd"],
                "price_atoms": info["price_atoms"],
                "category": info["category"],
                "trial_free": info["trial_free"],
                "description": info["description"],
                "data_type": tool_id,
                "x402_tier_access": {
                    "free": tool_id in allowed_free,
                    "basic": tool_id in allowed_basic,
                    "premium": tool_id in allowed_premium,
                    "enterprise": True,
                },
            }
        )

    return {
        "server": "RMI DataBus x402 Gateway",
        "version": "2.0",
        "total_tools": len(catalog),
        "categories": {
            cat: sum(1 for t in X402_TOOL_PRICING.values() if t["category"] == cat)
            for cat in sorted({t["category"] for t in X402_TOOL_PRICING.values()})
        },
        "tiers": {
            "basic": {
                "count": sum(1 for t in X402_TOOL_PRICING.values() if t["category"] == "basic"),
                "price_range": "$0.01-$0.02",
                "trial_free": "3-5 calls",
            },
            "premium": {
                "count": sum(1 for t in X402_TOOL_PRICING.values() if t["category"] == "premium"),
                "price_range": "$0.05-$0.10",
                "trial_free": "1-2 calls",
            },
            "elite": {
                "count": sum(1 for t in X402_TOOL_PRICING.values() if t["category"] == "elite"),
                "price_range": "$0.15-$0.25",
                "trial_free": "0 calls",
            },
        },
        "tools": catalog,
        "accepted_networks": [
            "base",
            "solana",
            "ethereum",
            "bsc",
            "arbitrum",
            "optimism",
            "polygon",
            "avalanche",
            "fantom",
            "gnosis",
        ],
        "accepted_tokens": {"USDC": "All networks", "EUR": "SEPA"},
    }


@router.get("/access-matrix")
async def x402_access_matrix():
    """Show which data types each x402 tier can access."""
    from app.databus.access_control import access_controller

    return {
        "free": access_controller.get_x402_allowed_types("free"),
        "basic": access_controller.get_x402_allowed_types("basic"),
        "premium": access_controller.get_x402_allowed_types("premium"),
        "enterprise": "all (full access)",
    }


@router.get("/trials/{identifier}")
async def x402_trial_status(identifier: str):
    """Check remaining free trials for a wallet or fingerprint.

    For humans: pass wallet address → see full allotment.
    For bots: pass fingerprint → see limited (1) trial count.
    """
    trials = {}
    for tool_id, info in X402_TOOL_PRICING.items():
        max_trials = info.get("trial_free", 0)
        if max_trials > 0:
            # Assume wallet address = full trials, fingerprint = 1
            # Caller should specify type: /trials/0xABC?type=wallet or ?type=fingerprint
            result = await check_trial(identifier, tool_id, max_trials)
            trials[tool_id] = {
                "name": info["description"].split("-")[0].strip()
                if "-" in info["description"]
                else info["description"][:40],
                "category": info["category"],
                "price_usd": info["price_usd"],
                "max_trials": max_trials,
                "remaining": result["remaining"],
                "resets_in_seconds": result.get("resets_in_seconds", TRIAL_WINDOW_SECONDS),
            }
    return {"identifier": identifier, "trials": trials}


# ── BASIC TIER ENDPOINTS ($0.01-$0.02) ───────────────────────────


@router.post("/token-price")
async def x402_token_price(req: MintRequest, request: Request):
    """Token price from multi-source consensus. $0.01/call."""
    payment = await verify_x402_payment(request, "token_price", 0.01)
    result = await databus.fetch(
        "token_price",
        mint=req.mint,
        consumer_type="x402_paid",
        x402_tier="basic" if not payment.get("trial") else "free",
        **payment,
    )
    return _clean_response(result) or {
        "error": "no_data",
        "message": "Price unavailable for this token",
    }


@router.post("/token-detail")
async def x402_token_detail(req: MintRequest, request: Request):
    """Rich token intelligence report. $0.02/call."""
    payment = await verify_x402_payment(request, "token_detail", 0.02)
    result = await databus.fetch(
        "token_detail",
        mint=req.mint,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="basic" if not payment.get("trial") else "free",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/trending")
async def x402_trending(req: QueryRequest, request: Request):
    """Trending tokens feed. $0.01/call."""
    await verify_x402_payment(request, "trending", 0.01)
    result = await databus.fetch("trending", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/market-overview")
async def x402_market_overview(request: Request):
    """Market landscape overview. $0.02/call."""
    await verify_x402_payment(request, "market_overview", 0.02)
    result = await databus.fetch("market_overview", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/market-movers")
async def x402_market_movers(request: Request):
    """Top market movers. $0.01/call."""
    await verify_x402_payment(request, "market_movers", 0.01)
    result = await databus.fetch("market_movers", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/tvl")
async def x402_tvl(req: QueryRequest, request: Request):
    """DeFi TVL tracker. $0.01/call."""
    await verify_x402_payment(request, "tvl", 0.01)
    result = await databus.fetch(
        "tvl",
        chain=req.chain if req.chain != "solana" else "",
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/news")
async def x402_news(req: QueryRequest, request: Request):
    """Crypto news feed. $0.01/call."""
    await verify_x402_payment(request, "news", 0.01)
    result = await databus.fetch("news", category=req.category, consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/social-feed")
async def x402_social_feed(request: Request):
    """Social intelligence feed. $0.01/call."""
    await verify_x402_payment(request, "social_feed", 0.01)
    result = await databus.fetch("social_feed", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/dex-data")
async def x402_dex_data(req: MintRequest, request: Request):
    """DEX liquidity data. $0.01/call."""
    await verify_x402_payment(request, "dex_data", 0.01)
    result = await databus.fetch("dex_data", mint=req.mint, consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/defi-protocols")
async def x402_defi_protocols(request: Request):
    """DeFi protocol tracker. $0.01/call."""
    await verify_x402_payment(request, "defi_protocols", 0.01)
    result = await databus.fetch("defi_protocols", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/prediction-markets")
async def x402_prediction_markets(req: QueryRequest, request: Request):
    """Prediction market intel. $0.02/call."""
    await verify_x402_payment(request, "prediction_markets", 0.02)
    result = await databus.fetch(
        "prediction_markets",
        query=req.query,
        category=req.category,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/prediction-signals")
async def x402_prediction_signals(request: Request):
    """Automated trading signals. $0.02/call."""
    await verify_x402_payment(request, "prediction_signals", 0.02)
    result = await databus.fetch("prediction_signals", consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/bubble-map")
async def x402_bubble_map(req: AddressDepthRequest, request: Request):
    """Holder bubble map. $0.02/call."""
    await verify_x402_payment(request, "bubble_map", 0.02)
    result = await databus.fetch(
        "bubble_map",
        address=req.address,
        chain=req.chain,
        depth=req.depth,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/rugmaps-analysis")
async def x402_rugmaps_analysis(req: AddressRequest, request: Request):
    """RugMaps AI holder analysis. $0.02/call."""
    await verify_x402_payment(request, "rugmaps_analysis", 0.02)
    result = await databus.fetch(
        "rugmaps_analysis",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/wallet-balance")
async def x402_wallet_balance(req: AddressRequest, request: Request):
    """Wallet balance check. $0.01/call."""
    await verify_x402_payment(request, "wallet_balance", 0.01)
    result = await databus.fetch("wallet_balance", address=req.address, consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


@router.post("/wallet-labels")
async def x402_wallet_labels(req: AddressRequest, request: Request):
    """Wallet entity lookup. $0.02/call."""
    await verify_x402_payment(request, "wallet_labels", 0.02)
    result = await databus.fetch(
        "wallet_labels",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/risk-scan")
async def x402_risk_scan(req: AddressRequest, request: Request):
    """RugShield quick scan. $0.02/call."""
    await verify_x402_payment(request, "risk_scan", 0.02)
    result = await databus.fetch(
        "risk_scan",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/threat-check")
async def x402_threat_check(req: AddressRequest, request: Request):
    """Threat intel check. $0.02/call."""
    await verify_x402_payment(request, "threat_check", 0.02)
    result = await databus.fetch(
        "threat_check",
        address=req.address,
        chain_id=req.chain,
        consumer_type="x402_paid",
        x402_tier="basic",
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/socialfi-resolve")
async def x402_socialfi_resolve(req: AddressRequest, request: Request):
    """Social identity resolver. $0.01/call."""
    await verify_x402_payment(request, "socialfi_resolve", 0.01)
    result = await databus.fetch("socialfi_resolve", address=req.address, consumer_type="x402_paid", x402_tier="basic")
    return _clean_response(result) or {"error": "no_data"}


# ── PREMIUM TIER ENDPOINTS ($0.05-$0.10) ─────────────────────────


@router.post("/wallet-profile")
async def x402_wallet_profile(req: AddressRequest, request: Request):
    """Wallet intelligence profiler. $0.05/call."""
    payment = await verify_x402_payment(request, "wallet_profile", 0.05)
    result = await databus.fetch(
        "wallet_profile",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/smart-money")
async def x402_smart_money(req: QueryRequest, request: Request):
    """Smart money tracker. $0.05/call."""
    payment = await verify_x402_payment(request, "smart_money", 0.05)
    result = await databus.fetch("smart_money", consumer_type="x402_paid", x402_tier="premium", **payment)
    return _clean_response(result) or {"error": "no_data"}


@router.post("/funding-source")
async def x402_funding_source(req: AddressRequest, request: Request):
    """Funding source tracer. $0.08/call."""
    payment = await verify_x402_payment(request, "funding_source", 0.08)
    chain_id = {
        "solana": 0,
        "ethereum": 1,
        "bsc": 56,
        "base": 8453,
        "arbitrum": 42161,
        "optimism": 10,
        "polygon": 137,
    }.get(req.chain, 1)
    result = await databus.fetch(
        "funding_source",
        address=req.address,
        chain_id=chain_id,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/cross-chain")
async def x402_cross_chain(req: AddressRequest, request: Request):
    """Cross-chain correlator. $0.08/call."""
    payment = await verify_x402_payment(request, "cross_chain", 0.08)
    result = await databus.fetch(
        "cross_chain",
        address=req.address,
        chains=req.chain,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/wallet-cluster")
async def x402_wallet_cluster(req: AddressRequest, request: Request):
    """Syndicate network mapper. $0.08/call."""
    payment = await verify_x402_payment(request, "wallet_cluster", 0.08)
    result = await databus.fetch(
        "wallet_cluster",
        address=req.address,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/bundle-detect")
async def x402_bundle_detect(req: AddressRequest, request: Request):
    """Bot activity detector. $0.08/call."""
    payment = await verify_x402_payment(request, "bundle_detect", 0.08)
    result = await databus.fetch(
        "bundle_detect",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/wallet-tokens")
async def x402_wallet_tokens(req: AddressRequest, request: Request):
    """Wallet token holdings. $0.05/call."""
    payment = await verify_x402_payment(request, "wallet_tokens", 0.05)
    result = await databus.fetch(
        "wallet_tokens",
        address=req.address,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/wallet-pnl")
async def x402_wallet_pnl(req: AddressRequest, request: Request):
    """Wallet PnL tracker. $0.05/call."""
    payment = await verify_x402_payment(request, "wallet_pnl", 0.05)
    result = await databus.fetch(
        "wallet_pnl", address=req.address, consumer_type="x402_paid", x402_tier="premium", **payment
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/contract-scan")
async def x402_contract_scan(req: AddressRequest, request: Request):
    """Deep contract auditor. $0.08/call."""
    payment = await verify_x402_payment(request, "contract_scan", 0.08)
    result = await databus.fetch(
        "contract_scan",
        address=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/sentinel-deep")
async def x402_sentinel_deep(req: AddressRequest, request: Request):
    """SENTINEL deep scan. $0.10/call."""
    payment = await verify_x402_payment(request, "sentinel_deep", 0.10)
    admin_key = request.headers.get("X-Admin-Key", "")
    result = await databus.fetch(
        "sentinel_deep",
        address=req.address,
        chain=req.chain,
        admin_key=admin_key,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/entity-intel")
async def x402_entity_intel(req: AddressRequest, request: Request):
    """Entity intelligence lookup. $0.10/call."""
    payment = await verify_x402_payment(request, "entity_intel", 0.10)
    admin_key = request.headers.get("X-Admin-Key", "")
    result = await databus.fetch(
        "entity_intel",
        address=req.address,
        admin_key=admin_key,
        consumer_type="x402_paid",
        x402_tier="premium",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/rag-search")
async def x402_rag_search(req: QueryRequest, request: Request):
    """Knowledge search engine. $0.05/call."""
    payment = await verify_x402_payment(request, "rag_search", 0.05)
    result = await databus.fetch(
        "rag_search", query=req.query, consumer_type="x402_paid", x402_tier="premium", **payment
    )
    return _clean_response(result) or {"error": "no_data"}


# ── ELITE TIER ENDPOINTS ($0.15-$0.40) ───────────────────────────


@router.post("/arkham-portfolio")
async def x402_arkham_portfolio(req: AddressRequest, request: Request):
    """Arkham portfolio intel. $0.25/call. Requires admin key."""
    payment = await verify_x402_payment(request, "arkham_portfolio", 0.25)
    admin_key = request.headers.get("X-Admin-Key", "")
    result = await databus.fetch(
        "arkham_portfolio",
        address=req.address,
        admin_key=admin_key,
        consumer_type="x402_paid",
        x402_tier="enterprise",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/arkham-transfers")
async def x402_arkham_transfers(req: AddressRequest, request: Request):
    """Arkham transfer tracer. $0.20/call."""
    payment = await verify_x402_payment(request, "arkham_transfers", 0.20)
    admin_key = request.headers.get("X-Admin-Key", "")
    result = await databus.fetch(
        "arkham_transfers",
        address=req.address,
        chain=req.chain,
        admin_key=admin_key,
        consumer_type="x402_paid",
        x402_tier="enterprise",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/nansen-labels")
async def x402_nansen_labels(req: AddressRequest, request: Request):
    """Nansen label intelligence. $0.15/call."""
    payment = await verify_x402_payment(request, "nansen_labels", 0.15)
    result = await databus.fetch(
        "nansen_labels",
        address=req.address,
        consumer_type="x402_paid",
        x402_tier="enterprise",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


@router.post("/portfolio")
async def x402_portfolio(req: AddressRequest, request: Request):
    """Multi-wallet portfolio tracker. $0.15/call."""
    payment = await verify_x402_payment(request, "portfolio", 0.15)
    result = await databus.fetch(
        "portfolio",
        wallet=req.address,
        chain=req.chain,
        consumer_type="x402_paid",
        x402_tier="enterprise",
        **payment,
    )
    return _clean_response(result) or {"error": "no_data"}


# ── UNIVERSAL DATA ENDPOINT ───────────────────────────────────────
# Single endpoint that accepts any data_type. Payment based on tier pricing.


@router.post("/fetch")
async def x402_universal_fetch(req: GenericDataRequest, request: Request):
    """
    Universal DataBus fetch through x402 paywall.
    Accepts any data_type. Pricing is automatic based on X402_TOOL_PRICING.
    """
    data_type = req.data_type
    if data_type not in X402_TOOL_PRICING:
        raise HTTPException(
            400,
            f"Unknown data_type: {data_type}. Available: {', '.join(sorted(X402_TOOL_PRICING.keys()))}",
        )

    pricing = X402_TOOL_PRICING[data_type]
    payment = await verify_x402_payment(request, data_type, pricing["price_usd"])

    x402_tier = "enterprise" if pricing["category"] == "elite" else pricing["category"]
    if payment.get("trial"):
        x402_tier = "free" if pricing["category"] == "basic" else x402_tier

    result = await databus.fetch(
        data_type=data_type,
        address=req.address,
        mint=req.mint,
        chain=req.chain,
        query=req.query,
        category=req.category,
        chain_id=req.chain_id,
        admin_key=req.admin_key,
        force_fresh=req.force_fresh,
        consumer_type="x402_paid",
        x402_tier=x402_tier,
    )

    if result is None:
        raise HTTPException(502, f"No data available for {data_type}")

    # Add payment metadata
    result["x402"] = {
        "tool_id": data_type,
        "price_usd": pricing["price_usd"],
        "price_atoms": pricing["price_atoms"],
        "category": pricing["category"],
        "trial": payment.get("trial", False),
        "description": pricing["description"],
    }

    return _clean_response(result)
