From 4ed565020d986a878aa0db0eee72ac579ae7a3b0 Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 25 Dec 2024 20:56:36 +0100 Subject: [PATCH 01/28] Create handler.go --- server/v2/api/swagger/handler.go | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 server/v2/api/swagger/handler.go diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go new file mode 100644 index 000000000000..91dcd8f79d12 --- /dev/null +++ b/server/v2/api/swagger/handler.go @@ -0,0 +1,46 @@ +package swagger + +import ( + "net/http" + "path" + "path/filepath" + "strings" + + "github.com/rakyll/statik/fs" +) + +// Handler returns an HTTP handler that serves the Swagger UI files +func Handler(statikFS http.FileSystem) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + // If the path is empty or "/", show index.html + if r.URL.Path == "/" || r.URL.Path == "" { + r.URL.Path = "/index.html" + } + + // Clearing the path + urlPath := path.Clean(r.URL.Path) + + // Opening the file from statikFS + f, err := statikFS.Open(urlPath) + if err != nil { + w.WriteHeader(http.StatusNotFound) + return + } + defer f.Close() + + // Determining the content-type + ext := strings.ToLower(filepath.Ext(urlPath)) + switch ext { + case ".html": + w.Header().Set("Content-Type", "text/html") + case ".css": + w.Header().Set("Content-Type", "text/css") + case ".js": + w.Header().Set("Content-Type", "application/javascript") + case ".json": + w.Header().Set("Content-Type", "application/json") + } + + http.ServeContent(w, r, urlPath, time.Time{}, f) + } +} From 2ac25553adc875084d76b5f28c985bde3cd0d1cd Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 25 Dec 2024 20:59:43 +0100 Subject: [PATCH 02/28] feat(server): add swagger UI configuration --- server/v2/api/swagger/config.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 server/v2/api/swagger/config.go diff --git a/server/v2/api/swagger/config.go b/server/v2/api/swagger/config.go new file mode 100644 index 000000000000..3b1d6fe97beb --- /dev/null +++ b/server/v2/api/swagger/config.go @@ -0,0 +1,27 @@ +package swagger + +import "github.com/cosmos/cosmos-sdk/server/v2/config" + +// Config represents Swagger configuration options +type Config struct { + // Enable enables the Swagger UI endpoint + Enable bool `mapstructure:"enable"` + // Path is the URL path where Swagger UI will be served + Path string `mapstructure:"path"` +} + +// DefaultConfig returns default configuration for Swagger +func DefaultConfig() Config { + return Config{ + Enable: false, + Path: "/swagger", + } +} + +// Validate validates the configuration +func (c Config) Validate() error { + if c.Path == "" { + return fmt.Errorf("swagger path cannot be empty") + } + return nil +} From 8930230caad5c29b127368004aa4858a237f0560 Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 25 Dec 2024 21:00:44 +0100 Subject: [PATCH 03/28] feat(server): integrate swagger UI setup --- server/v2/server.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/server/v2/server.go b/server/v2/server.go index 9f4f3ee66e58..e2eb97bca79b 100644 --- a/server/v2/server.go +++ b/server/v2/server.go @@ -8,12 +8,14 @@ import ( "path/filepath" "strings" + "github.com/cosmos/cosmos-sdk/server/v2/api/swagger" "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" "github.com/spf13/pflag" "cosmossdk.io/core/transaction" "cosmossdk.io/log" + "github.com/rakyll/statik/fs" ) // ServerComponent is a server component that can be started and stopped. @@ -73,6 +75,7 @@ var _ ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) type Server[T transaction.Tx] struct { components []ServerComponent[T] config ServerConfig + router *http.ServeMux } func NewServer[T transaction.Tx]( @@ -82,6 +85,7 @@ func NewServer[T transaction.Tx]( return &Server[T]{ config: config, components: components, + router: http.NewServeMux(), } } @@ -242,3 +246,18 @@ func (s *Server[T]) StartFlags() []*pflag.FlagSet { return flags } + +func (s *Server[T]) setupSwagger() error { + cfg := s.config.API.Swagger + if !cfg.Enable { + return nil + } + + statikFS, err := fs.New() + if err != nil { + return err + } + + s.router.PathPrefix(cfg.Path).Handler(swagger.Handler(statikFS)) + return nil +} From c812722b9447a765e3e09fbfff2d5f6b5303422d Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:30:39 +0100 Subject: [PATCH 04/28] Create server.go --- server/v2/api/swagger/server.go | 75 +++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 server/v2/api/swagger/server.go diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go new file mode 100644 index 000000000000..5cd0d2ecd1f8 --- /dev/null +++ b/server/v2/api/swagger/server.go @@ -0,0 +1,75 @@ +package swagger + +import ( + "context" + "fmt" + "net/http" + + "cosmossdk.io/core/server" + "cosmossdk.io/core/transaction" + "cosmossdk.io/log" + serverv2 "cosmossdk.io/server/v2" +) + +type Server[T transaction.Tx] struct { + logger log.Logger + config *Config + cfgOptions []CfgOption + server *http.Server +} + +func New[T transaction.Tx]( + logger log.Logger, + cfg server.ConfigMap, + cfgOptions ...CfgOption, +) (*Server[T], error) { + srv := &Server[T]{ + logger: logger.With(log.ModuleKey, ServerName), + cfgOptions: cfgOptions, + } + + serverCfg := srv.Config().(*Config) + if len(cfg) > 0 { + if err := serverv2.UnmarshalSubConfig(cfg, srv.Name(), &serverCfg); err != nil { + return nil, fmt.Errorf("failed to unmarshal config: %w", err) + } + } + srv.config = serverCfg + + mux := http.NewServeMux() + mux.Handle(srv.config.Path, NewSwaggerHandler()) + + srv.server = &http.Server{ + Addr: srv.config.Address, + Handler: mux, + } + + return srv, nil +} + +func (s *Server[T]) Name() string { + return ServerName +} + +func (s *Server[T]) Start(ctx context.Context) error { + if !s.config.Enable { + s.logger.Info("swagger server is disabled via config") + return nil + } + + s.logger.Info("starting swagger server...", "address", s.config.Address) + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + return fmt.Errorf("failed to start swagger server: %w", err) + } + + return nil +} + +func (s *Server[T]) Stop(ctx context.Context) error { + if !s.config.Enable { + return nil + } + + s.logger.Info("stopping swagger server...", "address", s.config.Address) + return s.server.Shutdown(ctx) +} From d0c20bc255f33da27a7aae3187f8fd6ae68d274a Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:32:55 +0100 Subject: [PATCH 05/28] Update config.go --- server/v2/api/swagger/config.go | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/server/v2/api/swagger/config.go b/server/v2/api/swagger/config.go index 3b1d6fe97beb..9f0f81bc4556 100644 --- a/server/v2/api/swagger/config.go +++ b/server/v2/api/swagger/config.go @@ -1,27 +1,23 @@ package swagger -import "github.com/cosmos/cosmos-sdk/server/v2/config" +import ( + "cosmossdk.io/core/server" +) + +const ServerName = "swagger" -// Config represents Swagger configuration options type Config struct { - // Enable enables the Swagger UI endpoint - Enable bool `mapstructure:"enable"` - // Path is the URL path where Swagger UI will be served - Path string `mapstructure:"path"` + Enable bool `toml:"enable" mapstructure:"enable"` + Address string `toml:"address" mapstructure:"address"` + Path string `toml:"path" mapstructure:"path"` } -// DefaultConfig returns default configuration for Swagger -func DefaultConfig() Config { - return Config{ - Enable: false, - Path: "/swagger", +func DefaultConfig() *Config { + return &Config{ + Enable: true, + Address: "localhost:8080", + Path: "/swagger/", } } -// Validate validates the configuration -func (c Config) Validate() error { - if c.Path == "" { - return fmt.Errorf("swagger path cannot be empty") - } - return nil -} +type CfgOption func(*Config) From ac5982aef33f692f9f19c7c65d976b1eb1ae090e Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:39:41 +0100 Subject: [PATCH 06/28] Update config.go --- server/v2/api/swagger/config.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/server/v2/api/swagger/config.go b/server/v2/api/swagger/config.go index 9f0f81bc4556..e9ebba253e7c 100644 --- a/server/v2/api/swagger/config.go +++ b/server/v2/api/swagger/config.go @@ -1,17 +1,21 @@ package swagger import ( + "fmt" + "cosmossdk.io/core/server" ) const ServerName = "swagger" +// Config defines the configuration for the Swagger UI server type Config struct { Enable bool `toml:"enable" mapstructure:"enable"` Address string `toml:"address" mapstructure:"address"` Path string `toml:"path" mapstructure:"path"` } +// DefaultConfig returns the default configuration func DefaultConfig() *Config { return &Config{ Enable: true, @@ -20,4 +24,13 @@ func DefaultConfig() *Config { } } +// Validate checks the configuration +func (c Config) Validate() error { + if c.Path == "" { + return fmt.Errorf("swagger path cannot be empty") + } + return nil +} + +// CfgOption defines a function for configuring the settings type CfgOption func(*Config) From f96dafeb23ccaec5be9d59a7fb91fdb6304870db Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:41:24 +0100 Subject: [PATCH 07/28] Update handler.go --- server/v2/api/swagger/handler.go | 109 +++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 35 deletions(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index 91dcd8f79d12..a81ab5d5b736 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -1,46 +1,85 @@ package swagger import ( + "io" "net/http" - "path" "path/filepath" "strings" + "time" "github.com/rakyll/statik/fs" ) -// Handler returns an HTTP handler that serves the Swagger UI files -func Handler(statikFS http.FileSystem) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - // If the path is empty or "/", show index.html - if r.URL.Path == "/" || r.URL.Path == "" { - r.URL.Path = "/index.html" - } - - // Clearing the path - urlPath := path.Clean(r.URL.Path) - - // Opening the file from statikFS - f, err := statikFS.Open(urlPath) - if err != nil { - w.WriteHeader(http.StatusNotFound) - return - } - defer f.Close() - - // Determining the content-type - ext := strings.ToLower(filepath.Ext(urlPath)) - switch ext { - case ".html": - w.Header().Set("Content-Type", "text/html") - case ".css": - w.Header().Set("Content-Type", "text/css") - case ".js": - w.Header().Set("Content-Type", "application/javascript") - case ".json": - w.Header().Set("Content-Type", "application/json") - } - - http.ServeContent(w, r, urlPath, time.Time{}, f) +// Handler returns an HTTP handler for Swagger UI +func Handler() http.Handler { + return &swaggerHandler{} +} + +type swaggerHandler struct{} + +func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Set CORS headers + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type") + + if r.Method == http.MethodOptions { + return + } + + // Get the static file system + statikFS, err := fs.New() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Process the path + urlPath := strings.TrimPrefix(r.URL.Path, "/swagger") + if urlPath == "" || urlPath == "/" { + urlPath = "/index.html" + } + + // Open the file + file, err := statikFS.Open(urlPath) + if err != nil { + http.Error(w, "File not found", http.StatusNotFound) + return + } + defer file.Close() + + // Set the content-type + ext := filepath.Ext(urlPath) + if ct := getContentType(ext); ct != "" { + w.Header().Set("Content-Type", ct) + } + + // Set caching headers + w.Header().Set("Cache-Control", "public, max-age=31536000") + w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat)) + + // Serve the file + http.ServeContent(w, r, urlPath, time.Now(), file.(io.ReadSeeker)) +} + +// getContentType returns the content-type for a file extension +func getContentType(ext string) string { + switch strings.ToLower(ext) { + case ".html": + return "text/html" + case ".css": + return "text/css" + case ".js": + return "application/javascript" + case ".json": + return "application/json" + case ".png": + return "image/png" + case ".jpg", ".jpeg": + return "image/jpeg" + case ".svg": + return "image/svg+xml" + default: + return "" } -} +} From 9859c389ba0056f70a2ce644d802871110cb702d Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:42:32 +0100 Subject: [PATCH 08/28] Update server.go --- server/v2/api/swagger/server.go | 37 +++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index 5cd0d2ecd1f8..d81ad24d1f0f 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -11,6 +11,12 @@ import ( serverv2 "cosmossdk.io/server/v2" ) +var ( + _ serverv2.ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) + _ serverv2.HasConfig = (*Server[transaction.Tx])(nil) +) + +// Server represents a Swagger UI server type Server[T transaction.Tx] struct { logger log.Logger config *Config @@ -18,6 +24,7 @@ type Server[T transaction.Tx] struct { server *http.Server } +// New creates a new Swagger UI server func New[T transaction.Tx]( logger log.Logger, cfg server.ConfigMap, @@ -36,8 +43,12 @@ func New[T transaction.Tx]( } srv.config = serverCfg + if err := srv.config.Validate(); err != nil { + return nil, err + } + mux := http.NewServeMux() - mux.Handle(srv.config.Path, NewSwaggerHandler()) + mux.Handle(srv.config.Path, Handler()) srv.server = &http.Server{ Addr: srv.config.Address, @@ -47,13 +58,34 @@ func New[T transaction.Tx]( return srv, nil } +// NewWithConfigOptions creates a new server with configuration options +func NewWithConfigOptions[T transaction.Tx](opts ...CfgOption) *Server[T] { + return &Server[T]{ + cfgOptions: opts, + } +} + +// Name returns the server's name func (s *Server[T]) Name() string { return ServerName } +// Config returns the server configuration +func (s *Server[T]) Config() any { + if s.config == nil || s.config.Address == "" { + cfg := DefaultConfig() + for _, opt := range s.cfgOptions { + opt(cfg) + } + return cfg + } + return s.config +} + +// Start starts the server func (s *Server[T]) Start(ctx context.Context) error { if !s.config.Enable { - s.logger.Info("swagger server is disabled via config") + s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) return nil } @@ -65,6 +97,7 @@ func (s *Server[T]) Start(ctx context.Context) error { return nil } +// Stop stops the server func (s *Server[T]) Stop(ctx context.Context) error { if !s.config.Enable { return nil From e96e5bb2c0bfcd52ebd10cb8087b561eff735336 Mon Sep 17 00:00:00 2001 From: crStiv Date: Thu, 26 Dec 2024 01:44:32 +0100 Subject: [PATCH 09/28] return original code --- server/v2/server.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/server/v2/server.go b/server/v2/server.go index e2eb97bca79b..9f4f3ee66e58 100644 --- a/server/v2/server.go +++ b/server/v2/server.go @@ -8,14 +8,12 @@ import ( "path/filepath" "strings" - "github.com/cosmos/cosmos-sdk/server/v2/api/swagger" "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" "github.com/spf13/pflag" "cosmossdk.io/core/transaction" "cosmossdk.io/log" - "github.com/rakyll/statik/fs" ) // ServerComponent is a server component that can be started and stopped. @@ -75,7 +73,6 @@ var _ ServerComponent[transaction.Tx] = (*Server[transaction.Tx])(nil) type Server[T transaction.Tx] struct { components []ServerComponent[T] config ServerConfig - router *http.ServeMux } func NewServer[T transaction.Tx]( @@ -85,7 +82,6 @@ func NewServer[T transaction.Tx]( return &Server[T]{ config: config, components: components, - router: http.NewServeMux(), } } @@ -246,18 +242,3 @@ func (s *Server[T]) StartFlags() []*pflag.FlagSet { return flags } - -func (s *Server[T]) setupSwagger() error { - cfg := s.config.API.Swagger - if !cfg.Enable { - return nil - } - - statikFS, err := fs.New() - if err != nil { - return err - } - - s.router.PathPrefix(cfg.Path).Handler(swagger.Handler(statikFS)) - return nil -} From e733362bfbfeda29733924b73fe8c1b45c22349f Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 16:13:15 +0100 Subject: [PATCH 10/28] Update handler.go --- server/v2/api/swagger/handler.go | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index a81ab5d5b736..86c106a0f512 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -10,13 +10,10 @@ import ( "github.com/rakyll/statik/fs" ) -// Handler returns an HTTP handler for Swagger UI -func Handler() http.Handler { - return &swaggerHandler{} +type swaggerHandler struct { + swaggerFS http.FileSystem } -type swaggerHandler struct{} - func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Set CORS headers w.Header().Set("Access-Control-Allow-Origin", "*") @@ -27,13 +24,6 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - // Get the static file system - statikFS, err := fs.New() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - // Process the path urlPath := strings.TrimPrefix(r.URL.Path, "/swagger") if urlPath == "" || urlPath == "/" { @@ -41,7 +31,7 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } // Open the file - file, err := statikFS.Open(urlPath) + file, err := h.swaggerFS.Open(urlPath) if err != nil { http.Error(w, "File not found", http.StatusNotFound) return From 34eab36bc685ff3917b13ddb4fac5a7b1835c3f2 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 16:13:40 +0100 Subject: [PATCH 11/28] Update server.go --- server/v2/api/swagger/server.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index d81ad24d1f0f..3bc9f68b6d1a 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -48,7 +48,9 @@ func New[T transaction.Tx]( } mux := http.NewServeMux() - mux.Handle(srv.config.Path, Handler()) + mux.Handle(srv.config.Path, &swaggerHandler{ + swaggerFS: srv.config.SwaggerUI, + }) srv.server = &http.Server{ Addr: srv.config.Address, From eec89d7b7cf4abdc9bf44bd8c35ac7335f9af557 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 16:13:53 +0100 Subject: [PATCH 12/28] Update config.go --- server/v2/api/swagger/config.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/server/v2/api/swagger/config.go b/server/v2/api/swagger/config.go index e9ebba253e7c..3b357867427b 100644 --- a/server/v2/api/swagger/config.go +++ b/server/v2/api/swagger/config.go @@ -2,6 +2,7 @@ package swagger import ( "fmt" + "net/http" "cosmossdk.io/core/server" ) @@ -10,9 +11,10 @@ const ServerName = "swagger" // Config defines the configuration for the Swagger UI server type Config struct { - Enable bool `toml:"enable" mapstructure:"enable"` - Address string `toml:"address" mapstructure:"address"` - Path string `toml:"path" mapstructure:"path"` + Enable bool `toml:"enable" mapstructure:"enable"` + Address string `toml:"address" mapstructure:"address"` + Path string `toml:"path" mapstructure:"path"` + SwaggerUI http.FileSystem `toml:"-" mapstructure:"-"` } // DefaultConfig returns the default configuration @@ -29,6 +31,9 @@ func (c Config) Validate() error { if c.Path == "" { return fmt.Errorf("swagger path cannot be empty") } + if c.Enable && c.SwaggerUI == nil { + return fmt.Errorf("swagger UI file system must be provided when enabled") + } return nil } From 654cc99afa5ba35e59fc554237ae628a6dba7382 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 16:15:39 +0100 Subject: [PATCH 13/28] Update app.go --- simapp/v2/app.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/simapp/v2/app.go b/simapp/v2/app.go index 601d641ad060..0eaa5682e84d 100644 --- a/simapp/v2/app.go +++ b/simapp/v2/app.go @@ -28,6 +28,8 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/std" _ "github.com/cosmos/cosmos-sdk/x/genutil" + "cosmossdk.io/client/docs" + swaggerv2 "cosmossdk.io/server/v2/api/swagger" ) // SimApp extends an ABCI application, but with most of its parameters exported. @@ -184,6 +186,33 @@ func NewSimApp[T transaction.Tx]( if err = app.LoadLatest(); err != nil { return nil, err } + + // Creating and Adding a Swagger Server + swaggerLogger := logger.With(log.ModuleKey, "swagger") + swaggerCfg := server.ConfigMap{ + "swagger": map[string]any{ + "enable": true, + "address": "localhost:8080", + "path": "/swagger/", + }, + } + + swaggerServer, err := swaggerv2.New[T]( + swaggerLogger, + swaggerCfg, + swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { + cfg.SwaggerUI = docs.SwaggerUI + }), + ) + if err != nil { + return nil, fmt.Errorf("failed to create swagger server: %w", err) + } + + // Adding a Swagger server to the application + if err := app.App.AddServer(swaggerServer); err != nil { + return nil, fmt.Errorf("failed to add swagger server: %w", err) + } + return app, nil } From c9d6544b0aa6b56380beba6849670c30d213ae5d Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 16:32:21 +0100 Subject: [PATCH 14/28] Create doc.go --- server/v2/api/swagger/doc.go | 47 ++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 server/v2/api/swagger/doc.go diff --git a/server/v2/api/swagger/doc.go b/server/v2/api/swagger/doc.go new file mode 100644 index 000000000000..929c582da32b --- /dev/null +++ b/server/v2/api/swagger/doc.go @@ -0,0 +1,47 @@ +/* +Package swagger provides Swagger UI support for server/v2. + +Example usage: + + import ( + "cosmossdk.io/client/docs" + "cosmossdk.io/core/server" + "cosmossdk.io/log" + swaggerv2 "cosmossdk.io/server/v2/api/swagger" + ) + + // Create a logger + logger := log.NewLogger() + + // Configure Swagger server + swaggerCfg := server.ConfigMap{ + "swagger": map[string]any{ + "enable": true, + "address": "localhost:8080", + "path": "/swagger/", + }, + } + + // Create new Swagger server with the default SDK Swagger UI + swaggerServer, err := swaggerv2.New[YourTxType]( + logger.With(log.ModuleKey, "swagger"), + swaggerCfg, + swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { + cfg.SwaggerUI = docs.SwaggerUI // Use the default SDK Swagger UI + }), + ) + if err != nil { + // Handle error + } + + // Add Swagger server to your application + app.AddServer(swaggerServer) + +The server will serve Swagger UI documentation at the configured path (default: /swagger/). +Users can customize the configuration through the following options: + - enable: Enable/disable the Swagger server + - address: The address to listen on (default: localhost:8080) + - path: The path to serve Swagger UI at (default: /swagger/) + - SwaggerUI: The http.FileSystem containing Swagger UI files +*/ +package swagger From 16556c1db53e0ccf33aa249a1ab50b1637064651 Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 19:09:51 +0100 Subject: [PATCH 15/28] Update commands.go --- simapp/v2/simdv2/cmd/commands.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/simapp/v2/simdv2/cmd/commands.go b/simapp/v2/simdv2/cmd/commands.go index 2a7634ffea98..ed89f5fb5240 100644 --- a/simapp/v2/simdv2/cmd/commands.go +++ b/simapp/v2/simdv2/cmd/commands.go @@ -38,6 +38,8 @@ import ( genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" v2 "github.com/cosmos/cosmos-sdk/x/genutil/v2/cli" + "cosmossdk.io/client/docs" + swaggerv2 "cosmossdk.io/server/v2/api/swagger" ) // CommandDependencies is a struct that contains all the dependencies needed to initialize the root command. @@ -92,6 +94,7 @@ func InitRootCmd[T transaction.Tx]( &telemetry.Server[T]{}, &rest.Server[T]{}, &grpcgateway.Server[T]{}, + &swaggerv2.Server[T]{}, ) } @@ -163,6 +166,18 @@ func InitRootCmd[T transaction.Tx]( } registerGRPCGatewayRoutes[T](deps, grpcgatewayServer) + // Create Swagger server + swaggerServer, err := swaggerv2.New[T]( + logger.With(log.ModuleKey, "swagger"), + deps.GlobalConfig, + swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { + cfg.SwaggerUI = docs.SwaggerUI + }), + ) + if err != nil { + return nil, err + } + // wire server commands return serverv2.AddCommands[T]( rootCmd, @@ -176,6 +191,7 @@ func InitRootCmd[T transaction.Tx]( telemetryServer, restServer, grpcgatewayServer, + swaggerServer, ) } From 2021911a50eb49e9a289ced74012a0dd09fe2ebb Mon Sep 17 00:00:00 2001 From: crStiv Date: Mon, 6 Jan 2025 19:11:08 +0100 Subject: [PATCH 16/28] Update app.go --- simapp/v2/app.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/simapp/v2/app.go b/simapp/v2/app.go index 0eaa5682e84d..1c7755aef4a5 100644 --- a/simapp/v2/app.go +++ b/simapp/v2/app.go @@ -28,8 +28,6 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/std" _ "github.com/cosmos/cosmos-sdk/x/genutil" - "cosmossdk.io/client/docs" - swaggerv2 "cosmossdk.io/server/v2/api/swagger" ) // SimApp extends an ABCI application, but with most of its parameters exported. @@ -187,32 +185,6 @@ func NewSimApp[T transaction.Tx]( return nil, err } - // Creating and Adding a Swagger Server - swaggerLogger := logger.With(log.ModuleKey, "swagger") - swaggerCfg := server.ConfigMap{ - "swagger": map[string]any{ - "enable": true, - "address": "localhost:8080", - "path": "/swagger/", - }, - } - - swaggerServer, err := swaggerv2.New[T]( - swaggerLogger, - swaggerCfg, - swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { - cfg.SwaggerUI = docs.SwaggerUI - }), - ) - if err != nil { - return nil, fmt.Errorf("failed to create swagger server: %w", err) - } - - // Adding a Swagger server to the application - if err := app.App.AddServer(swaggerServer); err != nil { - return nil, fmt.Errorf("failed to add swagger server: %w", err) - } - return app, nil } From 93dc4b6a3f2d9152e59302564f21cabd41f112a9 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 00:50:58 +0100 Subject: [PATCH 17/28] Update handler.go --- server/v2/api/swagger/handler.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index 86c106a0f512..67b99f1b7c6e 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -6,8 +6,6 @@ import ( "path/filepath" "strings" "time" - - "github.com/rakyll/statik/fs" ) type swaggerHandler struct { @@ -15,10 +13,9 @@ type swaggerHandler struct { } func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - // Set CORS headers + // Set minimal CORS headers w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS") - w.Header().Set("Access-Control-Allow-Headers", "DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type") + w.Header().Set("Access-Control-Allow-Methods", "GET") if r.Method == http.MethodOptions { return From 446c0f8c85a28b3e701290b08a1777d2ee6c9424 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 01:00:14 +0100 Subject: [PATCH 18/28] Update handler.go --- server/v2/api/swagger/handler.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index 67b99f1b7c6e..492e4417312c 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -21,12 +21,21 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - // Process the path + // Process and validate the path urlPath := strings.TrimPrefix(r.URL.Path, "/swagger") if urlPath == "" || urlPath == "/" { urlPath = "/index.html" } + // Basic path validation + if strings.Contains(urlPath, "..") || strings.Contains(urlPath, "//") { + http.Error(w, "Invalid path", http.StatusBadRequest) + return + } + + // Clean the path + urlPath = filepath.Clean(urlPath) + // Open the file file, err := h.swaggerFS.Open(urlPath) if err != nil { From c038d6cb533045fe1aa6e295622a05d8849c4f1f Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 01:00:44 +0100 Subject: [PATCH 19/28] Update doc.go --- server/v2/api/swagger/doc.go | 49 +++++++++++------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) diff --git a/server/v2/api/swagger/doc.go b/server/v2/api/swagger/doc.go index 929c582da32b..d30b300a9ebc 100644 --- a/server/v2/api/swagger/doc.go +++ b/server/v2/api/swagger/doc.go @@ -1,47 +1,26 @@ /* Package swagger provides Swagger UI support for server/v2. -Example usage: +Example usage in commands.go: - import ( - "cosmossdk.io/client/docs" - "cosmossdk.io/core/server" - "cosmossdk.io/log" - swaggerv2 "cosmossdk.io/server/v2/api/swagger" - ) - - // Create a logger - logger := log.NewLogger() - - // Configure Swagger server - swaggerCfg := server.ConfigMap{ - "swagger": map[string]any{ - "enable": true, - "address": "localhost:8080", - "path": "/swagger/", - }, - } - - // Create new Swagger server with the default SDK Swagger UI - swaggerServer, err := swaggerv2.New[YourTxType]( + // Create Swagger server + swaggerServer, err := swaggerv2.New[T]( logger.With(log.ModuleKey, "swagger"), - swaggerCfg, + deps.GlobalConfig, swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { - cfg.SwaggerUI = docs.SwaggerUI // Use the default SDK Swagger UI + cfg.SwaggerUI = docs.SwaggerUI }), ) - if err != nil { - // Handle error - } - // Add Swagger server to your application - app.AddServer(swaggerServer) + // Add server to your application + return serverv2.AddCommands[T]( + // ...other servers..., + swaggerServer, + ) -The server will serve Swagger UI documentation at the configured path (default: /swagger/). -Users can customize the configuration through the following options: - - enable: Enable/disable the Swagger server - - address: The address to listen on (default: localhost:8080) - - path: The path to serve Swagger UI at (default: /swagger/) - - SwaggerUI: The http.FileSystem containing Swagger UI files +Configuration options: + - enable: Enable/disable the Swagger server (default: true) + - address: Server address (default: localhost:8080) + - path: UI endpoint path (default: /swagger/) */ package swagger From 0938d61cdadb183775ade1fa8b71678b4b52dac5 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 03:02:40 +0100 Subject: [PATCH 20/28] Update config.go --- server/v2/api/swagger/config.go | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/server/v2/api/swagger/config.go b/server/v2/api/swagger/config.go index 3b357867427b..b5efb1f42215 100644 --- a/server/v2/api/swagger/config.go +++ b/server/v2/api/swagger/config.go @@ -11,9 +11,11 @@ const ServerName = "swagger" // Config defines the configuration for the Swagger UI server type Config struct { - Enable bool `toml:"enable" mapstructure:"enable"` - Address string `toml:"address" mapstructure:"address"` - Path string `toml:"path" mapstructure:"path"` + // Enable enables/disables the Swagger UI server + Enable bool `toml:"enable,omitempty" mapstructure:"enable"` + // Address defines the server address to bind to + Address string `toml:"address,omitempty" mapstructure:"address"` + // SwaggerUI defines the file system for serving Swagger UI files SwaggerUI http.FileSystem `toml:"-" mapstructure:"-"` } @@ -21,19 +23,20 @@ type Config struct { func DefaultConfig() *Config { return &Config{ Enable: true, - Address: "localhost:8080", - Path: "/swagger/", + Address: "localhost:8090", } } -// Validate checks the configuration -func (c Config) Validate() error { - if c.Path == "" { - return fmt.Errorf("swagger path cannot be empty") +// Validate returns an error if the config is invalid +func (c *Config) Validate() error { + if !c.Enable { + return nil } - if c.Enable && c.SwaggerUI == nil { - return fmt.Errorf("swagger UI file system must be provided when enabled") + + if c.Address == "" { + return fmt.Errorf("address is required when swagger UI is enabled") } + return nil } From 2466ab5e301f8dcc651ee1f55a24e8673c8fc697 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 03:23:10 +0100 Subject: [PATCH 21/28] Update handler.go --- server/v2/api/swagger/handler.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index 492e4417312c..59f8851942ab 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -50,10 +50,6 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", ct) } - // Set caching headers - w.Header().Set("Cache-Control", "public, max-age=31536000") - w.Header().Set("Last-Modified", time.Now().UTC().Format(http.TimeFormat)) - // Serve the file http.ServeContent(w, r, urlPath, time.Now(), file.(io.ReadSeeker)) } From 8a042b259dd4c215703a45d7ac6a48ec7c152258 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 03:23:42 +0100 Subject: [PATCH 22/28] Update commands.go --- simapp/v2/simdv2/cmd/commands.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/simapp/v2/simdv2/cmd/commands.go b/simapp/v2/simdv2/cmd/commands.go index ed89f5fb5240..077ce21db2ea 100644 --- a/simapp/v2/simdv2/cmd/commands.go +++ b/simapp/v2/simdv2/cmd/commands.go @@ -15,6 +15,7 @@ import ( grpcserver "cosmossdk.io/server/v2/api/grpc" "cosmossdk.io/server/v2/api/grpcgateway" "cosmossdk.io/server/v2/api/rest" + swaggerv2 "cosmossdk.io/server/v2/api/swagger" "cosmossdk.io/server/v2/api/telemetry" "cosmossdk.io/server/v2/cometbft" serverstore "cosmossdk.io/server/v2/store" @@ -38,8 +39,6 @@ import ( genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" v2 "github.com/cosmos/cosmos-sdk/x/genutil/v2/cli" - "cosmossdk.io/client/docs" - swaggerv2 "cosmossdk.io/server/v2/api/swagger" ) // CommandDependencies is a struct that contains all the dependencies needed to initialize the root command. @@ -170,9 +169,6 @@ func InitRootCmd[T transaction.Tx]( swaggerServer, err := swaggerv2.New[T]( logger.With(log.ModuleKey, "swagger"), deps.GlobalConfig, - swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { - cfg.SwaggerUI = docs.SwaggerUI - }), ) if err != nil { return nil, err From 8ccb884141b5e405e20f564ce634149d3b2851d7 Mon Sep 17 00:00:00 2001 From: crStiv Date: Tue, 7 Jan 2025 03:26:08 +0100 Subject: [PATCH 23/28] Update doc.go --- server/v2/api/swagger/doc.go | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/server/v2/api/swagger/doc.go b/server/v2/api/swagger/doc.go index d30b300a9ebc..6c3ab9424b5f 100644 --- a/server/v2/api/swagger/doc.go +++ b/server/v2/api/swagger/doc.go @@ -7,20 +7,10 @@ Example usage in commands.go: swaggerServer, err := swaggerv2.New[T]( logger.With(log.ModuleKey, "swagger"), deps.GlobalConfig, - swaggerv2.CfgOption(func(cfg *swaggerv2.Config) { - cfg.SwaggerUI = docs.SwaggerUI - }), - ) - - // Add server to your application - return serverv2.AddCommands[T]( - // ...other servers..., - swaggerServer, ) Configuration options: - - enable: Enable/disable the Swagger server (default: true) - - address: Server address (default: localhost:8080) - - path: UI endpoint path (default: /swagger/) + - enable: Enable/disable the Swagger UI server (default: true) + - address: Server address (default: localhost:8090) */ package swagger From 9659ba78ba65ccca2c953ed59a0f39cc9d7a710f Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 8 Jan 2025 00:14:43 +0100 Subject: [PATCH 24/28] Update server.go --- server/v2/api/swagger/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index 3bc9f68b6d1a..634a6bb036ca 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -48,7 +48,7 @@ func New[T transaction.Tx]( } mux := http.NewServeMux() - mux.Handle(srv.config.Path, &swaggerHandler{ + mux.Handle("/swagger", &swaggerHandler{ swaggerFS: srv.config.SwaggerUI, }) From 0fa0b6b4bae31570536187a548a93ac898e78b31 Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 8 Jan 2025 01:07:49 +0100 Subject: [PATCH 25/28] Update server.go --- server/v2/api/swagger/server.go | 53 ++------------------------------- 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index 634a6bb036ca..5feb36a254c2 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -48,7 +48,7 @@ func New[T transaction.Tx]( } mux := http.NewServeMux() - mux.Handle("/swagger", &swaggerHandler{ + mux.Handle("/swagger/", &swaggerHandler{ swaggerFS: srv.config.SwaggerUI, }) @@ -58,53 +58,4 @@ func New[T transaction.Tx]( } return srv, nil -} - -// NewWithConfigOptions creates a new server with configuration options -func NewWithConfigOptions[T transaction.Tx](opts ...CfgOption) *Server[T] { - return &Server[T]{ - cfgOptions: opts, - } -} - -// Name returns the server's name -func (s *Server[T]) Name() string { - return ServerName -} - -// Config returns the server configuration -func (s *Server[T]) Config() any { - if s.config == nil || s.config.Address == "" { - cfg := DefaultConfig() - for _, opt := range s.cfgOptions { - opt(cfg) - } - return cfg - } - return s.config -} - -// Start starts the server -func (s *Server[T]) Start(ctx context.Context) error { - if !s.config.Enable { - s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) - return nil - } - - s.logger.Info("starting swagger server...", "address", s.config.Address) - if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { - return fmt.Errorf("failed to start swagger server: %w", err) - } - - return nil -} - -// Stop stops the server -func (s *Server[T]) Stop(ctx context.Context) error { - if !s.config.Enable { - return nil - } - - s.logger.Info("stopping swagger server...", "address", s.config.Address) - return s.server.Shutdown(ctx) -} +} From 35f2fad2c0334502202de46ec9dc97025ca13848 Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 8 Jan 2025 02:52:53 +0100 Subject: [PATCH 26/28] Update handler.go --- server/v2/api/swagger/handler.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/server/v2/api/swagger/handler.go b/server/v2/api/swagger/handler.go index 59f8851942ab..089c2c8f5f7d 100644 --- a/server/v2/api/swagger/handler.go +++ b/server/v2/api/swagger/handler.go @@ -17,6 +17,11 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Methods", "GET") + // Add security headers + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("X-Frame-Options", "DENY") + w.Header().Set("Content-Security-Policy", "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'") + if r.Method == http.MethodOptions { return } @@ -27,15 +32,15 @@ func (h *swaggerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { urlPath = "/index.html" } - // Basic path validation - if strings.Contains(urlPath, "..") || strings.Contains(urlPath, "//") { + // Clean the path before validation + urlPath = filepath.Clean(urlPath) + + // Validate path before any operations + if strings.Contains(urlPath, "..") || strings.Contains(urlPath, "//") || strings.Contains(urlPath, "\\") { http.Error(w, "Invalid path", http.StatusBadRequest) return } - // Clean the path - urlPath = filepath.Clean(urlPath) - // Open the file file, err := h.swaggerFS.Open(urlPath) if err != nil { From 44da58f79564664bb66f71c02303b6a08f587db9 Mon Sep 17 00:00:00 2001 From: crStiv Date: Wed, 8 Jan 2025 02:55:11 +0100 Subject: [PATCH 27/28] Update server.go --- server/v2/api/swagger/server.go | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index 5feb36a254c2..19196e84a1a2 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -35,12 +35,15 @@ func New[T transaction.Tx]( cfgOptions: cfgOptions, } - serverCfg := srv.Config().(*Config) + serverCfg := DefaultConfig() if len(cfg) > 0 { - if err := serverv2.UnmarshalSubConfig(cfg, srv.Name(), &serverCfg); err != nil { + if err := serverv2.UnmarshalSubConfig(cfg, ServerName, serverCfg); err != nil { return nil, fmt.Errorf("failed to unmarshal config: %w", err) } } + for _, opt := range cfgOptions { + opt(serverCfg) + } srv.config = serverCfg if err := srv.config.Validate(); err != nil { @@ -48,7 +51,7 @@ func New[T transaction.Tx]( } mux := http.NewServeMux() - mux.Handle("/swagger/", &swaggerHandler{ + mux.Handle("/swagger", &swaggerHandler{ swaggerFS: srv.config.SwaggerUI, }) @@ -58,4 +61,46 @@ func New[T transaction.Tx]( } return srv, nil +} + +// Name returns the server's name +func (s *Server[T]) Name() string { + return ServerName +} + +// Config returns the server configuration +func (s *Server[T]) Config() any { + if s.config == nil { + cfg := DefaultConfig() + for _, opt := range s.cfgOptions { + opt(cfg) + } + return cfg + } + return s.config +} + +// Start starts the server +func (s *Server[T]) Start(ctx context.Context) error { + if !s.config.Enable { + s.logger.Info(fmt.Sprintf("%s server is disabled via config", s.Name())) + return nil + } + + s.logger.Info("starting swagger server...", "address", s.config.Address) + if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + return fmt.Errorf("failed to start swagger server: %w", err) + } + + return nil +} + +// Stop stops the server +func (s *Server[T]) Stop(ctx context.Context) error { + if !s.config.Enable { + return nil + } + + s.logger.Info("stopping swagger server...", "address", s.config.Address) + return s.server.Shutdown(ctx) } From 98f2d85317d1d159207365d020c98b31cda4623e Mon Sep 17 00:00:00 2001 From: crStiv Date: Sat, 11 Jan 2025 23:10:49 +0100 Subject: [PATCH 28/28] Update server.go --- server/v2/api/swagger/server.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/v2/api/swagger/server.go b/server/v2/api/swagger/server.go index 19196e84a1a2..94cbd5fc8be2 100644 --- a/server/v2/api/swagger/server.go +++ b/server/v2/api/swagger/server.go @@ -5,7 +5,6 @@ import ( "fmt" "net/http" - "cosmossdk.io/core/server" "cosmossdk.io/core/transaction" "cosmossdk.io/log" serverv2 "cosmossdk.io/server/v2" @@ -27,7 +26,7 @@ type Server[T transaction.Tx] struct { // New creates a new Swagger UI server func New[T transaction.Tx]( logger log.Logger, - cfg server.ConfigMap, + cfg serverv2.ConfigMap, cfgOptions ...CfgOption, ) (*Server[T], error) { srv := &Server[T]{