package openrpc import ( "encoding/json" "fmt" "io/ioutil" "path/filepath" "strings" "git.ourworld.tf/herocode/heroagent/pkg/openrpc/models" ) // ORPCManager manages OpenRPC specifications type ORPCManager struct { specs map[string]*models.OpenRPCSpec } // NewORPCManager creates a new OpenRPC Manager func NewORPCManager() *ORPCManager { return &ORPCManager{ specs: make(map[string]*models.OpenRPCSpec), } } // LoadSpecs loads all OpenRPC specifications from a directory func (m *ORPCManager) LoadSpecs(dir string) error { files, err := ioutil.ReadDir(dir) if err != nil { return fmt.Errorf("failed to read directory: %w", err) } for _, file := range files { if file.IsDir() { continue } if !strings.HasSuffix(file.Name(), ".json") { continue } path := filepath.Join(dir, file.Name()) if err := m.LoadSpec(path); err != nil { return fmt.Errorf("failed to load spec %s: %w", file.Name(), err) } } return nil } // LoadSpec loads an OpenRPC specification from a file func (m *ORPCManager) LoadSpec(path string) error { // Read the file data, err := ioutil.ReadFile(path) if err != nil { return fmt.Errorf("failed to read file: %w", err) } // Parse the JSON var spec models.OpenRPCSpec if err := json.Unmarshal(data, &spec); err != nil { return fmt.Errorf("failed to parse JSON: %w", err) } // Validate the specification if err := spec.Validate(); err != nil { return fmt.Errorf("invalid specification: %w", err) } // Store the specification name := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path)) m.specs[name] = &spec return nil } // GetSpec returns an OpenRPC specification by name func (m *ORPCManager) GetSpec(name string) *models.OpenRPCSpec { return m.specs[name] } // ListSpecs returns a list of all loaded specification names func (m *ORPCManager) ListSpecs() []string { var names []string for name := range m.specs { names = append(names, name) } return names } // ListMethods returns a list of all method names in a specification func (m *ORPCManager) ListMethods(specName string) []string { spec := m.GetSpec(specName) if spec == nil { return []string{} } var methods []string for _, method := range spec.Methods { methods = append(methods, method.Name) } return methods } // GetMethod returns a method from a specification func (m *ORPCManager) GetMethod(specName, methodName string) *models.Method { spec := m.GetSpec(specName) if spec == nil { return nil } for _, method := range spec.Methods { if method.Name == methodName { return &method } } return nil }