Files
LINUX-AETHERFORGE/internal/config/config.go
drjones 3678b199d0
Some checks failed
Test / test (push) Has been cancelled
Initial commit: AetherForge Linux (forge-mesh) v0.1.0-dev
2026-07-04 09:31:23 +00:00

135 lines
3.3 KiB
Go

package config
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
// Config holds forge-mesh server configuration loaded from config.json.
type Config struct {
ListenAddr string `json:"listen_addr"`
DataDir string `json:"data_dir"`
DatabasePath string `json:"database_path"`
OperatorClearance int `json:"operator_clearance"`
Auth AuthConfig `json:"auth"`
WalletPolicy WalletPolicy `json:"wallet_policy"`
Stratum StratumConfig `json:"stratum"`
Forge ForgeConfig `json:"forge"`
Court CourtConfig `json:"court"`
Telegram TelegramConfig `json:"telegram"`
}
// TelegramConfig holds alert bot settings (W19).
type TelegramConfig struct {
Enabled bool `json:"enabled"`
BotToken string `json:"bot_token"`
ChatID string `json:"chat_id"`
}
type AuthConfig struct {
BasicUsername string `json:"basic_username"`
BasicPassword string `json:"basic_password"`
FleetSecret string `json:"fleet_secret"`
}
type WalletPolicy struct {
DefaultWallet string `json:"default_wallet"`
Currency string `json:"currency"`
}
type StratumConfig struct {
XMRListen string `json:"xmr_listen"`
RVNListen string `json:"rvn_listen"`
UpstreamXMR string `json:"upstream_xmr"`
UpstreamRVN string `json:"upstream_rvn"`
}
type ForgeConfig struct {
SigningKeyPath string `json:"signing_key_path"`
ArtifactsDir string `json:"artifacts_dir"`
}
type CourtConfig struct {
OllamaURL string `json:"ollama_url"`
Enabled bool `json:"enabled"`
}
// Load reads and parses config from the given JSON file path.
func Load(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read config: %w", err)
}
var cfg Config
if err := json.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("parse config: %w", err)
}
cfg.applyDefaults(path)
if err := cfg.validate(); err != nil {
return nil, err
}
return &cfg, nil
}
func (c *Config) applyDefaults(configPath string) {
if c.ListenAddr == "" {
c.ListenAddr = ":8989"
}
if c.DataDir == "" {
c.DataDir = filepath.Dir(configPath)
}
if c.DatabasePath == "" {
c.DatabasePath = filepath.Join(c.DataDir, "forge-mesh.db")
}
if c.Auth.BasicUsername == "" {
c.Auth.BasicUsername = "admin"
}
if c.Auth.BasicPassword == "" {
c.Auth.BasicPassword = "changeme"
}
if c.WalletPolicy.Currency == "" {
c.WalletPolicy.Currency = "XMR"
}
if c.Stratum.XMRListen == "" {
c.Stratum.XMRListen = ":3333"
}
if c.Stratum.RVNListen == "" {
c.Stratum.RVNListen = ":3388"
}
if c.Forge.ArtifactsDir == "" {
c.Forge.ArtifactsDir = filepath.Join(c.DataDir, "artifacts")
}
if c.Forge.SigningKeyPath == "" {
c.Forge.SigningKeyPath = filepath.Join(c.DataDir, "signing.key")
}
if c.Court.OllamaURL == "" {
c.Court.OllamaURL = "http://127.0.0.1:11434"
}
if c.OperatorClearance == 0 {
c.OperatorClearance = 4
}
}
func (c *Config) validate() error {
if c.ListenAddr == "" {
return fmt.Errorf("listen_addr is required")
}
return nil
}
// EnsureDataDirs creates data directories referenced by the config.
func (c *Config) EnsureDataDirs() error {
dirs := []string{c.DataDir, c.Forge.ArtifactsDir}
for _, dir := range dirs {
if err := os.MkdirAll(dir, 0o755); err != nil {
return fmt.Errorf("mkdir %s: %w", dir, err)
}
}
return nil
}