Expose LCD router, allowing devs to register custom routes from their modules (#2836)
* Fixes #1081
This commit is contained in:
parent
15b6fa0959
commit
9676ce7d48
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"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"
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
log log.Logger
|
||||
listener net.Listener
|
||||
fingerprint string
|
||||
}
|
||||
|
||||
// NewRestServer creates a new rest server instance
|
||||
func NewRestServer(cdc *codec.Codec) *RestServer {
|
||||
r := mux.NewRouter()
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
// 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")
|
||||
|
||||
return &RestServer{
|
||||
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() {
|
||||
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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
||||
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) {
|
||||
listenAddr := viper.GetString(flagListenAddr)
|
||||
handler := createHandler(cdc)
|
||||
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))
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
// logger.Info("REST server started")
|
||||
|
||||
return nil
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
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))
|
||||
client.RegisterRestServerFlags(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func createHandler(cdc *codec.Codec) *mux.Router {
|
||||
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) {
|
||||
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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue