diff --git a/PENDING.md b/PENDING.md index 6295d5572698..a8f278ebb469 100644 --- a/PENDING.md +++ b/PENDING.md @@ -48,6 +48,7 @@ FEATURES IMPROVEMENTS * Gaia REST API (`gaiacli advanced rest-server`) + * [\#2836](https://github.com/cosmos/cosmos-sdk/pull/2836) Expose LCD router to allow users to register routes there. * Gaia CLI (`gaiacli`) * [\#2749](https://github.com/cosmos/cosmos-sdk/pull/2749) Add --chain-id flag to gaiad testnet diff --git a/client/flags.go b/client/flags.go index 9d03939e0240..dfadab07e43f 100644 --- a/client/flags.go +++ b/client/flags.go @@ -17,25 +17,32 @@ const ( DefaultGasLimit = 200000 GasFlagSimulate = "simulate" - FlagUseLedger = "ledger" - FlagChainID = "chain-id" - FlagNode = "node" - FlagHeight = "height" - FlagGas = "gas" - FlagGasAdjustment = "gas-adjustment" - FlagTrustNode = "trust-node" - FlagFrom = "from" - FlagName = "name" - FlagAccountNumber = "account-number" - FlagSequence = "sequence" - FlagMemo = "memo" - FlagFee = "fee" - FlagAsync = "async" - FlagJson = "json" - FlagPrintResponse = "print-response" - FlagDryRun = "dry-run" - FlagGenerateOnly = "generate-only" - FlagIndentResponse = "indent" + FlagUseLedger = "ledger" + FlagChainID = "chain-id" + FlagNode = "node" + FlagHeight = "height" + FlagGas = "gas" + FlagGasAdjustment = "gas-adjustment" + FlagTrustNode = "trust-node" + FlagFrom = "from" + FlagName = "name" + FlagAccountNumber = "account-number" + FlagSequence = "sequence" + FlagMemo = "memo" + FlagFee = "fee" + FlagAsync = "async" + FlagJson = "json" + FlagPrintResponse = "print-response" + FlagDryRun = "dry-run" + FlagGenerateOnly = "generate-only" + FlagIndentResponse = "indent" + FlagListenAddr = "laddr" + FlagCORS = "cors" + FlagMaxOpenConnections = "max-open" + FlagInsecure = "insecure" + FlagSSLHosts = "ssl-hosts" + FlagSSLCertFile = "ssl-certfile" + FlagSSLKeyFile = "ssl-keyfile" ) // LineBreak can be included in a command list to provide a blank line @@ -92,6 +99,26 @@ func PostCommands(cmds ...*cobra.Command) []*cobra.Command { return cmds } +// RegisterRestServerFlags registers the flags required for rest server +func RegisterRestServerFlags(cmd *cobra.Command) *cobra.Command { + cmd.Flags().String(FlagListenAddr, "tcp://localhost:1317", "The address for the server to listen on") + cmd.Flags().Bool(FlagInsecure, false, "Do not set up SSL/TLS layer") + cmd.Flags().String(FlagSSLHosts, "", "Comma-separated hostnames and IPs to generate a certificate for") + cmd.Flags().String(FlagSSLCertFile, "", "Path to a SSL certificate file. If not supplied, a self-signed certificate will be generated.") + cmd.Flags().String(FlagSSLKeyFile, "", "Path to a key file; ignored if a certificate file is not supplied.") + cmd.Flags().String(FlagCORS, "", "Set the domains that can make CORS requests (* for all)") + cmd.Flags().String(FlagChainID, "", "Chain ID of Tendermint node") + cmd.Flags().String(FlagNode, "tcp://localhost:26657", "Address of the node to connect to") + cmd.Flags().Int(FlagMaxOpenConnections, 1000, "The number of maximum open connections") + cmd.Flags().Bool(FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") + cmd.Flags().Bool(FlagIndentResponse, false, "Add indent to JSON response") + + viper.BindPFlag(FlagTrustNode, cmd.Flags().Lookup(FlagTrustNode)) + viper.BindPFlag(FlagChainID, cmd.Flags().Lookup(FlagChainID)) + viper.BindPFlag(FlagNode, cmd.Flags().Lookup(FlagNode)) + return cmd +} + // Gas flag parsing functions // GasSetting encapsulates the possible values passed through the --gas flag. diff --git a/client/keys/utils.go b/client/keys/utils.go index 742b512d3da7..0ac4a9c90727 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -2,20 +2,17 @@ package keys import ( "fmt" - "github.com/syndtr/goleveldb/leveldb/opt" + "net/http" "path/filepath" - "github.com/spf13/viper" - - "github.com/cosmos/cosmos-sdk/crypto/keys" - "github.com/tendermint/tendermint/libs/cli" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys" sdk "github.com/cosmos/cosmos-sdk/types" - "net/http" + "github.com/spf13/viper" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/tendermint/tendermint/libs/cli" + dbm "github.com/tendermint/tendermint/libs/db" ) // KeyDBName is the directory under root where we store the keys diff --git a/client/lcd/root.go b/client/lcd/root.go index 8366b6114c52..3d61816467fc 100644 --- a/client/lcd/root.go +++ b/client/lcd/root.go @@ -10,15 +10,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/keys" - "github.com/cosmos/cosmos-sdk/client/rpc" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/codec" + keybase "github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/server" - auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" - bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" - gov "github.com/cosmos/cosmos-sdk/x/gov/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/rakyll/statik/fs" "github.com/spf13/cobra" @@ -27,159 +21,155 @@ import ( tmserver "github.com/tendermint/tendermint/rpc/lib/server" ) -const ( - flagListenAddr = "laddr" - flagCORS = "cors" - flagMaxOpenConnections = "max-open" - flagInsecure = "insecure" - flagSSLHosts = "ssl-hosts" - flagSSLCertFile = "ssl-certfile" - flagSSLKeyFile = "ssl-keyfile" -) +// RestServer represents the Light Client Rest server +type RestServer struct { + Mux *mux.Router + CliCtx context.CLIContext + KeyBase keybase.Keybase + Cdc *codec.Codec -// 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 *codec.Codec) *cobra.Command { + log log.Logger + listener net.Listener + fingerprint string +} - cmd := &cobra.Command{ - Use: "rest-server", - Short: "Start LCD (light-client daemon), a local REST server", - RunE: func(cmd *cobra.Command, args []string) (err error) { - listenAddr := viper.GetString(flagListenAddr) - handler := createHandler(cdc) - - registerSwaggerUI(handler) - - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server") - maxOpen := viper.GetInt(flagMaxOpenConnections) - sslHosts := viper.GetString(flagSSLHosts) - certFile := viper.GetString(flagSSLCertFile) - keyFile := viper.GetString(flagSSLKeyFile) - - var listener net.Listener - var fingerprint string - - server.TrapSignal(func() { - err := listener.Close() - logger.Error("error closing listener", "err", err) - }) - - var cleanupFunc func() - - // TODO: re-enable insecure mode once #2715 has been addressed - if viper.GetBool(flagInsecure) { - fmt.Println( - "Insecure mode is temporarily disabled, please locally generate an " + - "SSL certificate to test. Support will be re-enabled soon!", - ) - // listener, err = tmserver.StartHTTPServer( - // listenAddr, handler, logger, - // tmserver.Config{MaxOpenConnections: maxOpen}, - // ) - // if err != nil { - // return - // } - } else { - if certFile != "" { - // validateCertKeyFiles() is needed to work around tendermint/tendermint#2460 - err = validateCertKeyFiles(certFile, keyFile) - if err != nil { - return err - } - - // cert/key pair is provided, read the fingerprint - fingerprint, err = fingerprintFromFile(certFile) - if err != nil { - return err - } - } else { - // if certificate is not supplied, generate a self-signed one - certFile, keyFile, fingerprint, err = genCertKeyFilesAndReturnFingerprint(sslHosts) - if err != nil { - return err - } - - cleanupFunc = func() { - os.Remove(certFile) - os.Remove(keyFile) - } - - defer cleanupFunc() - } - - listener, err = tmserver.StartHTTPAndTLSServer( - listenAddr, handler, - certFile, keyFile, - logger, - tmserver.Config{MaxOpenConnections: maxOpen}, - ) - if err != nil { - return - } - - logger.Info(fingerprint) - logger.Info("REST server started") - } +// NewRestServer creates a new rest server instance +func NewRestServer(cdc *codec.Codec) *RestServer { + r := mux.NewRouter() + cliCtx := context.NewCLIContext().WithCodec(cdc) - // logger.Info("REST server started") + // Register version methods on the router + r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET") + r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET") - return nil - }, - } + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server") - cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on") - cmd.Flags().Bool(flagInsecure, false, "Do not set up SSL/TLS layer") - cmd.Flags().String(flagSSLHosts, "", "Comma-separated hostnames and IPs to generate a certificate for") - cmd.Flags().String(flagSSLCertFile, "", "Path to a SSL certificate file. If not supplied, a self-signed certificate will be generated.") - cmd.Flags().String(flagSSLKeyFile, "", "Path to a key file; ignored if a certificate file is not supplied.") - cmd.Flags().String(flagCORS, "", "Set the domains that can make CORS requests (* for all)") - cmd.Flags().String(client.FlagChainID, "", "Chain ID of Tendermint node") - cmd.Flags().String(client.FlagNode, "tcp://localhost:26657", "Address of the node to connect to") - cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections") - cmd.Flags().Bool(client.FlagTrustNode, false, "Trust connected full node (don't verify proofs for responses)") - cmd.Flags().Bool(client.FlagIndentResponse, false, "Add indent to JSON response") - - viper.BindPFlag(client.FlagTrustNode, cmd.Flags().Lookup(client.FlagTrustNode)) - viper.BindPFlag(client.FlagChainID, cmd.Flags().Lookup(client.FlagChainID)) - viper.BindPFlag(client.FlagNode, cmd.Flags().Lookup(client.FlagNode)) + return &RestServer{ + Mux: r, + CliCtx: cliCtx, + Cdc: cdc, - return cmd + log: logger, + } } -func createHandler(cdc *codec.Codec) *mux.Router { - r := mux.NewRouter() +func (rs *RestServer) setKeybase(kb keybase.Keybase) { + // If a keybase is passed in, set it and return + if kb != nil { + rs.KeyBase = kb + return + } + // Otherwise get the keybase and set it kb, err := keys.GetKeyBase() //XXX if err != nil { - panic(err) + fmt.Printf("Failed to open Keybase: %s, exiting...", err) + os.Exit(1) } + rs.KeyBase = kb +} - cliCtx := context.NewCLIContext().WithCodec(cdc) +// Start starts the rest server +func (rs *RestServer) Start(listenAddr string, sslHosts string, + certFile string, keyFile string, maxOpen int, insecure bool) (err error) { + + server.TrapSignal(func() { + err := rs.listener.Close() + rs.log.Error("error closing listener", "err", err) + }) + + // TODO: re-enable insecure mode once #2715 has been addressed + if insecure { + fmt.Println( + "Insecure mode is temporarily disabled, please locally generate an " + + "SSL certificate to test. Support will be re-enabled soon!", + ) + // listener, err = tmserver.StartHTTPServer( + // listenAddr, handler, logger, + // tmserver.Config{MaxOpenConnections: maxOpen}, + // ) + // if err != nil { + // return + // } + } else { + if certFile != "" { + // validateCertKeyFiles() is needed to work around tendermint/tendermint#2460 + err = validateCertKeyFiles(certFile, keyFile) + if err != nil { + return err + } - // TODO: make more functional? aka r = keys.RegisterRoutes(r) - r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET") - r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET") + // cert/key pair is provided, read the fingerprint + rs.fingerprint, err = fingerprintFromFile(certFile) + if err != nil { + return err + } + } else { + // if certificate is not supplied, generate a self-signed one + certFile, keyFile, rs.fingerprint, err = genCertKeyFilesAndReturnFingerprint(sslHosts) + if err != nil { + return err + } + + defer func() { + os.Remove(certFile) + os.Remove(keyFile) + }() + } + + rs.listener, err = tmserver.StartHTTPAndTLSServer( + listenAddr, rs.Mux, + certFile, keyFile, + rs.log, + tmserver.Config{MaxOpenConnections: maxOpen}, + ) + if err != nil { + return + } + + rs.log.Info(rs.fingerprint) + rs.log.Info("REST server started") + } + + // logger.Info("REST server started") + + return nil +} - keys.RegisterRoutes(r, cliCtx.Indent) - 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) - gov.RegisterRoutes(cliCtx, r, cdc) +// ServeCommand will generate a long-running rest server +// (aka Light Client Daemon) that exposes functionality similar +// to the cli, but over rest +func (rs *RestServer) ServeCommand() *cobra.Command { + cmd := &cobra.Command{ + Use: "rest-server", + Short: "Start LCD (light-client daemon), a local REST server", + RunE: func(cmd *cobra.Command, args []string) (err error) { + rs.setKeybase(nil) + // Start the rest server and return error if one exists + err = rs.Start( + viper.GetString(client.FlagListenAddr), + viper.GetString(client.FlagSSLHosts), + viper.GetString(client.FlagSSLCertFile), + viper.GetString(client.FlagSSLKeyFile), + viper.GetInt(client.FlagMaxOpenConnections), + viper.GetBool(client.FlagInsecure)) + + return err + }, + } - return r + client.RegisterRestServerFlags(cmd) + + return cmd } -func registerSwaggerUI(r *mux.Router) { +func (rs *RestServer) registerSwaggerUI() { statikFS, err := fs.New() if err != nil { panic(err) } staticServer := http.FileServer(statikFS) - r.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", staticServer)) + rs.Mux.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", staticServer)) } func validateCertKeyFiles(certFile, keyFile string) error { diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 774fd4d6adb0..4fbacf3d5813 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -19,6 +19,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/keys" + "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/tx" gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/codec" crkeys "github.com/cosmos/cosmos-sdk/crypto/keys" @@ -45,6 +47,12 @@ import ( "github.com/tendermint/tendermint/proxy" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmtypes "github.com/tendermint/tendermint/types" + + authRest "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + bankRest "github.com/cosmos/cosmos-sdk/x/bank/client/rest" + govRest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" + slashingRest "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" + stakeRest "github.com/cosmos/cosmos-sdk/x/stake/client/rest" ) // makePathname creates a unique pathname for each test. It will panic if it @@ -103,6 +111,13 @@ func GetKeyBase(t *testing.T) crkeys.Keybase { return keybase } +// GetTestKeyBase fetches the current testing keybase +func GetTestKeyBase(t *testing.T) crkeys.Keybase { + keybase, err := keys.GetKeyBaseWithWritePerm() + require.NoError(t, err) + return keybase +} + // CreateAddr adds an address to the key store and returns an address and seed. // It also requires that the key could be created. func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.AccAddress, string) { @@ -288,7 +303,7 @@ func InitializeTestLCD( require.NoError(t, err) tests.WaitForNextHeightTM(tests.ExtractPortFromAddress(config.RPC.ListenAddress)) - lcd, err := startLCD(logger, listenAddr, cdc) + lcd, err := startLCD(logger, listenAddr, cdc, t) require.NoError(t, err) tests.WaitForLCDStart(port) @@ -347,8 +362,23 @@ func startTM( // startLCD starts the LCD. // // NOTE: This causes the thread to block. -func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec) (net.Listener, error) { - return tmrpc.StartHTTPServer(listenAddr, createHandler(cdc), logger, tmrpc.Config{}) +func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec, t *testing.T) (net.Listener, error) { + rs := NewRestServer(cdc) + rs.setKeybase(GetTestKeyBase(t)) + registerRoutes(rs) + return tmrpc.StartHTTPServer(listenAddr, rs.Mux, logger, tmrpc.Config{}) +} + +// NOTE: If making updates here also update cmd/gaia/cmd/gaiacli/main.go +func registerRoutes(rs *RestServer) { + keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) + rpc.RegisterRoutes(rs.CliCtx, rs.Mux) + tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) + authRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, "acc") + bankRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + stakeRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + slashingRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + govRest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) } // Request makes a test LCD test request. It returns a response object and a diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index de99b0fc8fac..3dd936f8635a 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -1,9 +1,11 @@ package main import ( + "net/http" "os" "path" + "github.com/rakyll/statik/fs" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -13,9 +15,15 @@ import ( "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/client/rpc" + "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" + auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" + gov "github.com/cosmos/cosmos-sdk/x/gov/client/rest" + slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" + stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" _ "github.com/cosmos/cosmos-sdk/client/lcd/statik" ) @@ -37,15 +45,25 @@ var ( ) func main() { + // Configure cobra to sort commands cobra.EnableCommandSorting = false + + // Instantiate the codec for the command line application cdc := app.MakeCodec() + // Read in the configuration file for the sdk config := sdk.GetConfig() config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub) config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub) config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub) config.Seal() + // Create a new RestServer instance to serve the light client routes + rs := lcd.NewRestServer(cdc) + + // registerRoutes registers the routes on the rest server + registerRoutes(rs) + // TODO: setup keybase, viper object, etc. to be passed into // the below functions and eliminate global vars, like we do // with the cdc @@ -58,7 +76,7 @@ func main() { queryCmd(cdc), txCmd(cdc), client.LineBreak, - lcd.ServeCommand(cdc), + rs.ServeCommand(), client.LineBreak, keys.Commands(), client.LineBreak, @@ -79,6 +97,30 @@ func main() { } } +// registerRoutes registers the routes from the different modules for the LCD. +// NOTE: details on the routes added for each module are in the module documentation +// NOTE: If making updates here you also need to update the test helper in client/lcd/test_helper.go +func registerRoutes(rs *lcd.RestServer) { + registerSwaggerUI(rs) + keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) + rpc.RegisterRoutes(rs.CliCtx, rs.Mux) + tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) + auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, "acc") + bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + stake.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + gov.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) +} + +func registerSwaggerUI(rs *lcd.RestServer) { + statikFS, err := fs.New() + if err != nil { + panic(err) + } + staticServer := http.FileServer(statikFS) + rs.Mux.PathPrefix("/swagger-ui/").Handler(http.StripPrefix("/swagger-ui/", staticServer)) +} + func initConfig(cmd *cobra.Command) error { home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) if err != nil { diff --git a/docs/examples/basecoin/cmd/basecli/main.go b/docs/examples/basecoin/cmd/basecli/main.go index 3a16c8a97bbd..ad32bf516978 100644 --- a/docs/examples/basecoin/cmd/basecli/main.go +++ b/docs/examples/basecoin/cmd/basecli/main.go @@ -9,12 +9,17 @@ import ( "github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" + slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" + stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" "github.com/spf13/cobra" "github.com/tendermint/tendermint/libs/cli" ) @@ -34,6 +39,17 @@ func main() { // get the codec cdc := app.MakeCodec() + // Setup certain SDK config + config := sdk.GetConfig() + config.SetBech32PrefixForAccount("baseacc", "basepub") + config.SetBech32PrefixForValidator("baseval", "basevalpub") + config.SetBech32PrefixForConsensusNode("basecons", "baseconspub") + config.Seal() + + rs := lcd.NewRestServer(cdc) + + registerRoutes(rs) + // TODO: Setup keybase, viper object, etc. to be passed into // the below functions and eliminate global vars, like we do // with the cdc. @@ -83,7 +99,7 @@ func main() { // add proxy, version and key info rootCmd.AddCommand( client.LineBreak, - lcd.ServeCommand(cdc), + rs.ServeCommand(), keys.Commands(), client.LineBreak, version.VersionCmd, @@ -97,3 +113,13 @@ func main() { panic(err) } } + +func registerRoutes(rs *lcd.RestServer) { + keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) + rpc.RegisterRoutes(rs.CliCtx, rs.Mux) + tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) + auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, "acc") + bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + stake.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) + slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) +} diff --git a/docs/examples/democoin/cmd/democli/main.go b/docs/examples/democoin/cmd/democli/main.go index adb6169c9ee5..d101da2d9c38 100644 --- a/docs/examples/democoin/cmd/democli/main.go +++ b/docs/examples/democoin/cmd/democli/main.go @@ -13,8 +13,9 @@ import ( "github.com/cosmos/cosmos-sdk/version" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" + auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" - ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli" + bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" "github.com/cosmos/cosmos-sdk/docs/examples/democoin/app" "github.com/cosmos/cosmos-sdk/docs/examples/democoin/types" @@ -47,6 +48,10 @@ func main() { config.SetBech32PrefixForConsensusNode("democons", "democonspub") config.Seal() + rs := lcd.NewRestServer(cdc) + + registerRoutes(rs) + // TODO: setup keybase, viper object, etc. to be passed into // the below functions and eliminate global vars, like we do // with the cdc @@ -74,11 +79,6 @@ func main() { )...) rootCmd.AddCommand( client.PostCommands( - ibccmd.IBCTransferCmd(cdc), - )...) - rootCmd.AddCommand( - client.PostCommands( - ibccmd.IBCRelayCmd(cdc), simplestakingcmd.BondTxCmd(cdc), )...) rootCmd.AddCommand( @@ -96,7 +96,7 @@ func main() { // add proxy, version and key info rootCmd.AddCommand( client.LineBreak, - lcd.ServeCommand(cdc), + rs.ServeCommand(), keys.Commands(), client.LineBreak, version.VersionCmd, @@ -110,3 +110,11 @@ func main() { panic(err) } } + +func registerRoutes(rs *lcd.RestServer) { + keys.RegisterRoutes(rs.Mux, rs.CliCtx.Indent) + rpc.RegisterRoutes(rs.CliCtx, rs.Mux) + tx.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) + auth.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, "acc") + bank.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) +}