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)
74 lines
2.5 KiB
Python
74 lines
2.5 KiB
Python
"""Solana wallet labels CSV source - 103K SOL labels via DuckDB."""
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import logging
|
|
from datetime import UTC, datetime
|
|
|
|
from app.domains.labels.models import Label, LabelSource
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
CSV_PATH = "/home/dev/rmi/backend/data/wallet-labels-clean/wallet_labels_solana.csv"
|
|
|
|
|
|
async def query_solana_labels_csv(address: str, chain: str = "solana") -> list[Label]:
|
|
"""Query the Solana wallet labels CSV via DuckDB.
|
|
|
|
Schema (likely): address,source,name,entity_type,threat_group,risk_level
|
|
|
|
Only matches if chain == "solana" - returns [] for EVM chains.
|
|
"""
|
|
if chain != "solana":
|
|
return []
|
|
|
|
def _query() -> list[Label]:
|
|
from app.core.duckdb_analytics import DuckDBAnalytics
|
|
|
|
try:
|
|
d = DuckDBAnalytics()
|
|
try:
|
|
rows = d.query_parquet(
|
|
CSV_PATH,
|
|
"""
|
|
SELECT *
|
|
FROM data
|
|
WHERE LOWER(address) = ?
|
|
LIMIT 20
|
|
""",
|
|
[address.lower()],
|
|
)
|
|
labels = []
|
|
for row in rows:
|
|
# Field names may differ - try common names
|
|
label_value = (
|
|
row.get("name")
|
|
or row.get("label")
|
|
or row.get("entity_type")
|
|
or row.get("source")
|
|
)
|
|
if not label_value:
|
|
continue
|
|
labels.append(
|
|
Label(
|
|
address=row.get("address", address).lower(),
|
|
chain="solana",
|
|
label_type="entity",
|
|
label_value=label_value,
|
|
source=LabelSource.SOLANA_LABELS_CSV,
|
|
confidence=0.8,
|
|
verified_at=datetime.now(UTC),
|
|
attributes={
|
|
k: v for k, v in row.items()
|
|
if k not in ("address", "name", "label") and v
|
|
},
|
|
)
|
|
)
|
|
return labels
|
|
finally:
|
|
d.close()
|
|
except Exception as e:
|
|
log.warning("solana_labels_csv_query_fail address=%s err=%s", address[:10], e)
|
|
raise
|
|
|
|
return await asyncio.to_thread(_query)
|