{"path":"oracle/src/config.ts","size":2047,"locked":false,"binary":false,"truncated":false,"content":"import * as dotenv from \"dotenv\";\ndotenv.config();\n\nfunction required(key: string): string {\n  const value = process.env[key];\n  if (!value || value.trim() === \"\") {\n    throw new Error(`Missing required environment variable: ${key}`);\n  }\n  return value.trim();\n}\n\nfunction optional(key: string, fallback: string): string {\n  return process.env[key]?.trim() || fallback;\n}\n\nfunction optionalNumber(key: string, fallback: number): number {\n  const val = process.env[key];\n  if (!val) return fallback;\n  const parsed = parseFloat(val);\n  if (isNaN(parsed)) throw new Error(`${key} must be a valid number`);\n  return parsed;\n}\n\nexport const config = {\n  solana: {\n    rpcUrl:         required(\"SOLANA_RPC_URL\"),\n    programId:      required(\"PROGRAM_ID\"),\n    oraclePrivateKey: required(\"ORACLE_PRIVATE_KEY\"),\n  },\n  helius: {\n    grpcEndpoint: required(\"HELIUS_GRPC_ENDPOINT\"),\n    apiKey:       required(\"HELIUS_API_KEY\"),\n  },\n  ai: {\n    geminiApiKey:    required(\"GEMINI_API_KEY\"),\n    anthropicApiKey: required(\"ANTHROPIC_API_KEY\"),\n    geminiModel: optional(\"GEMINI_MODEL\", \"gemini-3.5-flash\"),\n    anthropicModel:  optional(\"ANTHROPIC_MODEL\", \"claude-sonnet-4-6\"),\n    approvalThreshold:  optionalNumber(\"APPROVAL_CONFIDENCE_THRESHOLD\", 0.80),\n    rejectionThreshold: optionalNumber(\"REJECTION_CONFIDENCE_THRESHOLD\", 0.75),\n  },\n  server: {\n    port: (() => {\n      const raw = optional(\"PORT\", \"3001\");\n      const parsed = parseInt(raw, 10);\n      if (isNaN(parsed) || parsed < 1 || parsed > 65535) {\n        throw new Error(`PORT must be a valid port number (1-65535), got: \"${raw}\"`);\n      }\n      return parsed;\n    })(),\n    corsOrigins: optional(\"CORS_ALLOWED_ORIGINS\", \"\"),\n    rateLimitWindowMs: optionalNumber(\"RATE_LIMIT_WINDOW_MS\", 60_000),\n    rateLimitMax: optionalNumber(\"RATE_LIMIT_MAX_REQUESTS\", 20),\n    apiKey: optional(\"ORACLE_API_KEY\", \"\"),\n  },\n  sentry: {\n    dsn:     optional(\"SENTRY_DSN\", \"\"),\n    enabled: !!process.env.SENTRY_DSN,\n  },\n  isDev: optional(\"NODE_ENV\", \"development\") === \"development\",\n} as const;\n"}