Some checks failed
CI / build (push) Failing after 2s
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)
100 lines
3.9 KiB
Python
100 lines
3.9 KiB
Python
"""Market data fetchers - DexScreener, GoPlus, Solana RPC."""
|
|
|
|
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from app.domains.scanner.models import SOLANA_RPC_ENDPOINTS
|
|
|
|
logger = __import__("app.core.logging", fromlist=["get_logger"]).get_logger(__name__)
|
|
|
|
|
|
async def _solana_get_mint_info(token_address: str) -> dict[str, Any]:
|
|
"""Get mint info from Solana RPC."""
|
|
result = {
|
|
"mint_authority": "unknown",
|
|
"freeze_authority": "unknown",
|
|
"decimals": None,
|
|
"supply": None,
|
|
}
|
|
for rpc_url in SOLANA_RPC_ENDPOINTS:
|
|
try:
|
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
resp = await client.post(
|
|
rpc_url,
|
|
json={
|
|
"jsonrpc": "2.0",
|
|
"id": 1,
|
|
"method": "getAccountInfo",
|
|
"params": [token_address, {"encoding": "jsonParsed"}],
|
|
},
|
|
)
|
|
if resp.status_code == 200:
|
|
data = resp.json()
|
|
val = (data.get("result") or {}).get("value")
|
|
if val:
|
|
parsed = (val.get("data") or {}).get("parsed", {})
|
|
if parsed.get("type") == "mint":
|
|
info = parsed.get("info", {})
|
|
result["mint_authority"] = info.get("mintAuthority", "unknown")
|
|
result["freeze_authority"] = info.get("freezeAuthority", "unknown")
|
|
result["decimals"] = info.get("decimals")
|
|
result["supply"] = info.get("supply")
|
|
break
|
|
except Exception as e:
|
|
logger.warning("solana_rpc_failed", url=rpc_url, error=str(e))
|
|
return result
|
|
|
|
|
|
async def _dexscreener_lookup(token_address: str, chain: str, client: httpx.AsyncClient) -> list | None:
|
|
"""Look up token on DexScreener."""
|
|
try:
|
|
url = f"https://api.dexscreener.com/latest/dex/tokens/{token_address}"
|
|
resp = await client.get(url, timeout=10.0)
|
|
if resp.status_code == 200:
|
|
data = resp.json()
|
|
return data.get("pairs")
|
|
except Exception as e:
|
|
logger.warning("dexscreener_lookup_failed", token=token_address, chain=chain, error=str(e))
|
|
return None
|
|
|
|
|
|
async def fetch_market_data(token_address: str, chain: str) -> dict[str, Any]:
|
|
"""Fetch market data from DexScreener and Solana RPC."""
|
|
result = {"chain": chain, "token_address": token_address}
|
|
|
|
async with httpx.AsyncClient(timeout=10.0) as client:
|
|
pairs = await _dexscreener_lookup(token_address, chain, client)
|
|
if pairs:
|
|
result["pairs"] = pairs[:5] # Top 5 pairs
|
|
|
|
if chain == "solana":
|
|
mint_info = await _solana_get_mint_info(token_address)
|
|
result["solana_mint"] = mint_info
|
|
|
|
return result
|
|
|
|
|
|
async def _simulate_trade(token_address: str, chain: str) -> dict[str, Any] | None:
|
|
"""Simulate a trade to check for honeypot/mint issues."""
|
|
# Placeholder - actual simulation logic would be in simulation.py
|
|
logger.info("simulate_trade_started", token=token_address, chain=chain)
|
|
return None
|
|
|
|
|
|
async def _check_honeypot_is(token_address: str, chain: str) -> dict[str, Any] | None:
|
|
"""Check if token is a honeypot using IS platform."""
|
|
logger.info("check_honeypot_is", token=token_address, chain=chain)
|
|
return {"check": "honeypot_is", "result": "pending"}
|
|
|
|
|
|
async def _check_chainpatrol_asset(asset_type: str, asset_id: str) -> dict[str, Any] | None:
|
|
"""Check asset on ChainPatrol."""
|
|
logger.info("check_chainpatrol", type=asset_type, id=asset_id)
|
|
return {"check": "chainpatrol", "result": "pending"}
|
|
|
|
|
|
async def _check_defi_scanner(token_address: str, chain: str) -> dict[str, Any] | None:
|
|
"""Check token on DeFi Scanner."""
|
|
logger.info("check_defi_scanner", token=token_address, chain=chain)
|
|
return {"check": "defi_scanner", "result": "pending"}
|