Gitleaks flagged 4 production secrets in rmi-backend source:
app/caching_shield/solana_tracker.py: st_ZMzXzdUI54TXQPx5E6JkG
app/databus/arkham_ws.py: ws_Z5x09Rcr_1780418740765322917
app/routers/webhooks_router.py: helius-rmi-wh-2024
rmi_helius_wh_secret_2024
app/routers/stripe_integration.py: pk_test_51Tn13MAXseReicQtM...
Each replaced with os.getenv() reads. Placeholder env lines added to
/srv/rmi-infra/.env.secrets. Keys themselves still need rotating at
the providers (Solana Tracker, Arkham, Helius, Stripe) and storing in
gopass — see REMAINING.md.
No behavior change: code that read from env before still does, and
the empty-string fallback means the call site is the same.
Note: this commit scrubs the keys from the working tree. They remain
in git history. A follow-up git filter-repo pass is required to purge
them from history (see REMAINING.md). After that, all clones and
external remotes must be force-updated.
111 lines
3.8 KiB
Python
111 lines
3.8 KiB
Python
"""
|
|
Arkham Intelligence WebSocket Client
|
|
=====================================
|
|
Real-time entity updates, transfer monitoring, label changes.
|
|
Auto-reconnects, caches through DataBus, triggers premium scanner.
|
|
|
|
WS Key: from ARKHAM_WS_KEY env var (set in /etc/secrets or docker env)
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
from datetime import datetime
|
|
|
|
import httpx
|
|
|
|
logger = logging.getLogger("arkham_ws")
|
|
|
|
ARKHAM_WS_URL = "wss://api.arkhamintelligence.com/ws"
|
|
|
|
# Track active subscriptions
|
|
_subscriptions: dict[str, dict] = {}
|
|
_connected = False
|
|
|
|
|
|
async def arkham_ws_subscribe(address: str = "", action: str = "subscribe", **kw) -> dict | None:
|
|
"""Subscribe to real-time updates for an address via Arkham WebSocket.
|
|
|
|
Args:
|
|
address: Ethereum/Solana address to track
|
|
action: 'subscribe', 'unsubscribe', or 'status'
|
|
|
|
Returns subscription status or cached data.
|
|
"""
|
|
ws_key = os.getenv("ARKHAM_WS_KEY", "") or kw.get("api_key", "")
|
|
|
|
if action == "status":
|
|
return {
|
|
"connected": _connected,
|
|
"active_subscriptions": len(_subscriptions),
|
|
"subscriptions": list(_subscriptions.keys())[:50],
|
|
"source": "arkham_ws",
|
|
}
|
|
|
|
if action == "unsubscribe":
|
|
_subscriptions.pop(address, None)
|
|
return {"status": "unsubscribed", "address": address, "source": "arkham_ws"}
|
|
|
|
if action == "subscribe" and address:
|
|
# Store subscription intent (actual WS connection is managed separately)
|
|
_subscriptions[address] = {
|
|
"subscribed_at": datetime.utcnow().isoformat(),
|
|
"last_update": None,
|
|
}
|
|
|
|
# Also fetch current entity data via REST as seed
|
|
try:
|
|
api_key = os.getenv("ARKHAM_API_KEY", "")
|
|
if api_key:
|
|
async with httpx.AsyncClient(timeout=10) as c:
|
|
r = await c.get(
|
|
f"https://api.arkhamintelligence.com/intelligence/address/{address}",
|
|
headers={"API-Key": api_key},
|
|
)
|
|
if r.status_code == 200:
|
|
data = r.json()
|
|
_subscriptions[address]["entity"] = data.get("arkhamEntity", {}).get("name", "")
|
|
_subscriptions[address]["label"] = data.get("arkhamLabel", {}).get("name", "")
|
|
_subscriptions[address]["last_update"] = datetime.utcnow().isoformat()
|
|
|
|
return {
|
|
"status": "subscribed",
|
|
"address": address,
|
|
"entity": data.get("arkhamEntity", {}),
|
|
"label": data.get("arkhamLabel", {}),
|
|
"chain": data.get("chain"),
|
|
"ws_key_active": bool(ws_key),
|
|
"source": "arkham_ws",
|
|
}
|
|
except Exception as e:
|
|
logger.warning(f"Arkham WS seed fetch failed for {address}: {e}")
|
|
|
|
return {
|
|
"status": "subscribed",
|
|
"address": address,
|
|
"ws_key_active": bool(ws_key),
|
|
"source": "arkham_ws",
|
|
}
|
|
|
|
return {"status": "no_action", "source": "arkham_ws"}
|
|
|
|
|
|
async def broadcast_ws_update(address: str, update: dict):
|
|
"""Called when Arkham WS pushes an update — route through DataBus."""
|
|
if address in _subscriptions:
|
|
_subscriptions[address]["last_update"] = datetime.utcnow().isoformat()
|
|
_subscriptions[address]["latest_data"] = update
|
|
|
|
# Push to DataBus WebSocket for frontend subscribers
|
|
try:
|
|
from app.databus.ws_stream import ws_manager
|
|
|
|
await ws_manager.broadcast(
|
|
"arkham_realtime",
|
|
{
|
|
"address": address,
|
|
"update": update,
|
|
"timestamp": datetime.utcnow().isoformat(),
|
|
},
|
|
)
|
|
except Exception:
|
|
pass
|