101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import { eq } from 'drizzle-orm'
|
|
import { pollBreakout } from '@trumpsignal/backend/breakout'
|
|
import { createDatabase, subscriptions } from '@trumpsignal/database'
|
|
import { createContext } from '@trumpsignal/backend/context'
|
|
import { readConfig } from '@trumpsignal/backend/config'
|
|
import { createServices } from '@trumpsignal/backend/services'
|
|
import {
|
|
reanalyze,
|
|
backtestBatch,
|
|
backtestPost,
|
|
backfillImpact,
|
|
} from '@trumpsignal/backend/operations'
|
|
import { decryptApiKey, encryptApiKey } from '@trumpsignal/core/crypto'
|
|
const config = readConfig(),
|
|
database = createDatabase(config.database_url),
|
|
c = createContext(database, config),
|
|
s = createServices(c),
|
|
[command, arg] = process.argv.slice(2)
|
|
try {
|
|
let result: unknown
|
|
switch (command) {
|
|
case 'breakout':
|
|
result = await pollBreakout(c, s.state)
|
|
break
|
|
case 'preflight':
|
|
await database.pool.query('SELECT 1')
|
|
result = {
|
|
database: true,
|
|
encryption_key_configured: config.encryption_key.length >= 32,
|
|
ingest_configured: !!config.ingest_api_key,
|
|
telegram_configured: s.telegram.configured(),
|
|
ai_configured: !!(config.ai_api_key || config.anthropic_api_key),
|
|
}
|
|
break
|
|
case 'seed-wallets':
|
|
result = await s.kol.seed()
|
|
break
|
|
case 'truth-backfill':
|
|
result = await s.truth.cnn(true)
|
|
break
|
|
case 'kol-feeds':
|
|
result = await s.kol.pollFeeds()
|
|
break
|
|
case 'kol-x':
|
|
result = await s.kol.pollX()
|
|
break
|
|
case 'onchain':
|
|
result = await s.onchain.poll()
|
|
break
|
|
case 'divergence':
|
|
result = await s.kol.divergence(Number(arg) || 30)
|
|
break
|
|
case 'macro':
|
|
result = await s.macro.poll()
|
|
break
|
|
case 'backfill-prices':
|
|
result = await backfillImpact(c, arg ?? 'BTC')
|
|
break
|
|
case 'reanalyze':
|
|
result = await reanalyze(c, s, {
|
|
limit: Number(arg) || 500,
|
|
dry_run: process.env.DRY_RUN !== 'false',
|
|
delay_secs: 0.5,
|
|
legacy_signals: true,
|
|
})
|
|
break
|
|
case 'backtest':
|
|
result = await backtestPost(c, Number(arg))
|
|
break
|
|
case 'backtest-batch':
|
|
result = await backtestBatch(c, Number(arg) || 50)
|
|
break
|
|
case 'reencrypt-keys': {
|
|
const old = process.env.OLD_ENCRYPTION_KEY ?? config.encryption_key,
|
|
dry = process.env.DRY_RUN !== 'false',
|
|
rows = await c.db.select().from(subscriptions)
|
|
let changed = 0
|
|
for (const row of rows) {
|
|
if (!row.hl_api_key) continue
|
|
const key = await decryptApiKey(row.hl_api_key, old, config.environment)
|
|
if (!dry)
|
|
await c.db
|
|
.update(subscriptions)
|
|
.set({ hl_api_key: await encryptApiKey(key, config.encryption_key) })
|
|
.where(eq(subscriptions.id, row.id))
|
|
changed++
|
|
}
|
|
result = { dry_run: dry, keys_processed: changed }
|
|
break
|
|
}
|
|
default:
|
|
throw new Error(
|
|
'Commands: preflight, seed-wallets, truth-backfill, kol-feeds, kol-x, onchain, divergence, macro, backfill-prices, reanalyze, backtest, backtest-batch, reencrypt-keys',
|
|
)
|
|
}
|
|
process.stdout.write(JSON.stringify(result ?? { ok: true }, null, 2) + '\n')
|
|
} finally {
|
|
await database.pool.end()
|
|
await database.lockPool.end()
|
|
}
|