import React, { useMemo, useState } from "react"; import { Box, Text, useInput } from "ink"; import { TrendApp } from "./TrendApp"; import { GuardianApp } from "./GuardianApp"; import { MakerApp } from "./MakerApp"; import { MakerPointsApp } from "./MakerPointsApp"; import { OffsetMakerApp } from "./OffsetMakerApp"; import { LiquidityMakerApp } from "./LiquidityMakerApp"; import { GridApp } from "./GridApp"; import { BasisApp } from "./BasisApp"; import { isBasisStrategyEnabled } from "../config"; import { loadCopyrightFragments, verifyCopyrightIntegrity } from "../utils/copyright"; import { resolveExchangeId } from "../exchanges/create-adapter"; import { t } from "../i18n"; interface StrategyOption { id: "trend" | "guardian" | "maker" | "maker-points" | "offset-maker" | "liquidity-maker" | "basis" | "grid"; label: string; description: string; component: React.ComponentType<{ onExit: () => void }>; } const BASE_STRATEGIES: StrategyOption[] = [ { id: "trend", label: t("app.strategy.trend.label"), description: t("app.strategy.trend.desc"), component: TrendApp, }, { id: "guardian", label: t("app.strategy.guardian.label"), description: t("app.strategy.guardian.desc"), component: GuardianApp, }, { id: "maker", label: t("app.strategy.maker.label"), description: t("app.strategy.maker.desc"), component: MakerApp, }, { id: "grid", label: t("app.strategy.grid.label"), description: t("app.strategy.grid.desc"), component: GridApp, }, { id: "offset-maker", label: t("app.strategy.offset.label"), description: t("app.strategy.offset.desc"), component: OffsetMakerApp, }, { id: "liquidity-maker", label: t("app.strategy.liquidityMaker.label"), description: t("app.strategy.liquidityMaker.desc"), component: LiquidityMakerApp, }, ]; const inputSupported = Boolean(process.stdin && (process.stdin as any).isTTY); export function App() { const [cursor, setCursor] = useState(0); const [selected, setSelected] = useState(null); const copyright = useMemo(() => loadCopyrightFragments(), []); const integrityOk = useMemo(() => verifyCopyrightIntegrity(), []); const exchangeId = useMemo(() => resolveExchangeId(), []); const strategies = useMemo(() => { const next: StrategyOption[] = [...BASE_STRATEGIES]; if (exchangeId === "standx") { next.splice(3, 0, { id: "maker-points" as const, label: t("app.strategy.makerPoints.label"), description: t("app.strategy.makerPoints.desc"), component: MakerPointsApp, }); } if (isBasisStrategyEnabled()) { next.push({ id: "basis" as const, label: t("app.strategy.basis.label"), description: t("app.strategy.basis.desc"), component: BasisApp, }); } return next; }, [exchangeId]); useInput( (input, key) => { if (selected) return; if (key.upArrow) { setCursor((prev) => (prev - 1 + strategies.length) % strategies.length); } else if (key.downArrow) { setCursor((prev) => (prev + 1) % strategies.length); } else if (key.return) { const strategy = strategies[cursor]; if (strategy) { setSelected(strategy); } } }, { isActive: inputSupported && !selected } ); if (selected) { const Selected = selected.component; return setSelected(null)} />; } return ( {copyright.bannerText} {integrityOk ? null : ( {t("app.integrity.warning")} )} ──────────────────────────────────────────────────── {t("app.pickStrategy")} {t("app.pickHint")} {strategies.map((strategy, index) => { const active = index === cursor; return ( {active ? "➤" : " "} {strategy.label} {strategy.description} ); })} ); }