config.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. export interface BotConfig {
  2. rpc: { primary: string; fallback: string[] }
  3. contracts: {
  4. lbPair: `0x${string}`
  5. lbRouter: `0x${string}`
  6. lbFactory: `0x${string}`
  7. tokenX: `0x${string}`
  8. tokenY: `0x${string}`
  9. wmon: `0x${string}`
  10. usdc: `0x${string}`
  11. }
  12. strategy: {
  13. numBins: number
  14. distribution: 'uniform' | 'curve'
  15. positionSizeUSD: number
  16. slippageBps: number
  17. rebalanceCooldownMs: number
  18. gasLimitMultiplier: number
  19. pollIntervalMs: number
  20. maxDailyRebalances: number
  21. }
  22. notifications: {
  23. enabled: boolean
  24. provider: 'discord' | 'bark' | 'ntfy' | 'pushover'
  25. endpoint: string
  26. alertOnRebalance: boolean
  27. alertOnError: boolean
  28. alertOnLowBalance: boolean
  29. }
  30. }
  31. const env = (key: string, fallback = ''): string => process.env[key] ?? fallback
  32. const addr = (key: string, fallback = ''): `0x${string}` => {
  33. const v = env(key, fallback)
  34. if (!v.startsWith('0x')) throw new Error(`${key} must start with 0x`)
  35. return v as `0x${string}`
  36. }
  37. export const CHAIN_ID = 143
  38. export const BIN_STEP = Number(env('BIN_STEP', '5'))
  39. export const MON_DECIMALS = 18
  40. export const USDC_DECIMALS = 6
  41. export const config: BotConfig = {
  42. rpc: {
  43. primary: env('MONAD_RPC_URL', 'https://monad-mainnet.g.alchemy.com/v2/public'),
  44. fallback: env('MONAD_RPC_FALLBACK')
  45. .split(',')
  46. .map((s) => s.trim())
  47. .filter(Boolean),
  48. },
  49. contracts: {
  50. lbPair: addr('LB_PAIR_ADDRESS', '0x5afd3ec861f6104af26e8755abcc1f876de77620'),
  51. lbRouter: addr('LB_ROUTER_ADDRESS', '0x18556DA13313f3532c54711497A8FedAC273220E'),
  52. lbFactory: addr('LB_FACTORY_ADDRESS', '0xb43120c4745967fa9b93E79C149E66B0f2D6Fe0c'),
  53. tokenX: addr('WMON_ADDRESS', '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A'),
  54. tokenY: addr('USDC_ADDRESS', '0x754704bc059f8c67012fed69bc8a327a5aafb603'),
  55. wmon: addr('WMON_ADDRESS', '0x3bd359C1119dA7Da1D913D1C4D2B7c461115433A'),
  56. usdc: addr('USDC_ADDRESS', '0x754704bc059f8c67012fed69bc8a327a5aafb603'),
  57. },
  58. strategy: {
  59. numBins: Number(env('NUM_BINS', '3')),
  60. distribution: 'uniform',
  61. positionSizeUSD: Number(env('POSITION_SIZE_USD', '50')),
  62. slippageBps: Number(env('SLIPPAGE_BPS', '50')),
  63. rebalanceCooldownMs: Number(env('REBALANCE_COOLDOWN_MS', '10000')),
  64. gasLimitMultiplier: Number(env('GAS_LIMIT_MULTIPLIER', '1.2')),
  65. pollIntervalMs: Number(env('POLL_INTERVAL_MS', '3000')),
  66. maxDailyRebalances: Number(env('MAX_DAILY_REBALANCES', '50')),
  67. },
  68. notifications: {
  69. enabled: env('DISCORD_WEBHOOK_URL') !== '',
  70. provider: 'discord' as const,
  71. endpoint: env('DISCORD_WEBHOOK_URL'),
  72. alertOnRebalance: true,
  73. alertOnError: true,
  74. alertOnLowBalance: true,
  75. },
  76. }