Expose LCD router, allowing devs to register custom routes from their modules (#2836)

* Fixes #1081
This commit is contained in:
Jack Zampolin 2018-11-16 14:21:36 -08:00 committed by GitHub
parent 15b6fa0959
commit 9676ce7d48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 300 additions and 179 deletions

View File

@ -48,6 +48,7 @@ FEATURES
IMPROVEMENTS IMPROVEMENTS
* Gaia REST API (`gaiacli advanced rest-server`) * 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`) * Gaia CLI (`gaiacli`)
* [\#2749](https://github.com/cosmos/cosmos-sdk/pull/2749) Add --chain-id flag to gaiad testnet * [\#2749](https://github.com/cosmos/cosmos-sdk/pull/2749) Add --chain-id flag to gaiad testnet

View File

@ -36,6 +36,13 @@ const (
FlagDryRun = "dry-run" FlagDryRun = "dry-run"
FlagGenerateOnly = "generate-only" FlagGenerateOnly = "generate-only"
FlagIndentResponse = "indent" 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 // 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 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 // Gas flag parsing functions
// GasSetting encapsulates the possible values passed through the --gas flag. // GasSetting encapsulates the possible values passed through the --gas flag.

View File

@ -2,20 +2,17 @@ package keys
import ( import (
"fmt" "fmt"
"github.com/syndtr/goleveldb/leveldb/opt" "net/http"
"path/filepath" "path/filepath"
"github.com/spf13/viper" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/spf13/viper"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/cli"
dbm "github.com/tendermint/tendermint/libs/db" dbm "github.com/tendermint/tendermint/libs/db"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"net/http"
) )
// KeyDBName is the directory under root where we store the keys // KeyDBName is the directory under root where we store the keys

View File

@ -10,15 +10,9 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/keys" "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" "github.com/cosmos/cosmos-sdk/codec"
keybase "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server" "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/gorilla/mux"
"github.com/rakyll/statik/fs" "github.com/rakyll/statik/fs"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -27,48 +21,65 @@ import (
tmserver "github.com/tendermint/tendermint/rpc/lib/server" tmserver "github.com/tendermint/tendermint/rpc/lib/server"
) )
const ( // RestServer represents the Light Client Rest server
flagListenAddr = "laddr" type RestServer struct {
flagCORS = "cors" Mux *mux.Router
flagMaxOpenConnections = "max-open" CliCtx context.CLIContext
flagInsecure = "insecure" KeyBase keybase.Keybase
flagSSLHosts = "ssl-hosts" Cdc *codec.Codec
flagSSLCertFile = "ssl-certfile"
flagSSLKeyFile = "ssl-keyfile"
)
// ServeCommand will generate a long-running rest server log log.Logger
// (aka Light Client Daemon) that exposes functionality similar listener net.Listener
// to the cli, but over rest fingerprint string
func ServeCommand(cdc *codec.Codec) *cobra.Command { }
cmd := &cobra.Command{ // NewRestServer creates a new rest server instance
Use: "rest-server", func NewRestServer(cdc *codec.Codec) *RestServer {
Short: "Start LCD (light-client daemon), a local REST server", r := mux.NewRouter()
RunE: func(cmd *cobra.Command, args []string) (err error) { cliCtx := context.NewCLIContext().WithCodec(cdc)
listenAddr := viper.GetString(flagListenAddr)
handler := createHandler(cdc)
registerSwaggerUI(handler) // Register version methods on the router
r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET")
r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET")
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server") 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 return &RestServer{
var fingerprint string Mux: r,
CliCtx: cliCtx,
Cdc: cdc,
log: logger,
}
}
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 {
fmt.Printf("Failed to open Keybase: %s, exiting...", err)
os.Exit(1)
}
rs.KeyBase = kb
}
// 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() { server.TrapSignal(func() {
err := listener.Close() err := rs.listener.Close()
logger.Error("error closing listener", "err", err) rs.log.Error("error closing listener", "err", err)
}) })
var cleanupFunc func()
// TODO: re-enable insecure mode once #2715 has been addressed // TODO: re-enable insecure mode once #2715 has been addressed
if viper.GetBool(flagInsecure) { if insecure {
fmt.Println( fmt.Println(
"Insecure mode is temporarily disabled, please locally generate an " + "Insecure mode is temporarily disabled, please locally generate an " +
"SSL certificate to test. Support will be re-enabled soon!", "SSL certificate to test. Support will be re-enabled soon!",
@ -89,97 +100,76 @@ func ServeCommand(cdc *codec.Codec) *cobra.Command {
} }
// cert/key pair is provided, read the fingerprint // cert/key pair is provided, read the fingerprint
fingerprint, err = fingerprintFromFile(certFile) rs.fingerprint, err = fingerprintFromFile(certFile)
if err != nil { if err != nil {
return err return err
} }
} else { } else {
// if certificate is not supplied, generate a self-signed one // if certificate is not supplied, generate a self-signed one
certFile, keyFile, fingerprint, err = genCertKeyFilesAndReturnFingerprint(sslHosts) certFile, keyFile, rs.fingerprint, err = genCertKeyFilesAndReturnFingerprint(sslHosts)
if err != nil { if err != nil {
return err return err
} }
cleanupFunc = func() { defer func() {
os.Remove(certFile) os.Remove(certFile)
os.Remove(keyFile) os.Remove(keyFile)
}()
} }
defer cleanupFunc() rs.listener, err = tmserver.StartHTTPAndTLSServer(
} listenAddr, rs.Mux,
listener, err = tmserver.StartHTTPAndTLSServer(
listenAddr, handler,
certFile, keyFile, certFile, keyFile,
logger, rs.log,
tmserver.Config{MaxOpenConnections: maxOpen}, tmserver.Config{MaxOpenConnections: maxOpen},
) )
if err != nil { if err != nil {
return return
} }
logger.Info(fingerprint) rs.log.Info(rs.fingerprint)
logger.Info("REST server started") rs.log.Info("REST server started")
} }
// logger.Info("REST server started") // logger.Info("REST server started")
return nil return nil
}
// 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
}, },
} }
cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on") client.RegisterRestServerFlags(cmd)
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 cmd return cmd
} }
func createHandler(cdc *codec.Codec) *mux.Router { func (rs *RestServer) registerSwaggerUI() {
r := mux.NewRouter()
kb, err := keys.GetKeyBase() //XXX
if err != nil {
panic(err)
}
cliCtx := context.NewCLIContext().WithCodec(cdc)
// TODO: make more functional? aka r = keys.RegisterRoutes(r)
r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET")
r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET")
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)
return r
}
func registerSwaggerUI(r *mux.Router) {
statikFS, err := fs.New() statikFS, err := fs.New()
if err != nil { if err != nil {
panic(err) panic(err)
} }
staticServer := http.FileServer(statikFS) 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 { func validateCertKeyFiles(certFile, keyFile string) error {

View File

@ -19,6 +19,8 @@ import (
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/keys" "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" gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
crkeys "github.com/cosmos/cosmos-sdk/crypto/keys" crkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
@ -45,6 +47,12 @@ import (
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
tmrpc "github.com/tendermint/tendermint/rpc/lib/server" tmrpc "github.com/tendermint/tendermint/rpc/lib/server"
tmtypes "github.com/tendermint/tendermint/types" 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 // 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 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. // CreateAddr adds an address to the key store and returns an address and seed.
// It also requires that the key could be created. // It also requires that the key could be created.
func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.AccAddress, string) { func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.AccAddress, string) {
@ -288,7 +303,7 @@ func InitializeTestLCD(
require.NoError(t, err) require.NoError(t, err)
tests.WaitForNextHeightTM(tests.ExtractPortFromAddress(config.RPC.ListenAddress)) tests.WaitForNextHeightTM(tests.ExtractPortFromAddress(config.RPC.ListenAddress))
lcd, err := startLCD(logger, listenAddr, cdc) lcd, err := startLCD(logger, listenAddr, cdc, t)
require.NoError(t, err) require.NoError(t, err)
tests.WaitForLCDStart(port) tests.WaitForLCDStart(port)
@ -347,8 +362,23 @@ func startTM(
// startLCD starts the LCD. // startLCD starts the LCD.
// //
// NOTE: This causes the thread to block. // NOTE: This causes the thread to block.
func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec) (net.Listener, error) { func startLCD(logger log.Logger, listenAddr string, cdc *codec.Codec, t *testing.T) (net.Listener, error) {
return tmrpc.StartHTTPServer(listenAddr, createHandler(cdc), logger, tmrpc.Config{}) 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 // Request makes a test LCD test request. It returns a response object and a

View File

@ -1,9 +1,11 @@
package main package main
import ( import (
"net/http"
"os" "os"
"path" "path"
"github.com/rakyll/statik/fs"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -13,9 +15,15 @@ import (
"github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/lcd" "github.com/cosmos/cosmos-sdk/client/lcd"
"github.com/cosmos/cosmos-sdk/client/rpc" "github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version" "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" _ "github.com/cosmos/cosmos-sdk/client/lcd/statik"
) )
@ -37,15 +45,25 @@ var (
) )
func main() { func main() {
// Configure cobra to sort commands
cobra.EnableCommandSorting = false cobra.EnableCommandSorting = false
// Instantiate the codec for the command line application
cdc := app.MakeCodec() cdc := app.MakeCodec()
// Read in the configuration file for the sdk
config := sdk.GetConfig() config := sdk.GetConfig()
config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub) config.SetBech32PrefixForAccount(sdk.Bech32PrefixAccAddr, sdk.Bech32PrefixAccPub)
config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub) config.SetBech32PrefixForValidator(sdk.Bech32PrefixValAddr, sdk.Bech32PrefixValPub)
config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub) config.SetBech32PrefixForConsensusNode(sdk.Bech32PrefixConsAddr, sdk.Bech32PrefixConsPub)
config.Seal() 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 // TODO: setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do // the below functions and eliminate global vars, like we do
// with the cdc // with the cdc
@ -58,7 +76,7 @@ func main() {
queryCmd(cdc), queryCmd(cdc),
txCmd(cdc), txCmd(cdc),
client.LineBreak, client.LineBreak,
lcd.ServeCommand(cdc), rs.ServeCommand(),
client.LineBreak, client.LineBreak,
keys.Commands(), keys.Commands(),
client.LineBreak, 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 { func initConfig(cmd *cobra.Command) error {
home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) home, err := cmd.PersistentFlags().GetString(cli.HomeFlag)
if err != nil { if err != nil {

View File

@ -9,12 +9,17 @@ import (
"github.com/cosmos/cosmos-sdk/client/tx" "github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/app"
"github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/docs/examples/basecoin/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/version"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" 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" 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" ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/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" 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/spf13/cobra"
"github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/cli"
) )
@ -34,6 +39,17 @@ func main() {
// get the codec // get the codec
cdc := app.MakeCodec() 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 // TODO: Setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do // the below functions and eliminate global vars, like we do
// with the cdc. // with the cdc.
@ -83,7 +99,7 @@ func main() {
// add proxy, version and key info // add proxy, version and key info
rootCmd.AddCommand( rootCmd.AddCommand(
client.LineBreak, client.LineBreak,
lcd.ServeCommand(cdc), rs.ServeCommand(),
keys.Commands(), keys.Commands(),
client.LineBreak, client.LineBreak,
version.VersionCmd, version.VersionCmd,
@ -97,3 +113,13 @@ func main() {
panic(err) 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)
}

View File

@ -13,8 +13,9 @@ import (
"github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/version"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" 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" 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/app"
"github.com/cosmos/cosmos-sdk/docs/examples/democoin/types" "github.com/cosmos/cosmos-sdk/docs/examples/democoin/types"
@ -47,6 +48,10 @@ func main() {
config.SetBech32PrefixForConsensusNode("democons", "democonspub") config.SetBech32PrefixForConsensusNode("democons", "democonspub")
config.Seal() config.Seal()
rs := lcd.NewRestServer(cdc)
registerRoutes(rs)
// TODO: setup keybase, viper object, etc. to be passed into // TODO: setup keybase, viper object, etc. to be passed into
// the below functions and eliminate global vars, like we do // the below functions and eliminate global vars, like we do
// with the cdc // with the cdc
@ -74,11 +79,6 @@ func main() {
)...) )...)
rootCmd.AddCommand( rootCmd.AddCommand(
client.PostCommands( client.PostCommands(
ibccmd.IBCTransferCmd(cdc),
)...)
rootCmd.AddCommand(
client.PostCommands(
ibccmd.IBCRelayCmd(cdc),
simplestakingcmd.BondTxCmd(cdc), simplestakingcmd.BondTxCmd(cdc),
)...) )...)
rootCmd.AddCommand( rootCmd.AddCommand(
@ -96,7 +96,7 @@ func main() {
// add proxy, version and key info // add proxy, version and key info
rootCmd.AddCommand( rootCmd.AddCommand(
client.LineBreak, client.LineBreak,
lcd.ServeCommand(cdc), rs.ServeCommand(),
keys.Commands(), keys.Commands(),
client.LineBreak, client.LineBreak,
version.VersionCmd, version.VersionCmd,
@ -110,3 +110,11 @@ func main() {
panic(err) 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)
}