export interface BotConfig { rpc: { primary: string; fallback: string[] } contracts: { lbPair: `0x${string}` lbRouter: `0x${string}` lbFactory: `0x${string}` tokenX: `0x${string}` tokenY: `0x${string}` wmon: `0x${string}` usdc: `0x${string}` } strategy: { numBins: number distribution: 'uniform' | 'curve' positionSizeUSD: number slippageBps: number rebalanceCooldownMs: number gasLimitMultiplier: number pollIntervalMs: number maxDailyRebalances: number } notifications: { enabled: boolean provider: 'discord' | 'bark' | 'ntfy' | 'pushover' endpoint: string alertOnRebalance: boolean alertOnError: boolean alertOnLowBalance: boolean } } const env = (key: string, fallback = ''): string => process.env[key] ?? fallback const addr = (key: string, fallback = ''): `0x${string}` => { const v = env(key, fallback) if (!v.startsWith('0x')) throw new Error(`${key} must start with 0x`) return v as `0x${string}` } export const CHAIN_ID = 143 export const BIN_STEP = Number(env('BIN_STEP', '5')) export const MON_DECIMALS = 18 export const USDC_DECIMALS = 6 export const config: BotConfig = { rpc: { primary: env('MONAD_RPC_URL', 'https://monad-mainnet.g.alchemy.com/v2/public'), fallback: env('MONAD_RPC_FALLBACK') .split(',') .map((s) => s.trim()) .filter(Boolean), }, contracts: { lbPair: addr('LB_PAIR_ADDRESS', '0x5afd3ec861f6104af26e8755abcc1f876de77620'), lbRouter: addr('LB_ROUTER_ADDRESS', '0x18556DA13313f3532c54711497A8FedAC273220E'), lbFactory: addr('LB_FACTORY_ADDRESS', '0xb43120c4745967fa9b93E79C149E66B0f2D6Fe0c'), tokenX: addr('WMON_ADDRESS', '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A'), tokenY: addr('USDC_ADDRESS', '0x754704bc059f8c67012fed69bc8a327a5aafb603'), wmon: addr('WMON_ADDRESS', '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A'), usdc: addr('USDC_ADDRESS', '0x754704bc059f8c67012fed69bc8a327a5aafb603'), }, strategy: { numBins: Number(env('NUM_BINS', '3')), distribution: 'uniform', positionSizeUSD: Number(env('POSITION_SIZE_USD', '50')), slippageBps: Number(env('SLIPPAGE_BPS', '50')), rebalanceCooldownMs: Number(env('REBALANCE_COOLDOWN_MS', '10000')), gasLimitMultiplier: Number(env('GAS_LIMIT_MULTIPLIER', '1.2')), pollIntervalMs: Number(env('POLL_INTERVAL_MS', '3000')), maxDailyRebalances: Number(env('MAX_DAILY_REBALANCES', '50')), }, notifications: { enabled: env('DISCORD_WEBHOOK_URL') !== '', provider: 'discord' as const, endpoint: env('DISCORD_WEBHOOK_URL'), alertOnRebalance: true, alertOnError: true, alertOnLowBalance: true, }, }