// Copyright 2016 All in Bits, inc // Modifications copyright 2018 Kava Labs package lcd import ( "net/http" "os" client "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" keys "github.com/cosmos/cosmos-sdk/client/keys" rpc "github.com/cosmos/cosmos-sdk/client/rpc" tx "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/wire" auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" "github.com/gorilla/mux" "github.com/spf13/cobra" "github.com/spf13/viper" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/log" tmserver "github.com/tendermint/tendermint/rpc/lib/server" ) // ServeCommand will generate a long-running rest server // (aka Light Client Daemon) that exposes functionality similar // to the cli, but over rest func ServeCommand(cdc *wire.Codec) *cobra.Command { flagListenAddr := "laddr" flagCORS := "cors" flagMaxOpenConnections := "max-open" cmd := &cobra.Command{ Use: "rest-server", Short: "Start LCD (light-client daemon), a local REST server", RunE: func(cmd *cobra.Command, args []string) error { listenAddr := viper.GetString(flagListenAddr) handler := createHandler(cdc) logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server") maxOpen := viper.GetInt(flagMaxOpenConnections) listener, err := tmserver.StartHTTPServer( listenAddr, handler, logger, tmserver.Config{MaxOpenConnections: maxOpen}, ) if err != nil { return err } logger.Info("REST server started") // wait forever and cleanup cmn.TrapSignal(func() { err := listener.Close() logger.Error("error closing listener", "err", err) }) return nil }, } cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on") cmd.Flags().String(flagCORS, "", "Set the domains that can make CORS requests (* for all)") cmd.Flags().String(client.FlagChainID, "", "The chain ID to connect to") cmd.Flags().String(client.FlagNode, "tcp://localhost:17127", "Address of the node to connect to") cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections") return cmd } func createHandler(cdc *wire.Codec) http.Handler { r := mux.NewRouter() kb, err := keys.GetKeyBase() //XXX if err != nil { panic(err) } cliCtx := context.NewCLIContext().WithCodec(cdc).WithLogger(os.Stdout) r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET") r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET") r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(cliCtx, cdc)).Methods("POST") keys.RegisterRoutes(r) rpc.RegisterRoutes(cliCtx, r) tx.RegisterRoutes(cliCtx, r, cdc) auth.RegisterRoutes(cliCtx, r, cdc, "acc") bank.RegisterRoutes(cliCtx, r, cdc, kb) stake.RegisterRoutes(cliCtx, r, cdc, kb) slashing.RegisterRoutes(cliCtx, r, cdc, kb) return r }