1Branch0Tags
GL
glucryptoAdopt opentool 0.19.8
1f37f4912 days ago17Commits
typescript
import { DEFAULT_AMOUNT_USD, DEFAULT_ASSET, DEFAULT_MARKET_SYMBOL, DEFAULT_SCHEDULE_CRON, TEMPLATE_CONFIG_DEFAULTS, TEMPLATE_CONFIG_ENV_VAR, TEMPLATE_CONFIG_VERSION, } from "./defaults"; import { configSchema, TEMPLATE_CONFIG_SCHEMA } from "./schema"; import type { TwapBotConfig } from "./types"; function parseJson(value: string | null | undefined) { if (!value) return null; try { return JSON.parse(value) as unknown; } catch { return null; } } export function normalizeBaseAsset(value: string | null | undefined) { const trimmed = value?.trim().toUpperCase() ?? ""; if (!trimmed) return ""; const withoutDex = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed; const base = withoutDex.split(/[-/]/)[0] ?? withoutDex; return base.trim().toUpperCase(); } export function normalizeMarketSymbol(value: string | null | undefined) { const trimmed = value?.trim().toUpperCase() ?? ""; if (!trimmed) return ""; if (trimmed.includes("/")) return trimmed; if (trimmed.includes("-")) { const [base, ...rest] = trimmed.split("-"); const quote = rest.join("-").trim(); return base && quote ? `${base}/${quote}` : trimmed; } return trimmed; } export const TWAP_BOT_TEMPLATE_CONFIG = { version: TEMPLATE_CONFIG_VERSION, schema: TEMPLATE_CONFIG_SCHEMA, defaults: TEMPLATE_CONFIG_DEFAULTS, envVar: TEMPLATE_CONFIG_ENV_VAR, }; export function readConfig(): TwapBotConfig { const parsed = configSchema.safeParse( parseJson(process.env[TEMPLATE_CONFIG_ENV_VAR]), ); const input = parsed.success ? parsed.data : {}; const marketSymbol = normalizeMarketSymbol(input.marketSymbol) || DEFAULT_MARKET_SYMBOL; const asset = normalizeBaseAsset(marketSymbol) || DEFAULT_ASSET; return { configVersion: TEMPLATE_CONFIG_VERSION, platform: "hyperliquid", signalType: "twap", allocationMode: "fixed", asset, marketSymbol, amountUsd: input.amountUsd ?? DEFAULT_AMOUNT_USD, schedule: { cron: input.schedule?.cron ?? DEFAULT_SCHEDULE_CRON, enabled: input.schedule?.enabled ?? TEMPLATE_CONFIG_DEFAULTS.schedule.enabled, notifyEmail: input.schedule?.notifyEmail ?? TEMPLATE_CONFIG_DEFAULTS.schedule.notifyEmail, }, twap: { side: input.twap?.side ?? TEMPLATE_CONFIG_DEFAULTS.twap.side, minutes: input.twap?.minutes ?? TEMPLATE_CONFIG_DEFAULTS.twap.minutes, randomize: input.twap?.randomize ?? TEMPLATE_CONFIG_DEFAULTS.twap.randomize, }, execution: { enabled: input.execution?.enabled ?? TEMPLATE_CONFIG_DEFAULTS.execution!.enabled, environment: input.execution?.environment ?? TEMPLATE_CONFIG_DEFAULTS.execution!.environment, ...(typeof input.execution?.leverage === "number" ? { leverage: input.execution.leverage } : {}), }, }; } export function resolveScheduleConfig(config: TwapBotConfig) { return config.schedule; } export function resolveProfileAssets(config: TwapBotConfig) { const marketSymbol = (config.marketSymbol || config.asset).trim(); if (!marketSymbol) { return []; } return [ { venue: "hyperliquid" as const, chain: config.execution?.environment === "testnet" ? ("hyperliquid-testnet" as const) : ("hyperliquid" as const), assetSymbols: [marketSymbol], ...(typeof config.execution?.leverage === "number" ? { leverage: config.execution.leverage } : {}), }, ]; }