Files
sendico/api/gateway/tron/internal/service/gateway/tronclient/registry.go
2026-02-05 16:27:43 +01:00

128 lines
3.2 KiB
Go

package tronclient
import (
"context"
"fmt"
"strings"
"time"
"github.com/tech/sendico/gateway/tron/shared"
"github.com/tech/sendico/pkg/merrors"
"github.com/tech/sendico/pkg/mlogger"
"go.uber.org/zap"
)
// Registry manages TRON gRPC clients keyed by network name.
type Registry struct {
logger mlogger.Logger
clients map[string]*Client
}
// NewRegistry creates an empty registry.
func NewRegistry(logger mlogger.Logger) *Registry {
return &Registry{
logger: logger.Named("tron_registry"),
clients: make(map[string]*Client),
}
}
// Prepare initializes TRON gRPC clients for all networks with a configured GRPCUrl.
// Networks without GRPCUrl are skipped (they will fallback to EVM).
func Prepare(ctx context.Context, logger mlogger.Logger, networks []shared.Network) (*Registry, error) {
if logger == nil {
return nil, merrors.InvalidArgument("tronclient: logger is required")
}
registry := NewRegistry(logger)
timeout := 30 * time.Second
for _, network := range networks {
name := network.Name.String()
grpcURL := strings.TrimSpace(network.GRPCUrl)
grpcToken := strings.TrimSpace(network.GRPCToken)
if !network.Name.IsValid() {
continue
}
// Skip networks without TRON gRPC URL configured
if grpcURL == "" {
registry.logger.Debug("Skipping network without TRON gRPC URL",
zap.String("network", name),
)
continue
}
registry.logger.Info("Initializing TRON gRPC client",
zap.String("network", name),
zap.String("grpc_url", grpcURL),
)
client, err := NewClient(grpcURL, timeout, grpcToken)
if err != nil {
registry.Close()
registry.logger.Error("Failed to initialize TRON gRPC client",
zap.String("network", name),
zap.Error(err),
)
return nil, merrors.Internal(fmt.Sprintf("tronclient: failed to connect to %s: %v", name, err))
}
registry.clients[name] = client
registry.logger.Info("TRON gRPC client ready",
zap.String("network", name),
)
}
if len(registry.clients) > 0 {
registry.logger.Info("TRON gRPC clients initialized",
zap.Int("count", len(registry.clients)),
)
} else {
registry.logger.Debug("No TRON gRPC clients were initialized (no networks with grpc_url_env)")
}
return registry, nil
}
// Client returns the TRON gRPC client for the given network.
func (r *Registry) Client(networkName string) (*Client, error) {
if r == nil {
return nil, merrors.Internal("tronclient: registry not initialized")
}
name := strings.ToLower(strings.TrimSpace(networkName))
client, ok := r.clients[name]
if !ok || client == nil {
return nil, merrors.InvalidArgument(fmt.Sprintf("tronclient: no client for network %s", name))
}
return client, nil
}
// HasClient checks if a TRON gRPC client is available for the given network.
func (r *Registry) HasClient(networkName string) bool {
if r == nil || len(r.clients) == 0 {
return false
}
name := strings.ToLower(strings.TrimSpace(networkName))
client, ok := r.clients[name]
return ok && client != nil
}
// Close closes all TRON gRPC connections.
func (r *Registry) Close() {
if r == nil {
return
}
for name, client := range r.clients {
if client != nil {
client.Close()
if r.logger != nil {
r.logger.Info("TRON gRPC client closed", zap.String("network", name))
}
}
}
r.clients = make(map[string]*Client)
}