File size: 2,235 Bytes
9e22644
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { NextResponse } from 'next/server'
import { fetchWalletSignals, isHeliusConfigured } from '@/lib/helius'
import { calculateChurnScore } from '@/lib/agent-engine'
import { sendCustomEvent, isTorqueConfigured } from '@/lib/torque-mcp'
import { pushEvent } from '@/lib/event-store'
import { recordIntervention } from '@/lib/attribution-store'

export async function POST(req: Request) {
  const { address, autoFire = false } = await req.json()

  if (!address || typeof address !== 'string') {
    return NextResponse.json({ error: 'address required' }, { status: 400 })
  }
  if (!isHeliusConfigured()) {
    return NextResponse.json({ error: 'HELIUS_API_KEY not configured' }, { status: 503 })
  }

  const signals = await fetchWalletSignals(address)
  if (!signals) {
    return NextResponse.json({ error: 'Failed to fetch wallet data from Helius' }, { status: 502 })
  }

  const { score, risk, signals: detectedSignals } = calculateChurnScore({
    daysInactive: signals.daysInactive,
    volumeDropPct: signals.volumeDropPct,
    uniqueProtocols: signals.uniqueProtocols,
    currentStreak: signals.currentStreak,
    hasLiquidation: signals.hasLiquidation,
  })

  let torqueResult: { fired: boolean; eventId?: string; eventName?: string } = { fired: false }

  if (autoFire && isTorqueConfigured() && (risk === 'critical' || risk === 'high' || risk === 'medium')) {
    const eventName = risk === 'critical' || risk === 'high' ? 'churn_risk_high' : 'churn_risk_medium'
    const result = await sendCustomEvent(address, eventName, {
      risk, score,
      daysInactive: signals.daysInactive,
      protocols: signals.protocols,
      source: 'helius_live',
      detectedBy: 'flowstate-helius-scan',
    })
    if (result.success && result.eventId) {
      pushEvent({
        ingestionId: result.eventId,
        wallet: address,
        eventName,
        risk,
        score,
        firedAt: new Date().toISOString(),
        source: 'scan',
      })
      recordIntervention(address, eventName, score)
      torqueResult = { fired: true, eventId: result.eventId, eventName }
    }
  }

  return NextResponse.json({
    address,
    signals,
    score,
    risk,
    detectedSignals,
    torque: torqueResult,
  })
}