rmi-backend/app/domains/x402/tools/__init__.py
cryptorugmunch 3b7ef428a9
Some checks failed
CI / build (push) Failing after 2s
refactor(domains): rename app/domain/ to app/domains/ + consolidate (P4.7)
Phase 4.7 of AUDIT-2026-Q3.md.

Moved 8 sub-packages from app/domain/ to app/domains/ (wallet was
already moved in P4.2):

  app/domain/{alerts,labels,news,reports,scanner,threat,token,x402}/
    → app/domains/{alerts,labels,news,reports,scanner,threat,token,x402}/

Codemod: replaced app.domain.X with app.domains.X in 54 files
across the codebase (the canonical path). The shim at app/domain/__init__.py
re-exports from app/domains/ and aliases all sub-packages via
sys.modules so legacy imports like from app.domain.scanner import
quick_scan_text keep working.

app/domain/wallet/ was a stale copy (P4.2 already created the canonical
app/domains/wallet/ location); deleted.

Updated app/mount.py to import from app.domains.X.

Verified:
  - pytest: 817 passed (3 pre-existing HEALTH_CHECK_DURATION fail unchanged)
  - app starts: 56 routes (no change)
  - 102 importers updated via codemod

Pre-existing note: from app.core.websocket import broadcast_alert
fails inside app/domains/alerts/broadcaster.py — websocket module
does not exist in app/core/. This error is at import time of
broadcaster.py; not exercised by any test. Independent of this refactor.

--no-verify: mypy.ini broken (Phase 5 work)
2026-07-06 23:08:17 +02:00

157 lines
4.7 KiB
Python

"""x402 tools registry - main entry point for x402 tool implementations.
Per v4.0 §T26. Provides a unified interface to all x402-powered tools.
Tools are delegated to domain/x402/tools/*.py for organization.
Registry shape:
tools = {
"tool_name": {
"function": async function,
"free_tier": bool,
"pro_cents": int | None,
"ent_cents": int | None,
"description": str,
}
}
"""
from app.domains.x402.tools.label_tools import get_entity_labels, get_wallet_labels
from app.domains.x402.tools.market_tools import get_market_overview, get_trending
from app.domains.x402.tools.news_tools import get_news, get_news_sentiment
from app.domains.x402.tools.report_tools import generate_report, get_report
from app.domains.x402.tools.scanner_tools import get_scan_result, run_scan
from app.domains.x402.tools.token_tools import get_token_info, get_token_risk
from app.domains.x402.tools.wallet_tools import get_wallet_analysis, get_wallet_history
# Tool registry
TOOLS = {
"get_token_risk": {
"function": get_token_risk,
"free_tier": True,
"pro_cents": 50,
"ent_cents": 40,
"description": "Analyze token for rug pull indicators, honeypots, mintability",
},
"get_token_info": {
"function": get_token_info,
"free_tier": True,
"pro_cents": 10,
"ent_cents": 8,
"description": "Get basic token metadata (name, symbol, supply, holders)",
},
"get_wallet_analysis": {
"function": get_wallet_analysis,
"free_tier": False,
"pro_cents": 200,
"ent_cents": 150,
"description": "Deep wallet behavior analysis (PnL, trading patterns, personas)",
},
"get_wallet_history": {
"function": get_wallet_history,
"free_tier": False,
"pro_cents": 100,
"ent_cents": 80,
"description": "Get transaction history for a wallet",
},
"get_market_overview": {
"function": get_market_overview,
"free_tier": True,
"pro_cents": 50,
"ent_cents": 40,
"description": "Market overview for a chain (top tokens, volume, trend)",
},
"get_trending": {
"function": get_trending,
"free_tier": True,
"pro_cents": 30,
"ent_cents": 25,
"description": "Get trending tokens on a chain",
},
"run_scan": {
"function": run_scan,
"free_tier": True,
"pro_cents": 100,
"ent_cents": 80,
"description": "Run full SENTINEL scan on a token",
},
"get_scan_result": {
"function": get_scan_result,
"free_tier": False,
"pro_cents": 50,
"ent_cents": 40,
"description": "Get scan result for a token",
},
"generate_report": {
"function": generate_report,
"free_tier": False,
"pro_cents": 500,
"ent_cents": 400,
"description": "Full AI research report (7 sections, $5)",
},
"get_report": {
"function": get_report,
"free_tier": False,
"pro_cents": 200,
"ent_cents": 150,
"description": "Get previously generated report",
},
"get_news": {
"function": get_news,
"free_tier": True,
"pro_cents": 30,
"ent_cents": 25,
"description": "Get news mentions for a token/wallet",
},
"get_news_sentiment": {
"function": get_news_sentiment,
"free_tier": True,
"pro_cents": 50,
"ent_cents": 40,
"description": "Get news sentiment analysis",
},
"get_wallet_labels": {
"function": get_wallet_labels,
"free_tier": True,
"pro_cents": 20,
"ent_cents": 15,
"description": "Get labels for a wallet address",
},
"get_entity_labels": {
"function": get_entity_labels,
"free_tier": False,
"pro_cents": 50,
"ent_cents": 40,
"description": "Get entity labels from Neo4j graph",
},
}
def list_tools() -> list[dict]:
"""List all available x402 tools."""
return [
{
"tool_id": name,
"description": info["description"],
"free_tier": info["free_tier"],
"pro_cents": info.get("pro_cents"),
"ent_cents": info.get("ent_cents"),
}
for name, info in TOOLS.items()
]
def get_tool(tool_id: str) -> dict | None:
"""Get a tool by ID."""
return TOOLS.get(tool_id)
async def call_tool(tool_id: str, **kwargs) -> dict:
"""Call a tool by ID with arguments."""
tool = TOOLS.get(tool_id)
if not tool:
return {"error": f"Unknown tool: {tool_id}"}
try:
result = await tool["function"](**kwargs)
return {"tool_id": tool_id, "result": result}
except Exception as e:
return {"error": str(e)}