From eadd0cfd5f27007b9c2f87bd1a1af05ed8c638a9 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 22 Jul 2021 02:38:46 +0530 Subject: [PATCH 01/18] Added REST API start command with service handler --- cmd/connect.go | 3 +- cmd/start.go | 77 ++++++++++ context/context.go | 22 +++ go.mod | 3 +- go.sum | 7 +- main.go | 19 ++- middlewares/header.go | 16 ++ middlewares/log.go | 34 +++++ rest/service/handler.go | 292 +++++++++++++++++++++++++++++++++++++ rest/service/request.go | 63 ++++++++ rest/service/response.go | 9 ++ rest/service/route.go | 23 +++ types/config/config.go | 104 +++++++++++++ types/config/cors.go | 19 +++ types/config/keyring.go | 30 ++++ types/keys.go | 8 + types/rest.go | 21 --- types/rest/error.go | 13 ++ types/rest/response.go | 15 ++ types/rest/writer.go | 35 +++++ utils/rand/string.go | 13 ++ utils/rest/writer.go | 35 +++++ x/node/client/cmd/query.go | 3 +- 23 files changed, 832 insertions(+), 32 deletions(-) create mode 100644 cmd/start.go create mode 100644 context/context.go create mode 100644 middlewares/header.go create mode 100644 middlewares/log.go create mode 100644 rest/service/handler.go create mode 100644 rest/service/request.go create mode 100644 rest/service/response.go create mode 100644 rest/service/route.go create mode 100644 types/config/config.go create mode 100644 types/config/cors.go create mode 100644 types/config/keyring.go delete mode 100644 types/rest.go create mode 100644 types/rest/error.go create mode 100644 types/rest/response.go create mode 100644 types/rest/writer.go create mode 100644 utils/rand/string.go create mode 100644 utils/rest/writer.go diff --git a/cmd/connect.go b/cmd/connect.go index cde74b6..1c24489 100644 --- a/cmd/connect.go +++ b/cmd/connect.go @@ -30,6 +30,7 @@ import ( "github.com/sentinel-official/cli-client/services/wireguard" wireguardtypes "github.com/sentinel-official/cli-client/services/wireguard/types" clienttypes "github.com/sentinel-official/cli-client/types" + resttypes "github.com/sentinel-official/cli-client/types/rest" netutil "github.com/sentinel-official/cli-client/utils/net" ) @@ -214,7 +215,7 @@ func ConnectCmd() *cobra.Command { } var ( - body clienttypes.Response + body resttypes.Response endpoint = fmt.Sprintf( "%s/accounts/%s/sessions/%d", strings.Trim(node.RemoteURL, "/"), ctx.FromAddress, session.Id, diff --git a/cmd/start.go b/cmd/start.go new file mode 100644 index 0000000..fd9dd1f --- /dev/null +++ b/cmd/start.go @@ -0,0 +1,77 @@ +package cmd + +import ( + "net/http" + "path/filepath" + "strings" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/gorilla/mux" + "github.com/rs/cors" + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/sentinel-official/cli-client/context" + "github.com/sentinel-official/cli-client/middlewares" + servicerest "github.com/sentinel-official/cli-client/rest/service" + "github.com/sentinel-official/cli-client/types" + configtypes "github.com/sentinel-official/cli-client/types/config" + randutils "github.com/sentinel-official/cli-client/utils/rand" +) + +func StartCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "start", + Short: "Start REST API server", + RunE: func(cmd *cobra.Command, args []string) error { + var ( + home = viper.GetString(flags.FlagHome) + configPath = filepath.Join(home, types.ConfigFilename) + buildPath = filepath.Join(home, types.BuildFolderName) + ) + + v := viper.New() + v.SetConfigFile(configPath) + + config, err := configtypes.ReadInConfig(v) + if err != nil { + return err + } + if err := config.Validate(); err != nil { + return err + } + + config.Token = randutils.RandomStringHex(types.TokenLength) + if err := config.SaveToPath(configPath); err != nil { + return err + } + + var ( + ctx = context.NewContext(). + WithConfig(config) + + muxRouter = mux.NewRouter() + prefixRouter = muxRouter.PathPrefix(types.APIPathPrefix).Subrouter() + ) + + muxRouter.Use(middlewares.Log) + muxRouter.PathPrefix("/"). + Handler(http.FileServer(http.Dir(buildPath))) + + prefixRouter.Use(middlewares.AddHeaders) + servicerest.RegisterRoutes(prefixRouter, ctx) + + router := cors.New( + cors.Options{ + AllowedOrigins: strings.Split(config.CORS.AllowedOrigins, ","), + AllowedMethods: []string{http.MethodPost}, + AllowedHeaders: []string{"Content-Type"}, + }, + ).Handler(muxRouter) + + return http.ListenAndServe(config.ListenOn, router) + }, + } + + return cmd +} diff --git a/context/context.go b/context/context.go new file mode 100644 index 0000000..190cf61 --- /dev/null +++ b/context/context.go @@ -0,0 +1,22 @@ +package context + +import ( + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/viper" + + configtypes "github.com/sentinel-official/cli-client/types/config" +) + +type Context struct { + config *configtypes.Config +} + +func NewContext() *Context { + return &Context{} +} + +func (c *Context) WithConfig(v *configtypes.Config) *Context { c.config = v; return c } + +func (c *Context) Config() *configtypes.Config { return c.config } + +func (c *Context) Home() string { return viper.GetString(flags.FlagHome) } diff --git a/go.mod b/go.mod index ed5845b..4084c86 100644 --- a/go.mod +++ b/go.mod @@ -6,13 +6,14 @@ require ( github.com/alessio/shellescape v1.4.1 github.com/cosmos/cosmos-sdk v0.42.5 github.com/go-kit/kit v0.10.0 + github.com/gorilla/mux v1.8.0 github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/errors v0.9.1 + github.com/rs/cors v1.7.0 github.com/sentinel-official/hub v0.7.0 github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.8.0 golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e - golang.org/x/net v0.0.0-20210614182718-04defd469f4e ) replace ( diff --git a/go.sum b/go.sum index 78dedb6..01ce406 100644 --- a/go.sum +++ b/go.sum @@ -791,9 +791,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -881,7 +880,6 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -894,9 +892,8 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/main.go b/main.go index 5b52480..6644729 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "context" "os" + "path/filepath" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -16,6 +17,7 @@ import ( "github.com/sentinel-official/cli-client/cmd" "github.com/sentinel-official/cli-client/types" + configtypes "github.com/sentinel-official/cli-client/types/config" ) func main() { @@ -24,11 +26,21 @@ func main() { Use: "sentinelcli", SilenceUsage: true, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { - home := viper.GetString(flags.FlagHome) - if _, err := os.Stat(home); err != nil { + var ( + home = viper.GetString(flags.FlagHome) + configPath = filepath.Join(home, "config.toml") + ) + + if _, err := os.Stat(configPath); err != nil { if err := os.MkdirAll(home, 0700); err != nil { return err } + + config := configtypes.NewConfig(). + WithDefaultValues() + if err := config.SaveToPath(configPath); err != nil { + return err + } } var ( @@ -56,12 +68,13 @@ func main() { cmd.ConnectCmd(), cmd.DisconnectCmd(), cmd.QueryCommand(), + cmd.StartCmd(), cmd.TxCommand(), keys.Commands(types.DefaultHomeDirectory), version.NewVersionCommand(), ) - root.PersistentFlags().String(flags.FlagHome, types.DefaultHomeDirectory, "application home directory") + root.PersistentFlags().String(flags.FlagHome, types.DefaultHomeDirectory, "home directory of the application") _ = viper.BindPFlag(flags.FlagHome, root.PersistentFlags().Lookup(flags.FlagHome)) _ = root.ExecuteContext( diff --git a/middlewares/header.go b/middlewares/header.go new file mode 100644 index 0000000..8b42cad --- /dev/null +++ b/middlewares/header.go @@ -0,0 +1,16 @@ +package middlewares + +import ( + "net/http" + + "github.com/go-kit/kit/transport/http/jsonrpc" +) + +func AddHeaders(next http.Handler) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", jsonrpc.ContentType) + next.ServeHTTP(w, r) + }, + ) +} diff --git a/middlewares/log.go b/middlewares/log.go new file mode 100644 index 0000000..5217806 --- /dev/null +++ b/middlewares/log.go @@ -0,0 +1,34 @@ +package middlewares + +import ( + "log" + "net/http" + "time" + + resttypes "github.com/sentinel-official/cli-client/types/rest" +) + +func Log(next http.Handler) http.Handler { + return http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + var ( + rw = resttypes.NewResponseWriter(w) + start = time.Now() + ) + + next.ServeHTTP(rw, r) + log.Printf( + "- %s - %s %s %s - %d %d - %s - %s - %s", + r.RemoteAddr, + r.Proto, + r.Method, + r.RequestURI, + rw.Status, + rw.Length, + time.Since(start), + r.Referer(), + r.UserAgent(), + ) + }, + ) +} diff --git a/rest/service/handler.go b/rest/service/handler.go new file mode 100644 index 0000000..ca931f5 --- /dev/null +++ b/rest/service/handler.go @@ -0,0 +1,292 @@ +package service + +import ( + "encoding/binary" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/version" + + "github.com/sentinel-official/cli-client/context" + "github.com/sentinel-official/cli-client/services/wireguard" + wireguardtypes "github.com/sentinel-official/cli-client/services/wireguard/types" + "github.com/sentinel-official/cli-client/types" + resttypes "github.com/sentinel-official/cli-client/types/rest" + netutils "github.com/sentinel-official/cli-client/utils/net" + restutils "github.com/sentinel-official/cli-client/utils/rest" +) + +func HandlerConnect(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + status = types.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + ) + + request, err := NewRequestConnect(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := request.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } + + if err := status.LoadFromPath(statusFilePath); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1003, err.Error()), + ) + return + } + + if status.IFace != "" { + var ( + service = wireguard.NewWireGuard(). + WithConfig( + &wireguardtypes.Config{ + Name: status.IFace, + }, + ) + ) + + if service.IsUp() { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1004, fmt.Sprintf("service is already running in interface %s", status.IFace)), + ) + return + } + } + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1005, err.Error()), + ) + return + } + + key, err := kr.Key(request.From) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1006, err.Error()), + ) + return + } + + listenPort, err := netutils.GetFreeUDPPort() + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1007, err.Error()), + ) + return + } + + var ( + wireGuardConfig = &wireguardtypes.Config{ + Name: wireguardtypes.DefaultInterface, + Interface: wireguardtypes.Interface{ + Addresses: []wireguardtypes.IPNet{ + { + IP: net.IP(request.Info[0 : 0+4]), + Net: 32, + }, + { + IP: net.IP(request.Info[4 : 4+16]), + Net: 128, + }, + }, + ListenPort: listenPort, + PrivateKey: *wireguardtypes.NewKey(request.Keys[0]), + DNS: append( + []net.IP{net.ParseIP("10.8.0.1")}, + request.Resolvers..., + ), + }, + Peers: []wireguardtypes.Peer{ + { + PublicKey: *wireguardtypes.NewKey(request.Info[26 : 26+32]), + AllowedIPs: []wireguardtypes.IPNet{ + {IP: net.ParseIP("0.0.0.0")}, + {IP: net.ParseIP("::")}, + }, + Endpoint: wireguardtypes.Endpoint{ + Host: net.IP(request.Info[20 : 20+4]).String(), + Port: binary.BigEndian.Uint16(request.Info[24 : 24+2]), + }, + PersistentKeepalive: 15, + }, + }, + } + + service = wireguard.NewWireGuard(). + WithConfig(wireGuardConfig) + ) + + status = status. + WithID(request.ID). + WithFrom(key.GetAddress().String()). + WithTo(request.To). + WithIFace(wireGuardConfig.Name) + + if err := status.SaveToPath(statusFilePath); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1008, err.Error()), + ) + } + + if err := service.PreUp(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1009, err.Error()), + ) + } + if err := service.Up(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1010, err.Error()), + ) + } + if err := service.PostUp(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1011, err.Error()), + ) + } + + restutils.WriteResultToResponse(w, http.StatusOK, nil) + } +} + +func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + status = types.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + ) + + if err := status.LoadFromPath(statusFilePath); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1001, err.Error()), + ) + return + } + + if status.IFace != "" { + var ( + service = wireguard.NewWireGuard(). + WithConfig( + &wireguardtypes.Config{ + Name: status.IFace, + }, + ) + ) + + if service.IsUp() { + if err := service.PreDown(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1002, err.Error()), + ) + } + if err := service.Down(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1003, err.Error()), + ) + } + if err := service.PostDown(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1004, err.Error()), + ) + } + } + } + + if err := os.Remove(statusFilePath); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1005, err.Error()), + ) + } + + restutils.WriteResultToResponse(w, http.StatusOK, nil) + } +} + +func HandlerStatus(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + status = types.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + ) + + if err := status.LoadFromPath(statusFilePath); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1001, err.Error()), + ) + return + } + + if status.IFace != "" { + var ( + service = wireguard.NewWireGuard(). + WithConfig( + &wireguardtypes.Config{ + Name: status.IFace, + }, + ) + ) + + if service.IsUp() { + upload, download, err := service.Transfer() + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1002, err.Error()), + ) + return + } + + restutils.WriteResultToResponse(w, http.StatusOK, + &ResponseStatus{ + From: status.From, + ID: status.ID, + To: status.To, + Upload: upload, + Download: download, + }, + ) + return + } + } + + restutils.WriteResultToResponse(w, http.StatusOK, nil) + } +} diff --git a/rest/service/request.go b/rest/service/request.go new file mode 100644 index 0000000..9469718 --- /dev/null +++ b/rest/service/request.go @@ -0,0 +1,63 @@ +package service + +import ( + "encoding/json" + "fmt" + "net" + "net/http" + + "github.com/pkg/errors" + hubtypes "github.com/sentinel-official/hub/types" +) + +type RequestConnect struct { + ID uint64 `json:"id"` + From string `json:"from"` + To string `json:"to"` + + Info []byte `json:"info"` + Keys [][]byte `json:"keys"` + Resolvers []net.IP `json:"resolvers"` +} + +func NewRequestConnect(r *http.Request) (*RequestConnect, error) { + var v RequestConnect + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *RequestConnect) Validate() error { + if r.ID == 0 { + return errors.New("id cannot be zero") + } + if r.From == "" { + return errors.New("from cannot be empty") + } + if r.To == "" { + return errors.New("to cannot be empty") + } + if _, err := hubtypes.NodeAddressFromBech32(r.To); err != nil { + return errors.Wrap(err, "invalid to") + } + + if r.Info == nil { + return errors.New("info cannot be nil") + } + if len(r.Info) != 4+16+4+2+32 { + return fmt.Errorf("info length must be %d bytes", 4+16+4+2+32) + } + if r.Keys == nil { + return errors.New("keys cannot be nil") + } + if len(r.Keys) != 1 { + return fmt.Errorf("keys length must be %d", 1) + } + if len(r.Keys[0]) != 32 { + return fmt.Errorf("key at index %d length must be %d bytes", 0, 32) + } + + return nil +} diff --git a/rest/service/response.go b/rest/service/response.go new file mode 100644 index 0000000..f1b900d --- /dev/null +++ b/rest/service/response.go @@ -0,0 +1,9 @@ +package service + +type ResponseStatus struct { + From string `json:"from"` + ID uint64 `json:"id"` + To string `json:"to"` + Upload int64 `json:"upload"` + Download int64 `json:"download"` +} diff --git a/rest/service/route.go b/rest/service/route.go new file mode 100644 index 0000000..190af35 --- /dev/null +++ b/rest/service/route.go @@ -0,0 +1,23 @@ +package service + +import ( + "net/http" + + "github.com/gorilla/mux" + + "github.com/sentinel-official/cli-client/context" +) + +func RegisterRoutes(r *mux.Router, ctx *context.Context) *mux.Router { + r.Name("ServiceConnect"). + Methods(http.MethodPost).Path("/connect"). + Handler(HandlerConnect(ctx)) + r.Name("ServiceDisconnect"). + Methods(http.MethodPost).Path("/disconnect"). + Handler(HandlerDisconnect(ctx)) + r.Name("ServiceStatus"). + Methods(http.MethodGet).Path("/status"). + Handler(HandlerStatus(ctx)) + + return r +} diff --git a/types/config/config.go b/types/config/config.go new file mode 100644 index 0000000..ce08cad --- /dev/null +++ b/types/config/config.go @@ -0,0 +1,104 @@ +package config + +import ( + "bytes" + "io/ioutil" + "strings" + "text/template" + + "github.com/pkg/errors" + "github.com/spf13/viper" +) + +var ( + ct = strings.TrimSpace(` +listen_on = "{{ .ListenOn }}" +token = "{{ .Token }}" +version = {{ .Version }} + +[cors] +allowed_origins = "{{ .CORS.AllowedOrigins }}" + +[keyring] +backend = "{{ .Keyring.Backend }}" + `) + + t = func() *template.Template { + t, err := template.New("").Parse(ct) + if err != nil { + panic(err) + } + + return t + }() +) + +type Config struct { + ListenOn string `json:"listen_on" mapstructure:"listen_on"` + Token string `json:"token" mapstructure:"token"` + Version int64 `json:"version" mapstructure:"version"` + CORS *CORSConfig `json:"cors" mapstructure:"cors"` + Keyring *KeyringConfig `json:"keyring" mapstructure:"keyring"` +} + +func NewConfig() *Config { + return &Config{ + CORS: NewCORSConfig(), + Keyring: NewKeyringConfig(), + } +} + +func (c *Config) WithDefaultValues() *Config { + c.ListenOn = "127.0.0.1:9090" + c.Token = "" + c.Version = 1 + + c.CORS = c.CORS.WithDefaultValues() + c.Keyring = c.Keyring.WithDefaultValues() + + return c +} + +func (c *Config) SaveToPath(path string) error { + var buffer bytes.Buffer + if err := t.Execute(&buffer, c); err != nil { + return err + } + + return ioutil.WriteFile(path, buffer.Bytes(), 0600) +} + +func (c *Config) String() string { + var buffer bytes.Buffer + if err := t.Execute(&buffer, c); err != nil { + panic(err) + } + + return buffer.String() +} + +func (c *Config) Validate() error { + if c.ListenOn == "" { + return errors.New("listen_on cannot be empty") + } + if err := c.CORS.Validate(); err != nil { + return errors.Wrapf(err, "invalid section cors") + } + if err := c.Keyring.Validate(); err != nil { + return errors.Wrapf(err, "invalid section keyring") + } + + return nil +} + +func ReadInConfig(v *viper.Viper) (*Config, error) { + cfg := NewConfig().WithDefaultValues() + if err := v.ReadInConfig(); err != nil { + return nil, err + } + if err := v.Unmarshal(cfg); err != nil { + return nil, err + } + + return cfg, nil +} diff --git a/types/config/cors.go b/types/config/cors.go new file mode 100644 index 0000000..575fd2e --- /dev/null +++ b/types/config/cors.go @@ -0,0 +1,19 @@ +package config + +type CORSConfig struct { + AllowedOrigins string `json:"allowed_origins" mapstructure:"allowed_origins"` +} + +func NewCORSConfig() *CORSConfig { + return &CORSConfig{} +} + +func (c *CORSConfig) Validate() error { + return nil +} + +func (c *CORSConfig) WithDefaultValues() *CORSConfig { + c.AllowedOrigins = "*" + + return c +} diff --git a/types/config/keyring.go b/types/config/keyring.go new file mode 100644 index 0000000..739b6f1 --- /dev/null +++ b/types/config/keyring.go @@ -0,0 +1,30 @@ +package config + +import ( + "github.com/pkg/errors" +) + +type KeyringConfig struct { + Backend string `json:"backend" mapstructure:"backend"` +} + +func NewKeyringConfig() *KeyringConfig { + return &KeyringConfig{} +} + +func (c *KeyringConfig) Validate() error { + if c.Backend == "" { + return errors.New("backend cannot be empty") + } + if c.Backend != "os" && c.Backend != "test" { + return errors.New("backend must be either os or test") + } + + return nil +} + +func (c *KeyringConfig) WithDefaultValues() *KeyringConfig { + c.Backend = "os" + + return c +} diff --git a/types/keys.go b/types/keys.go index b36d41b..e38f9a9 100644 --- a/types/keys.go +++ b/types/keys.go @@ -5,6 +5,14 @@ import ( "path/filepath" ) +const ( + APIPathPrefix = "/api/v1" + BuildFolderName = "build" + ConfigFilename = "config.toml" + StatusFilename = "status.json" + TokenLength = 32 +) + var ( DefaultHomeDirectory = func() string { home, err := os.UserHomeDir() diff --git a/types/rest.go b/types/rest.go deleted file mode 100644 index ddc7493..0000000 --- a/types/rest.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -type Response struct { - Success bool `json:"success"` - Error *Error `json:"error,omitempty"` - Result interface{} `json:"result,omitempty"` -} - -type Error struct { - Code int `json:"code"` - Message string `json:"message"` - Module string `json:"module,omitempty"` -} - -func NewError(module string, code int, message string) *Error { - return &Error{ - Code: code, - Message: message, - Module: module, - } -} diff --git a/types/rest/error.go b/types/rest/error.go new file mode 100644 index 0000000..21f2e9d --- /dev/null +++ b/types/rest/error.go @@ -0,0 +1,13 @@ +package rest + +type Error struct { + Code int `json:"code"` + Message string `json:"message"` +} + +func NewError(code int, message string) *Error { + return &Error{ + Code: code, + Message: message, + } +} diff --git a/types/rest/response.go b/types/rest/response.go new file mode 100644 index 0000000..6cebbea --- /dev/null +++ b/types/rest/response.go @@ -0,0 +1,15 @@ +package rest + +type Response struct { + Success bool `json:"success"` + Error *Error `json:"error,omitempty"` + Result interface{} `json:"result,omitempty"` +} + +func NewResponse(e *Error, result interface{}) *Response { + return &Response{ + Success: e == nil, + Error: e, + Result: result, + } +} diff --git a/types/rest/writer.go b/types/rest/writer.go new file mode 100644 index 0000000..c6fd6cc --- /dev/null +++ b/types/rest/writer.go @@ -0,0 +1,35 @@ +package rest + +import ( + "net/http" +) + +type ResponseWriter struct { + http.ResponseWriter + Status int + Length int +} + +func NewResponseWriter(w http.ResponseWriter) *ResponseWriter { + return &ResponseWriter{ + ResponseWriter: w, + Status: 0, + Length: 0, + } +} + +func (r *ResponseWriter) Header() http.Header { + return r.ResponseWriter.Header() +} + +func (r *ResponseWriter) Write(p []byte) (n int, err error) { + n, err = r.ResponseWriter.Write(p) + r.Length += n + + return n, err +} + +func (r *ResponseWriter) WriteHeader(status int) { + r.ResponseWriter.WriteHeader(status) + r.Status = status +} diff --git a/utils/rand/string.go b/utils/rand/string.go new file mode 100644 index 0000000..1c5fd90 --- /dev/null +++ b/utils/rand/string.go @@ -0,0 +1,13 @@ +package rand + +import ( + "crypto/rand" + "encoding/base64" +) + +func RandomStringHex(l int) string { + v := make([]byte, l) + _, _ = rand.Read(v) + + return base64.StdEncoding.EncodeToString(v) +} diff --git a/utils/rest/writer.go b/utils/rest/writer.go new file mode 100644 index 0000000..443fd94 --- /dev/null +++ b/utils/rest/writer.go @@ -0,0 +1,35 @@ +package rest + +import ( + "encoding/json" + "net/http" + + resttypes "github.com/sentinel-official/cli-client/types/rest" +) + +func write(w http.ResponseWriter, status int, resp *resttypes.Response) error { + w.WriteHeader(status) + return json.NewEncoder(w).Encode(resp) +} + +func WriteErrorToResponse(w http.ResponseWriter, status int, result *resttypes.Error) { + _ = write( + w, + status, + resttypes.NewResponse( + result, + nil, + ), + ) +} + +func WriteResultToResponse(w http.ResponseWriter, status int, result interface{}) { + _ = write( + w, + status, + resttypes.NewResponse( + nil, + result, + ), + ) +} diff --git a/x/node/client/cmd/query.go b/x/node/client/cmd/query.go index 12b16ca..fee6b7a 100644 --- a/x/node/client/cmd/query.go +++ b/x/node/client/cmd/query.go @@ -18,6 +18,7 @@ import ( "github.com/spf13/cobra" clienttypes "github.com/sentinel-official/cli-client/types" + resttypes "github.com/sentinel-official/cli-client/types/rest" "github.com/sentinel-official/cli-client/x/node/types" ) @@ -39,7 +40,7 @@ var ( func fetchNodeInfo(remote string, timeout time.Duration) (info types.Info, err error) { var ( - body clienttypes.Response + body resttypes.Response endpoint = strings.Trim(remote, "/") + "/status" httpclient = &http.Client{ Transport: &http.Transport{ From 797d744daab778394411f4459b527d7d72f4a843 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 22 Jul 2021 03:55:11 +0530 Subject: [PATCH 02/18] Added REST API endpoints for keys --- cmd/start.go | 2 + go.mod | 1 + rest/keys/handler.go | 220 ++++++++++++++++++++++++++++++++++++++++++ rest/keys/request.go | 42 ++++++++ rest/keys/route.go | 27 ++++++ rest/service/route.go | 6 +- types/keyring/key.go | 34 +++++++ 7 files changed, 329 insertions(+), 3 deletions(-) create mode 100644 rest/keys/handler.go create mode 100644 rest/keys/request.go create mode 100644 rest/keys/route.go create mode 100644 types/keyring/key.go diff --git a/cmd/start.go b/cmd/start.go index fd9dd1f..133dd07 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -13,6 +13,7 @@ import ( "github.com/sentinel-official/cli-client/context" "github.com/sentinel-official/cli-client/middlewares" + keysrest "github.com/sentinel-official/cli-client/rest/keys" servicerest "github.com/sentinel-official/cli-client/rest/service" "github.com/sentinel-official/cli-client/types" configtypes "github.com/sentinel-official/cli-client/types/config" @@ -59,6 +60,7 @@ func StartCmd() *cobra.Command { Handler(http.FileServer(http.Dir(buildPath))) prefixRouter.Use(middlewares.AddHeaders) + keysrest.RegisterRoutes(prefixRouter, ctx) servicerest.RegisterRoutes(prefixRouter, ctx) router := cors.New( diff --git a/go.mod b/go.mod index 4084c86..8b44d85 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.16 require ( github.com/alessio/shellescape v1.4.1 github.com/cosmos/cosmos-sdk v0.42.5 + github.com/cosmos/go-bip39 v1.0.0 github.com/go-kit/kit v0.10.0 github.com/gorilla/mux v1.8.0 github.com/olekukonko/tablewriter v0.0.5 diff --git a/rest/keys/handler.go b/rest/keys/handler.go new file mode 100644 index 0000000..835f331 --- /dev/null +++ b/rest/keys/handler.go @@ -0,0 +1,220 @@ +package keys + +import ( + "fmt" + "net/http" + "strings" + + "github.com/cosmos/cosmos-sdk/crypto/hd" + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/cosmos-sdk/version" + "github.com/gorilla/mux" + + "github.com/sentinel-official/cli-client/context" + keyringtypes "github.com/sentinel-official/cli-client/types/keyring" + resttypes "github.com/sentinel-official/cli-client/types/rest" + restutils "github.com/sentinel-official/cli-client/utils/rest" +) + +func HandlerGetKey(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + vars = mux.Vars(r) + ) + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1001, err.Error()), + ) + return + } + + key, err := kr.Key(vars["name"]) + if err != nil { + if strings.Contains(err.Error(), "could not be found") { + restutils.WriteErrorToResponse( + w, http.StatusNotFound, + resttypes.NewError(1002, err.Error()), + ) + return + } + + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1002, err.Error()), + ) + return + } + + item := keyringtypes.NewKeyFromRaw(key) + restutils.WriteResultToResponse(w, http.StatusOK, item) + } +} + +func HandlerGetKeys(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + ) + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1001, err.Error()), + ) + return + } + + list, err := kr.List() + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1002, err.Error()), + ) + return + } + + items := keyringtypes.NewKeysFromRaw(list) + restutils.WriteResultToResponse(w, http.StatusOK, items) + } +} + +func HandlerAddKey(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + ) + + request, err := NewRequestAddKey(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := request.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1003, err.Error()), + ) + return + } + + key, _ := kr.Key(request.Name) + if key != nil { + restutils.WriteErrorToResponse( + w, http.StatusConflict, + resttypes.NewError(1004, fmt.Sprintf("key with name %s already exists", request.Name)), + ) + return + } + + var ( + path = hd.CreateHDPath(request.Type, request.Account, request.Index) + algorithms, _ = kr.SupportedAlgorithms() + ) + + algorithm, err := keyring.NewSigningAlgoFromString(string(hd.Secp256k1Type), algorithms) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1005, err.Error()), + ) + return + } + + key, err = kr.NewAccount(request.Name, request.Mnemonic, request.BIP39Password, path.String(), algorithm) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1006, err.Error()), + ) + return + } + + item := keyringtypes.NewKeyFromRaw(key) + restutils.WriteResultToResponse(w, http.StatusCreated, item) + } +} + +func HandlerSignTx(_ *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + } +} + +func HandlerDeleteKey(ctx *context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + vars = mux.Vars(r) + ) + + request, err := NewRequestAddKey(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := request.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1003, err.Error()), + ) + return + } + + if err := kr.Delete(vars["name"]); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1004, err.Error()), + ) + } + + restutils.WriteResultToResponse(w, http.StatusOK, nil) + } +} diff --git a/rest/keys/request.go b/rest/keys/request.go new file mode 100644 index 0000000..3262069 --- /dev/null +++ b/rest/keys/request.go @@ -0,0 +1,42 @@ +package keys + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/cosmos/go-bip39" + "github.com/pkg/errors" +) + +type RequestAddKey struct { + Name string `json:"name"` + Mnemonic string `json:"mnemonic"` + Type uint32 `json:"type"` + Account uint32 `json:"account"` + Index uint32 `json:"index"` + BIP39Password string `json:"bip39_password"` +} + +func NewRequestAddKey(r *http.Request) (*RequestAddKey, error) { + var v RequestAddKey + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *RequestAddKey) Validate() error { + if r.Name == "" { + return errors.New("name cannot be empty") + } + if r.Mnemonic == "" { + return errors.New("mnemonic cannot be empty") + } + if !bip39.IsMnemonicValid(r.Mnemonic) { + return fmt.Errorf("invalid mnemonic %s", r.Mnemonic) + } + + return nil +} diff --git a/rest/keys/route.go b/rest/keys/route.go new file mode 100644 index 0000000..45a7171 --- /dev/null +++ b/rest/keys/route.go @@ -0,0 +1,27 @@ +package keys + +import ( + "net/http" + + "github.com/gorilla/mux" + + "github.com/sentinel-official/cli-client/context" +) + +func RegisterRoutes(r *mux.Router, ctx *context.Context) { + r.Name("GetKey"). + Methods(http.MethodGet).Path("/keys/{name}"). + HandlerFunc(HandlerGetKey(ctx)) + r.Name("GetKeys"). + Methods(http.MethodGet).Path("/keys"). + HandlerFunc(HandlerGetKeys(ctx)) + r.Name("AddKey"). + Methods(http.MethodPost).Path("/keys"). + HandlerFunc(HandlerAddKey(ctx)) + r.Name("SignTx"). + Methods(http.MethodPost).Path("/keys/{name}/sign"). + HandlerFunc(HandlerSignTx(ctx)) + r.Name("DeleteKey"). + Methods(http.MethodDelete).Path("/keys/{name}"). + HandlerFunc(HandlerDeleteKey(ctx)) +} diff --git a/rest/service/route.go b/rest/service/route.go index 190af35..1694d19 100644 --- a/rest/service/route.go +++ b/rest/service/route.go @@ -9,13 +9,13 @@ import ( ) func RegisterRoutes(r *mux.Router, ctx *context.Context) *mux.Router { - r.Name("ServiceConnect"). + r.Name("Connect"). Methods(http.MethodPost).Path("/connect"). Handler(HandlerConnect(ctx)) - r.Name("ServiceDisconnect"). + r.Name("Disconnect"). Methods(http.MethodPost).Path("/disconnect"). Handler(HandlerDisconnect(ctx)) - r.Name("ServiceStatus"). + r.Name("Status"). Methods(http.MethodGet).Path("/status"). Handler(HandlerStatus(ctx)) diff --git a/types/keyring/key.go b/types/keyring/key.go new file mode 100644 index 0000000..fb52712 --- /dev/null +++ b/types/keyring/key.go @@ -0,0 +1,34 @@ +package keyring + +import ( + "encoding/hex" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" +) + +type Key struct { + Name string `json:"name"` + PubKey string `json:"pub_key"` + Address string `json:"address"` +} + +func NewKeyFromRaw(v keyring.Info) Key { + return Key{ + Name: v.GetName(), + PubKey: hex.EncodeToString(v.GetPubKey().Bytes()), + Address: hex.EncodeToString(v.GetAddress().Bytes()), + } +} + +type ( + Keys []Key +) + +func NewKeysFromRaw(v []keyring.Info) Keys { + items := make(Keys, 0, len(v)) + for i := 0; i < len(v); i++ { + items = append(items, NewKeyFromRaw(v[i])) + } + + return items +} From bb1e1852f95f571ac237695a264f132a50469ae8 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 22 Jul 2021 20:21:40 +0530 Subject: [PATCH 03/18] Added sign bytes with key handler --- cmd/start.go | 12 +++++++++-- context/context.go | 10 ++++++--- rest/keys/handler.go | 49 ++++++++++++++++++++++++++++++++++++++++++- rest/keys/response.go | 6 ++++++ rest/keys/route.go | 4 ++-- 5 files changed, 73 insertions(+), 8 deletions(-) create mode 100644 rest/keys/response.go diff --git a/cmd/start.go b/cmd/start.go index 133dd07..18013bb 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -6,8 +6,11 @@ import ( "strings" "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/std" "github.com/gorilla/mux" "github.com/rs/cors" + "github.com/sentinel-official/hub" + hubparams "github.com/sentinel-official/hub/params" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -47,9 +50,14 @@ func StartCmd() *cobra.Command { return err } + encoding := hubparams.MakeEncodingConfig() + std.RegisterInterfaces(encoding.InterfaceRegistry) + hub.ModuleBasics.RegisterInterfaces(encoding.InterfaceRegistry) + var ( ctx = context.NewContext(). - WithConfig(config) + WithConfig(config). + WithEncoding(&encoding) muxRouter = mux.NewRouter() prefixRouter = muxRouter.PathPrefix(types.APIPathPrefix).Subrouter() @@ -66,7 +74,7 @@ func StartCmd() *cobra.Command { router := cors.New( cors.Options{ AllowedOrigins: strings.Split(config.CORS.AllowedOrigins, ","), - AllowedMethods: []string{http.MethodPost}, + AllowedMethods: []string{http.MethodDelete, http.MethodGet, http.MethodPost}, AllowedHeaders: []string{"Content-Type"}, }, ).Handler(muxRouter) diff --git a/context/context.go b/context/context.go index 190cf61..cd58713 100644 --- a/context/context.go +++ b/context/context.go @@ -2,21 +2,25 @@ package context import ( "github.com/cosmos/cosmos-sdk/client/flags" + hubparams "github.com/sentinel-official/hub/params" "github.com/spf13/viper" configtypes "github.com/sentinel-official/cli-client/types/config" ) type Context struct { - config *configtypes.Config + config *configtypes.Config + encoding *hubparams.EncodingConfig } func NewContext() *Context { return &Context{} } -func (c *Context) WithConfig(v *configtypes.Config) *Context { c.config = v; return c } +func (c *Context) WithConfig(v *configtypes.Config) *Context { c.config = v; return c } +func (c *Context) WithEncoding(v *hubparams.EncodingConfig) *Context { c.encoding = v; return c } -func (c *Context) Config() *configtypes.Config { return c.config } +func (c *Context) Config() *configtypes.Config { return c.config } +func (c *Context) Encoding() *hubparams.EncodingConfig { return c.encoding } func (c *Context) Home() string { return viper.GetString(flags.FlagHome) } diff --git a/rest/keys/handler.go b/rest/keys/handler.go index 835f331..a02e263 100644 --- a/rest/keys/handler.go +++ b/rest/keys/handler.go @@ -1,7 +1,9 @@ package keys import ( + "encoding/hex" "fmt" + "io/ioutil" "net/http" "strings" @@ -166,8 +168,53 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { } } -func HandlerSignTx(_ *context.Context) http.HandlerFunc { +func HandlerSignBytes(ctx *context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { + var ( + config = ctx.Config() + vars = mux.Vars(r) + ) + + bytes, err := ioutil.ReadAll(r.Body) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1001, err.Error()), + ) + return + } + + defer r.Body.Close() + + kr, err := keyring.New( + version.Name, + config.Keyring.Backend, + ctx.Home(), + strings.NewReader(""), + ) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1002, err.Error()), + ) + return + } + + signature, pubKey, err := kr.Sign(vars["name"], bytes) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusInternalServerError, + resttypes.NewError(1003, err.Error()), + ) + return + } + + restutils.WriteResultToResponse(w, http.StatusOK, + &ResponseSignTx{ + PubKey: hex.EncodeToString(pubKey.Bytes()), + Signature: signature, + }, + ) } } diff --git a/rest/keys/response.go b/rest/keys/response.go new file mode 100644 index 0000000..d592dc9 --- /dev/null +++ b/rest/keys/response.go @@ -0,0 +1,6 @@ +package keys + +type ResponseSignTx struct { + PubKey string `json:"pub_key"` + Signature []byte `json:"signature"` +} diff --git a/rest/keys/route.go b/rest/keys/route.go index 45a7171..311e3b0 100644 --- a/rest/keys/route.go +++ b/rest/keys/route.go @@ -18,9 +18,9 @@ func RegisterRoutes(r *mux.Router, ctx *context.Context) { r.Name("AddKey"). Methods(http.MethodPost).Path("/keys"). HandlerFunc(HandlerAddKey(ctx)) - r.Name("SignTx"). + r.Name("SignBytes"). Methods(http.MethodPost).Path("/keys/{name}/sign"). - HandlerFunc(HandlerSignTx(ctx)) + HandlerFunc(HandlerSignBytes(ctx)) r.Name("DeleteKey"). Methods(http.MethodDelete).Path("/keys/{name}"). HandlerFunc(HandlerDeleteKey(ctx)) From 4aac23d44c8527eb7827a3c420cb752e669618ba Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Tue, 3 Aug 2021 19:19:45 +0530 Subject: [PATCH 04/18] Removed request body from DeleteKey endpoint --- rest/keys/handler.go | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/rest/keys/handler.go b/rest/keys/handler.go index a02e263..3110279 100644 --- a/rest/keys/handler.go +++ b/rest/keys/handler.go @@ -225,22 +225,6 @@ func HandlerDeleteKey(ctx *context.Context) http.HandlerFunc { vars = mux.Vars(r) ) - request, err := NewRequestAddKey(r) - if err != nil { - restutils.WriteErrorToResponse( - w, http.StatusBadRequest, - resttypes.NewError(1001, err.Error()), - ) - return - } - if err := request.Validate(); err != nil { - restutils.WriteErrorToResponse( - w, http.StatusBadRequest, - resttypes.NewError(1002, err.Error()), - ) - return - } - kr, err := keyring.New( version.Name, config.Keyring.Backend, @@ -250,7 +234,7 @@ func HandlerDeleteKey(ctx *context.Context) http.HandlerFunc { if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1003, err.Error()), + resttypes.NewError(1001, err.Error()), ) return } @@ -258,8 +242,9 @@ func HandlerDeleteKey(ctx *context.Context) http.HandlerFunc { if err := kr.Delete(vars["name"]); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1004, err.Error()), + resttypes.NewError(1002, err.Error()), ) + return } restutils.WriteResultToResponse(w, http.StatusOK, nil) From ba1089c0ea6e5d878ed1dd4bf3606459c01a7a5e Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Tue, 3 Aug 2021 19:21:10 +0530 Subject: [PATCH 05/18] Added missing return statements --- rest/service/handler.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rest/service/handler.go b/rest/service/handler.go index ca931f5..6ee0bc8 100644 --- a/rest/service/handler.go +++ b/rest/service/handler.go @@ -156,6 +156,7 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { w, http.StatusInternalServerError, resttypes.NewError(1008, err.Error()), ) + return } if err := service.PreUp(); err != nil { @@ -163,18 +164,21 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { w, http.StatusInternalServerError, resttypes.NewError(1009, err.Error()), ) + return } if err := service.Up(); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, resttypes.NewError(1010, err.Error()), ) + return } if err := service.PostUp(); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, resttypes.NewError(1011, err.Error()), ) + return } restutils.WriteResultToResponse(w, http.StatusOK, nil) @@ -212,18 +216,21 @@ func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { w, http.StatusInternalServerError, resttypes.NewError(1002, err.Error()), ) + return } if err := service.Down(); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, resttypes.NewError(1003, err.Error()), ) + return } if err := service.PostDown(); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, resttypes.NewError(1004, err.Error()), ) + return } } } @@ -233,6 +240,7 @@ func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { w, http.StatusInternalServerError, resttypes.NewError(1005, err.Error()), ) + return } restutils.WriteResultToResponse(w, http.StatusOK, nil) From 0359421edf63eed0dd53108ad0366db5a311d259 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Fri, 6 Aug 2021 11:51:07 +0530 Subject: [PATCH 06/18] Added server context --- context/server_context.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 context/server_context.go diff --git a/context/server_context.go b/context/server_context.go new file mode 100644 index 0000000..85ba9a8 --- /dev/null +++ b/context/server_context.go @@ -0,0 +1,18 @@ +package context + +type ServerContext struct { + home string +} + +func NewServiceContext() ServerContext { + return ServerContext{} +} + +func (c ServerContext) WithHome(v string) ServerContext { + c.home = v + return c +} + +func (c ServerContext) Home() string { + return c.home +} From b8399610865f4214a990bbdc8469932f415fb983 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Fri, 6 Aug 2021 17:22:34 +0530 Subject: [PATCH 07/18] Changed REST folder structure --- rest/{keys/handler.go => handlers/keyring.go} | 176 +++++++------- .../handler.go => handlers/service.go} | 95 +++----- rest/keys/request.go | 42 ---- rest/keys/response.go | 6 - rest/keys/route.go | 27 --- rest/modules/keyring.go | 29 +++ rest/modules/service.go | 25 ++ rest/requests/keyring.go | 217 ++++++++++++++++++ .../request.go => requests/service.go} | 30 ++- rest/responses/keyring.go | 6 + rest/responses/service.go | 8 + rest/routes/keyring.go | 9 + rest/routes/service.go | 7 + rest/service/response.go | 9 - rest/service/route.go | 23 -- 15 files changed, 460 insertions(+), 249 deletions(-) rename rest/{keys/handler.go => handlers/keyring.go} (56%) rename rest/{service/handler.go => handlers/service.go} (73%) delete mode 100644 rest/keys/request.go delete mode 100644 rest/keys/response.go delete mode 100644 rest/keys/route.go create mode 100644 rest/modules/keyring.go create mode 100644 rest/modules/service.go create mode 100644 rest/requests/keyring.go rename rest/{service/request.go => requests/service.go} (59%) create mode 100644 rest/responses/keyring.go create mode 100644 rest/responses/service.go create mode 100644 rest/routes/keyring.go create mode 100644 rest/routes/service.go delete mode 100644 rest/service/response.go delete mode 100644 rest/service/route.go diff --git a/rest/keys/handler.go b/rest/handlers/keyring.go similarity index 56% rename from rest/keys/handler.go rename to rest/handlers/keyring.go index 3110279..992b203 100644 --- a/rest/keys/handler.go +++ b/rest/handlers/keyring.go @@ -1,57 +1,60 @@ -package keys +package handlers import ( - "encoding/hex" + "encoding/base64" "fmt" - "io/ioutil" "net/http" "strings" "github.com/cosmos/cosmos-sdk/crypto/hd" "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/version" - "github.com/gorilla/mux" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sentinel-official/cli-client/context" + restrequests "github.com/sentinel-official/cli-client/rest/requests" + restresponses "github.com/sentinel-official/cli-client/rest/responses" keyringtypes "github.com/sentinel-official/cli-client/types/keyring" resttypes "github.com/sentinel-official/cli-client/types/rest" restutils "github.com/sentinel-official/cli-client/utils/rest" ) -func HandlerGetKey(ctx *context.Context) http.HandlerFunc { +func GetKey(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - config = ctx.Config() - vars = mux.Vars(r) - ) + req, err := restrequests.NewGeyKey(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := req.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } kr, err := keyring.New( - version.Name, - config.Keyring.Backend, + sdk.KeyringServiceName(), + req.Backend, ctx.Home(), - strings.NewReader(""), + strings.NewReader(strings.Repeat(req.Password+"\n", 4)), ) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1001, err.Error()), + resttypes.NewError(1003, err.Error()), ) return } - key, err := kr.Key(vars["name"]) + key, err := kr.Key(req.Name) if err != nil { - if strings.Contains(err.Error(), "could not be found") { - restutils.WriteErrorToResponse( - w, http.StatusNotFound, - resttypes.NewError(1002, err.Error()), - ) - return - } - restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1002, err.Error()), + resttypes.NewError(1004, err.Error()), ) return } @@ -61,22 +64,34 @@ func HandlerGetKey(ctx *context.Context) http.HandlerFunc { } } -func HandlerGetKeys(ctx *context.Context) http.HandlerFunc { +func GetKeys(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - config = ctx.Config() - ) + req, err := restrequests.NewGeyKeys(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := req.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } kr, err := keyring.New( - version.Name, - config.Keyring.Backend, + sdk.KeyringServiceName(), + req.Backend, ctx.Home(), - strings.NewReader(""), + strings.NewReader(strings.Repeat(req.Password+"\n", 4)), ) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1001, err.Error()), + resttypes.NewError(1003, err.Error()), ) return } @@ -85,7 +100,7 @@ func HandlerGetKeys(ctx *context.Context) http.HandlerFunc { if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1002, err.Error()), + resttypes.NewError(1004, err.Error()), ) return } @@ -95,13 +110,9 @@ func HandlerGetKeys(ctx *context.Context) http.HandlerFunc { } } -func HandlerAddKey(ctx *context.Context) http.HandlerFunc { +func AddKey(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - config = ctx.Config() - ) - - request, err := NewRequestAddKey(r) + req, err := restrequests.NewAddKey(r) if err != nil { restutils.WriteErrorToResponse( w, http.StatusBadRequest, @@ -109,7 +120,7 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { ) return } - if err := request.Validate(); err != nil { + if err := req.Validate(); err != nil { restutils.WriteErrorToResponse( w, http.StatusBadRequest, resttypes.NewError(1002, err.Error()), @@ -118,10 +129,10 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { } kr, err := keyring.New( - version.Name, - config.Keyring.Backend, + sdk.KeyringServiceName(), + req.Backend, ctx.Home(), - strings.NewReader(""), + strings.NewReader(strings.Repeat(req.Password+"\n", 4)), ) if err != nil { restutils.WriteErrorToResponse( @@ -131,17 +142,17 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { return } - key, _ := kr.Key(request.Name) + key, _ := kr.Key(req.Name) if key != nil { restutils.WriteErrorToResponse( w, http.StatusConflict, - resttypes.NewError(1004, fmt.Sprintf("key with name %s already exists", request.Name)), + resttypes.NewError(1004, fmt.Sprintf("key with name %s already exists", req.Name)), ) return } var ( - path = hd.CreateHDPath(request.Type, request.Account, request.Index) + path = hd.CreateHDPath(req.CoinType, req.Account, req.Index) algorithms, _ = kr.SupportedAlgorithms() ) @@ -154,7 +165,7 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { return } - key, err = kr.NewAccount(request.Name, request.Mnemonic, request.BIP39Password, path.String(), algorithm) + key, err = kr.NewAccount(req.Name, req.Mnemonic, req.BIP39Password, path.String(), algorithm) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, @@ -168,81 +179,92 @@ func HandlerAddKey(ctx *context.Context) http.HandlerFunc { } } -func HandlerSignBytes(ctx *context.Context) http.HandlerFunc { +func SignBytes(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - config = ctx.Config() - vars = mux.Vars(r) - ) - - bytes, err := ioutil.ReadAll(r.Body) + req, err := restrequests.NewSignBytes(r) if err != nil { restutils.WriteErrorToResponse( - w, http.StatusInternalServerError, + w, http.StatusBadRequest, resttypes.NewError(1001, err.Error()), ) return } - - defer r.Body.Close() + if err := req.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } kr, err := keyring.New( - version.Name, - config.Keyring.Backend, + sdk.KeyringServiceName(), + req.Backend, ctx.Home(), - strings.NewReader(""), + strings.NewReader(strings.Repeat(req.Password+"\n", 4)), ) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1002, err.Error()), + resttypes.NewError(1003, err.Error()), ) return } - signature, pubKey, err := kr.Sign(vars["name"], bytes) + signature, pubKey, err := kr.Sign(req.Name, req.Bytes) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1003, err.Error()), + resttypes.NewError(1004, err.Error()), ) return } restutils.WriteResultToResponse(w, http.StatusOK, - &ResponseSignTx{ - PubKey: hex.EncodeToString(pubKey.Bytes()), - Signature: signature, + &restresponses.SignBytes{ + PubKey: base64.StdEncoding.EncodeToString(pubKey.Bytes()), + Signature: base64.StdEncoding.EncodeToString(signature), }, ) } } -func HandlerDeleteKey(ctx *context.Context) http.HandlerFunc { +func DeleteKey(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var ( - config = ctx.Config() - vars = mux.Vars(r) - ) + req, err := restrequests.NewDeleteKey(r) + if err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1001, err.Error()), + ) + return + } + if err := req.Validate(); err != nil { + restutils.WriteErrorToResponse( + w, http.StatusBadRequest, + resttypes.NewError(1002, err.Error()), + ) + return + } kr, err := keyring.New( - version.Name, - config.Keyring.Backend, + sdk.KeyringServiceName(), + req.Backend, ctx.Home(), - strings.NewReader(""), + strings.NewReader(strings.Repeat(req.Password+"\n", 4)), ) if err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1001, err.Error()), + resttypes.NewError(1003, err.Error()), ) return } - if err := kr.Delete(vars["name"]); err != nil { + if err := kr.Delete(req.Name); err != nil { restutils.WriteErrorToResponse( w, http.StatusInternalServerError, - resttypes.NewError(1002, err.Error()), + resttypes.NewError(1004, err.Error()), ) return } diff --git a/rest/service/handler.go b/rest/handlers/service.go similarity index 73% rename from rest/service/handler.go rename to rest/handlers/service.go index 6ee0bc8..dafa86e 100644 --- a/rest/service/handler.go +++ b/rest/handlers/service.go @@ -1,4 +1,4 @@ -package service +package handlers import ( "encoding/binary" @@ -7,29 +7,26 @@ import ( "net/http" "os" "path/filepath" - "strings" - - "github.com/cosmos/cosmos-sdk/crypto/keyring" - "github.com/cosmos/cosmos-sdk/version" "github.com/sentinel-official/cli-client/context" + restrequests "github.com/sentinel-official/cli-client/rest/requests" + restresponses "github.com/sentinel-official/cli-client/rest/responses" "github.com/sentinel-official/cli-client/services/wireguard" wireguardtypes "github.com/sentinel-official/cli-client/services/wireguard/types" - "github.com/sentinel-official/cli-client/types" + clitypes "github.com/sentinel-official/cli-client/types" resttypes "github.com/sentinel-official/cli-client/types/rest" netutils "github.com/sentinel-official/cli-client/utils/net" restutils "github.com/sentinel-official/cli-client/utils/rest" ) -func HandlerConnect(ctx *context.Context) http.HandlerFunc { +func Connect(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( - config = ctx.Config() - status = types.NewStatus() - statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + status = clitypes.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), clitypes.StatusFilename) ) - request, err := NewRequestConnect(r) + req, err := restrequests.NewConnect(r) if err != nil { restutils.WriteErrorToResponse( w, http.StatusBadRequest, @@ -37,7 +34,7 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { ) return } - if err := request.Validate(); err != nil { + if err := req.Validate(); err != nil { restutils.WriteErrorToResponse( w, http.StatusBadRequest, resttypes.NewError(1002, err.Error()), @@ -60,41 +57,19 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { &wireguardtypes.Config{ Name: status.IFace, }, - ) + ). + WithHome(ctx.Home()) ) if service.IsUp() { restutils.WriteErrorToResponse( w, http.StatusBadRequest, - resttypes.NewError(1004, fmt.Sprintf("service is already running in interface %s", status.IFace)), + resttypes.NewError(1004, fmt.Sprintf("service is already running on interface %s", status.IFace)), ) return } } - kr, err := keyring.New( - version.Name, - config.Keyring.Backend, - ctx.Home(), - strings.NewReader(""), - ) - if err != nil { - restutils.WriteErrorToResponse( - w, http.StatusInternalServerError, - resttypes.NewError(1005, err.Error()), - ) - return - } - - key, err := kr.Key(request.From) - if err != nil { - restutils.WriteErrorToResponse( - w, http.StatusInternalServerError, - resttypes.NewError(1006, err.Error()), - ) - return - } - listenPort, err := netutils.GetFreeUDPPort() if err != nil { restutils.WriteErrorToResponse( @@ -110,31 +85,31 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { Interface: wireguardtypes.Interface{ Addresses: []wireguardtypes.IPNet{ { - IP: net.IP(request.Info[0 : 0+4]), + IP: net.IP(req.Info[0 : 0+4]), Net: 32, }, { - IP: net.IP(request.Info[4 : 4+16]), + IP: net.IP(req.Info[4 : 4+16]), Net: 128, }, }, ListenPort: listenPort, - PrivateKey: *wireguardtypes.NewKey(request.Keys[0]), + PrivateKey: *wireguardtypes.NewKey(req.Keys[0]), DNS: append( []net.IP{net.ParseIP("10.8.0.1")}, - request.Resolvers..., + req.Resolvers..., ), }, Peers: []wireguardtypes.Peer{ { - PublicKey: *wireguardtypes.NewKey(request.Info[26 : 26+32]), + PublicKey: *wireguardtypes.NewKey(req.Info[26 : 26+32]), AllowedIPs: []wireguardtypes.IPNet{ {IP: net.ParseIP("0.0.0.0")}, {IP: net.ParseIP("::")}, }, Endpoint: wireguardtypes.Endpoint{ - Host: net.IP(request.Info[20 : 20+4]).String(), - Port: binary.BigEndian.Uint16(request.Info[24 : 24+2]), + Host: net.IP(req.Info[20 : 20+4]).String(), + Port: binary.BigEndian.Uint16(req.Info[24 : 24+2]), }, PersistentKeepalive: 15, }, @@ -142,13 +117,12 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { } service = wireguard.NewWireGuard(). - WithConfig(wireGuardConfig) + WithConfig(wireGuardConfig). + WithHome(ctx.Home()) ) - status = status. - WithID(request.ID). - WithFrom(key.GetAddress().String()). - WithTo(request.To). + status = clitypes.NewStatus(). + WithID(req.ID). WithIFace(wireGuardConfig.Name) if err := status.SaveToPath(statusFilePath); err != nil { @@ -185,11 +159,11 @@ func HandlerConnect(ctx *context.Context) http.HandlerFunc { } } -func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { +func Disconnect(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( - status = types.NewStatus() - statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + status = clitypes.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), clitypes.StatusFilename) ) if err := status.LoadFromPath(statusFilePath); err != nil { @@ -207,7 +181,8 @@ func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { &wireguardtypes.Config{ Name: status.IFace, }, - ) + ). + WithHome(ctx.Home()) ) if service.IsUp() { @@ -247,11 +222,11 @@ func HandlerDisconnect(ctx *context.Context) http.HandlerFunc { } } -func HandlerStatus(ctx *context.Context) http.HandlerFunc { +func GetStatus(ctx *context.ServerContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var ( - status = types.NewStatus() - statusFilePath = filepath.Join(ctx.Home(), types.StatusFilename) + status = clitypes.NewStatus() + statusFilePath = filepath.Join(ctx.Home(), clitypes.StatusFilename) ) if err := status.LoadFromPath(statusFilePath); err != nil { @@ -269,7 +244,8 @@ func HandlerStatus(ctx *context.Context) http.HandlerFunc { &wireguardtypes.Config{ Name: status.IFace, }, - ) + ). + WithHome(ctx.Home()) ) if service.IsUp() { @@ -283,10 +259,9 @@ func HandlerStatus(ctx *context.Context) http.HandlerFunc { } restutils.WriteResultToResponse(w, http.StatusOK, - &ResponseStatus{ - From: status.From, + &restresponses.GetStatus{ ID: status.ID, - To: status.To, + IFace: status.IFace, Upload: upload, Download: download, }, diff --git a/rest/keys/request.go b/rest/keys/request.go deleted file mode 100644 index 3262069..0000000 --- a/rest/keys/request.go +++ /dev/null @@ -1,42 +0,0 @@ -package keys - -import ( - "encoding/json" - "fmt" - "net/http" - - "github.com/cosmos/go-bip39" - "github.com/pkg/errors" -) - -type RequestAddKey struct { - Name string `json:"name"` - Mnemonic string `json:"mnemonic"` - Type uint32 `json:"type"` - Account uint32 `json:"account"` - Index uint32 `json:"index"` - BIP39Password string `json:"bip39_password"` -} - -func NewRequestAddKey(r *http.Request) (*RequestAddKey, error) { - var v RequestAddKey - if err := json.NewDecoder(r.Body).Decode(&v); err != nil { - return nil, err - } - - return &v, nil -} - -func (r *RequestAddKey) Validate() error { - if r.Name == "" { - return errors.New("name cannot be empty") - } - if r.Mnemonic == "" { - return errors.New("mnemonic cannot be empty") - } - if !bip39.IsMnemonicValid(r.Mnemonic) { - return fmt.Errorf("invalid mnemonic %s", r.Mnemonic) - } - - return nil -} diff --git a/rest/keys/response.go b/rest/keys/response.go deleted file mode 100644 index d592dc9..0000000 --- a/rest/keys/response.go +++ /dev/null @@ -1,6 +0,0 @@ -package keys - -type ResponseSignTx struct { - PubKey string `json:"pub_key"` - Signature []byte `json:"signature"` -} diff --git a/rest/keys/route.go b/rest/keys/route.go deleted file mode 100644 index 311e3b0..0000000 --- a/rest/keys/route.go +++ /dev/null @@ -1,27 +0,0 @@ -package keys - -import ( - "net/http" - - "github.com/gorilla/mux" - - "github.com/sentinel-official/cli-client/context" -) - -func RegisterRoutes(r *mux.Router, ctx *context.Context) { - r.Name("GetKey"). - Methods(http.MethodGet).Path("/keys/{name}"). - HandlerFunc(HandlerGetKey(ctx)) - r.Name("GetKeys"). - Methods(http.MethodGet).Path("/keys"). - HandlerFunc(HandlerGetKeys(ctx)) - r.Name("AddKey"). - Methods(http.MethodPost).Path("/keys"). - HandlerFunc(HandlerAddKey(ctx)) - r.Name("SignBytes"). - Methods(http.MethodPost).Path("/keys/{name}/sign"). - HandlerFunc(HandlerSignBytes(ctx)) - r.Name("DeleteKey"). - Methods(http.MethodDelete).Path("/keys/{name}"). - HandlerFunc(HandlerDeleteKey(ctx)) -} diff --git a/rest/modules/keyring.go b/rest/modules/keyring.go new file mode 100644 index 0000000..e157fcc --- /dev/null +++ b/rest/modules/keyring.go @@ -0,0 +1,29 @@ +package modules + +import ( + "net/http" + + "github.com/gorilla/mux" + + "github.com/sentinel-official/cli-client/context" + "github.com/sentinel-official/cli-client/rest/handlers" + "github.com/sentinel-official/cli-client/rest/routes" +) + +func RegisterKeyring(r *mux.Router, ctx *context.ServerContext) { + r.Name(routes.GetKey). + Methods(http.MethodPost).Path(routes.GetKey). + HandlerFunc(handlers.GetKey(ctx)) + r.Name(routes.GetKeys). + Methods(http.MethodPost).Path(routes.GetKeys). + HandlerFunc(handlers.GetKeys(ctx)) + r.Name(routes.AddKey). + Methods(http.MethodPost).Path(routes.AddKey). + HandlerFunc(handlers.AddKey(ctx)) + r.Name(routes.SignBytes). + Methods(http.MethodPost).Path(routes.SignBytes). + HandlerFunc(handlers.SignBytes(ctx)) + r.Name(routes.Delete). + Methods(http.MethodPost).Path(routes.Delete). + HandlerFunc(handlers.DeleteKey(ctx)) +} diff --git a/rest/modules/service.go b/rest/modules/service.go new file mode 100644 index 0000000..9ca94d9 --- /dev/null +++ b/rest/modules/service.go @@ -0,0 +1,25 @@ +package modules + +import ( + "net/http" + + "github.com/gorilla/mux" + + "github.com/sentinel-official/cli-client/context" + "github.com/sentinel-official/cli-client/rest/handlers" + "github.com/sentinel-official/cli-client/rest/routes" +) + +func RegisterService(r *mux.Router, ctx *context.ServerContext) *mux.Router { + r.Name(routes.Connect). + Methods(http.MethodPost).Path(routes.Connect). + Handler(handlers.Connect(ctx)) + r.Name(routes.Disconnect). + Methods(http.MethodPost).Path(routes.Disconnect). + Handler(handlers.Disconnect(ctx)) + r.Name(routes.GetStatus). + Methods(http.MethodPost).Path(routes.GetStatus). + Handler(handlers.GetStatus(ctx)) + + return r +} diff --git a/rest/requests/keyring.go b/rest/requests/keyring.go new file mode 100644 index 0000000..2e49218 --- /dev/null +++ b/rest/requests/keyring.go @@ -0,0 +1,217 @@ +package requests + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/cosmos/go-bip39" + "github.com/pkg/errors" +) + +type GeyKey struct { + Backend string `json:"backend"` + Password string `json:"password"` + + Name string `json:"name"` +} + +func NewGeyKey(r *http.Request) (*GeyKey, error) { + var v GeyKey + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *GeyKey) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + + if r.Name == "" { + return errors.New("name cannot be empty") + } + + return nil +} + +type GeyKeys struct { + Backend string ` json:"backend"` + Password string `json:"password"` +} + +func NewGeyKeys(r *http.Request) (*GeyKeys, error) { + var v GeyKeys + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *GeyKeys) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + + return nil +} + +type SignBytes struct { + Backend string `json:"backend"` + Password string `json:"password"` + + Name string `json:"name"` + Bytes []byte `json:"bytes"` +} + +func NewSignBytes(r *http.Request) (*SignBytes, error) { + var v SignBytes + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *SignBytes) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + + if r.Name == "" { + return errors.New("name cannot be empty") + } + + return nil +} + +type AddKey struct { + Backend string `json:"backend"` + Password string `json:"password"` + + Name string `json:"name"` + Mnemonic string `json:"mnemonic"` + CoinType uint32 `json:"coin_type"` + Account uint32 `json:"account"` + Index uint32 `json:"index"` + BIP39Password string `json:"bip39_password"` +} + +func NewAddKey(r *http.Request) (*AddKey, error) { + var v AddKey + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *AddKey) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + + if r.Name == "" { + return errors.New("name cannot be empty") + } + if r.Mnemonic == "" { + return errors.New("mnemonic cannot be empty") + } + if !bip39.IsMnemonicValid(r.Mnemonic) { + return fmt.Errorf("invalid mnemonic %s", r.Mnemonic) + } + + return nil +} + +type DeleteKey struct { + Backend string `json:"backend"` + Password string `json:"password"` + + Name string `json:"name"` +} + +func NewDeleteKey(r *http.Request) (*DeleteKey, error) { + var v DeleteKey + if err := json.NewDecoder(r.Body).Decode(&v); err != nil { + return nil, err + } + + return &v, nil +} + +func (r *DeleteKey) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + + if r.Name == "" { + return errors.New("name cannot be empty") + } + + return nil +} diff --git a/rest/service/request.go b/rest/requests/service.go similarity index 59% rename from rest/service/request.go rename to rest/requests/service.go index 9469718..ed3d517 100644 --- a/rest/service/request.go +++ b/rest/requests/service.go @@ -1,4 +1,4 @@ -package service +package requests import ( "encoding/json" @@ -6,11 +6,15 @@ import ( "net" "net/http" + "github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/pkg/errors" hubtypes "github.com/sentinel-official/hub/types" ) -type RequestConnect struct { +type Connect struct { + Backend string `json:"backend"` + Password string `json:"password"` + ID uint64 `json:"id"` From string `json:"from"` To string `json:"to"` @@ -20,8 +24,8 @@ type RequestConnect struct { Resolvers []net.IP `json:"resolvers"` } -func NewRequestConnect(r *http.Request) (*RequestConnect, error) { - var v RequestConnect +func NewConnect(r *http.Request) (*Connect, error) { + var v Connect if err := json.NewDecoder(r.Body).Decode(&v); err != nil { return nil, err } @@ -29,7 +33,23 @@ func NewRequestConnect(r *http.Request) (*RequestConnect, error) { return &v, nil } -func (r *RequestConnect) Validate() error { +func (r *Connect) Validate() error { + if r.Backend == "" { + return errors.New("backend cannot be empty") + } + if r.Backend != keyring.BackendFile && r.Backend != keyring.BackendOS && r.Backend != keyring.BackendTest { + return fmt.Errorf("backend must be one of [%s, %s, %s]", + keyring.BackendFile, keyring.BackendOS, keyring.BackendTest) + } + if r.Backend == keyring.BackendFile { + if r.Password == "" { + return errors.New("password cannot be empty") + } + if len(r.Password) < 8 { + return fmt.Errorf("password length cannot be less than %d", 8) + } + } + if r.ID == 0 { return errors.New("id cannot be zero") } diff --git a/rest/responses/keyring.go b/rest/responses/keyring.go new file mode 100644 index 0000000..78d8373 --- /dev/null +++ b/rest/responses/keyring.go @@ -0,0 +1,6 @@ +package responses + +type SignBytes struct { + PubKey string `json:"pub_key"` + Signature string `json:"signature"` +} diff --git a/rest/responses/service.go b/rest/responses/service.go new file mode 100644 index 0000000..760e3cb --- /dev/null +++ b/rest/responses/service.go @@ -0,0 +1,8 @@ +package responses + +type GetStatus struct { + ID uint64 `json:"id"` + IFace string `json:"iface"` + Upload int64 `json:"upload"` + Download int64 `json:"download"` +} diff --git a/rest/routes/keyring.go b/rest/routes/keyring.go new file mode 100644 index 0000000..d8c3a33 --- /dev/null +++ b/rest/routes/keyring.go @@ -0,0 +1,9 @@ +package routes + +const ( + AddKey = "/Keys.AddKey" + Delete = "/Keys.DeleteKey" + GetKey = "/Keys.GetKey" + GetKeys = "/Keys.GetKeys" + SignBytes = "/Keys.SignBytes" +) diff --git a/rest/routes/service.go b/rest/routes/service.go new file mode 100644 index 0000000..690392d --- /dev/null +++ b/rest/routes/service.go @@ -0,0 +1,7 @@ +package routes + +const ( + Connect = "/Service.Connect" + Disconnect = "/Service.Disconnect" + GetStatus = "/Service.GetStatus" +) diff --git a/rest/service/response.go b/rest/service/response.go deleted file mode 100644 index f1b900d..0000000 --- a/rest/service/response.go +++ /dev/null @@ -1,9 +0,0 @@ -package service - -type ResponseStatus struct { - From string `json:"from"` - ID uint64 `json:"id"` - To string `json:"to"` - Upload int64 `json:"upload"` - Download int64 `json:"download"` -} diff --git a/rest/service/route.go b/rest/service/route.go deleted file mode 100644 index 1694d19..0000000 --- a/rest/service/route.go +++ /dev/null @@ -1,23 +0,0 @@ -package service - -import ( - "net/http" - - "github.com/gorilla/mux" - - "github.com/sentinel-official/cli-client/context" -) - -func RegisterRoutes(r *mux.Router, ctx *context.Context) *mux.Router { - r.Name("Connect"). - Methods(http.MethodPost).Path("/connect"). - Handler(HandlerConnect(ctx)) - r.Name("Disconnect"). - Methods(http.MethodPost).Path("/disconnect"). - Handler(HandlerDisconnect(ctx)) - r.Name("Status"). - Methods(http.MethodGet).Path("/status"). - Handler(HandlerStatus(ctx)) - - return r -} From 6f48c1dba836b7bdb9b18d00179b5672f69c795e Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Sat, 7 Aug 2021 14:54:51 +0530 Subject: [PATCH 08/18] Moved middlewares to rest folder --- {middlewares => rest/middlewares}/header.go | 0 {middlewares => rest/middlewares}/log.go | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {middlewares => rest/middlewares}/header.go (100%) rename {middlewares => rest/middlewares}/log.go (100%) diff --git a/middlewares/header.go b/rest/middlewares/header.go similarity index 100% rename from middlewares/header.go rename to rest/middlewares/header.go diff --git a/middlewares/log.go b/rest/middlewares/log.go similarity index 100% rename from middlewares/log.go rename to rest/middlewares/log.go From f23b47445e41b2be3e406032427b6e8003a10dc9 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Sat, 7 Aug 2021 15:13:21 +0530 Subject: [PATCH 09/18] Removed configuration --- types/config/config.go | 104 ---------------------------------------- types/config/cors.go | 19 -------- types/config/keyring.go | 30 ------------ 3 files changed, 153 deletions(-) delete mode 100644 types/config/config.go delete mode 100644 types/config/cors.go delete mode 100644 types/config/keyring.go diff --git a/types/config/config.go b/types/config/config.go deleted file mode 100644 index ce08cad..0000000 --- a/types/config/config.go +++ /dev/null @@ -1,104 +0,0 @@ -package config - -import ( - "bytes" - "io/ioutil" - "strings" - "text/template" - - "github.com/pkg/errors" - "github.com/spf13/viper" -) - -var ( - ct = strings.TrimSpace(` -listen_on = "{{ .ListenOn }}" -token = "{{ .Token }}" -version = {{ .Version }} - -[cors] -allowed_origins = "{{ .CORS.AllowedOrigins }}" - -[keyring] -backend = "{{ .Keyring.Backend }}" - `) - - t = func() *template.Template { - t, err := template.New("").Parse(ct) - if err != nil { - panic(err) - } - - return t - }() -) - -type Config struct { - ListenOn string `json:"listen_on" mapstructure:"listen_on"` - Token string `json:"token" mapstructure:"token"` - Version int64 `json:"version" mapstructure:"version"` - CORS *CORSConfig `json:"cors" mapstructure:"cors"` - Keyring *KeyringConfig `json:"keyring" mapstructure:"keyring"` -} - -func NewConfig() *Config { - return &Config{ - CORS: NewCORSConfig(), - Keyring: NewKeyringConfig(), - } -} - -func (c *Config) WithDefaultValues() *Config { - c.ListenOn = "127.0.0.1:9090" - c.Token = "" - c.Version = 1 - - c.CORS = c.CORS.WithDefaultValues() - c.Keyring = c.Keyring.WithDefaultValues() - - return c -} - -func (c *Config) SaveToPath(path string) error { - var buffer bytes.Buffer - if err := t.Execute(&buffer, c); err != nil { - return err - } - - return ioutil.WriteFile(path, buffer.Bytes(), 0600) -} - -func (c *Config) String() string { - var buffer bytes.Buffer - if err := t.Execute(&buffer, c); err != nil { - panic(err) - } - - return buffer.String() -} - -func (c *Config) Validate() error { - if c.ListenOn == "" { - return errors.New("listen_on cannot be empty") - } - if err := c.CORS.Validate(); err != nil { - return errors.Wrapf(err, "invalid section cors") - } - if err := c.Keyring.Validate(); err != nil { - return errors.Wrapf(err, "invalid section keyring") - } - - return nil -} - -func ReadInConfig(v *viper.Viper) (*Config, error) { - cfg := NewConfig().WithDefaultValues() - if err := v.ReadInConfig(); err != nil { - return nil, err - } - if err := v.Unmarshal(cfg); err != nil { - return nil, err - } - - return cfg, nil -} diff --git a/types/config/cors.go b/types/config/cors.go deleted file mode 100644 index 575fd2e..0000000 --- a/types/config/cors.go +++ /dev/null @@ -1,19 +0,0 @@ -package config - -type CORSConfig struct { - AllowedOrigins string `json:"allowed_origins" mapstructure:"allowed_origins"` -} - -func NewCORSConfig() *CORSConfig { - return &CORSConfig{} -} - -func (c *CORSConfig) Validate() error { - return nil -} - -func (c *CORSConfig) WithDefaultValues() *CORSConfig { - c.AllowedOrigins = "*" - - return c -} diff --git a/types/config/keyring.go b/types/config/keyring.go deleted file mode 100644 index 739b6f1..0000000 --- a/types/config/keyring.go +++ /dev/null @@ -1,30 +0,0 @@ -package config - -import ( - "github.com/pkg/errors" -) - -type KeyringConfig struct { - Backend string `json:"backend" mapstructure:"backend"` -} - -func NewKeyringConfig() *KeyringConfig { - return &KeyringConfig{} -} - -func (c *KeyringConfig) Validate() error { - if c.Backend == "" { - return errors.New("backend cannot be empty") - } - if c.Backend != "os" && c.Backend != "test" { - return errors.New("backend must be either os or test") - } - - return nil -} - -func (c *KeyringConfig) WithDefaultValues() *KeyringConfig { - c.Backend = "os" - - return c -} From eecb84609eb5c47ceccfafcaedc86dad3f4e643e Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Mon, 9 Aug 2021 18:15:52 +0530 Subject: [PATCH 10/18] Added client, query and tx contexts --- context/client_context.go | 551 ++++++++++++++++++++++++++++++++++++++ context/context.go | 26 -- context/query_context.go | 466 ++++++++++++++++++++++++++++++++ context/tx_context.go | 79 ++++++ 4 files changed, 1096 insertions(+), 26 deletions(-) create mode 100644 context/client_context.go delete mode 100644 context/context.go create mode 100644 context/query_context.go create mode 100644 context/tx_context.go diff --git a/context/client_context.go b/context/client_context.go new file mode 100644 index 0000000..5c93f39 --- /dev/null +++ b/context/client_context.go @@ -0,0 +1,551 @@ +package context + +import ( + "bufio" + "bytes" + "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" + "net" + "net/http" + "path/filepath" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/go-kit/kit/transport/http/jsonrpc" + "github.com/spf13/cobra" + + restrequests "github.com/sentinel-official/cli-client/rest/requests" + restresponses "github.com/sentinel-official/cli-client/rest/responses" + restroutes "github.com/sentinel-official/cli-client/rest/routes" + clitypes "github.com/sentinel-official/cli-client/types" + keyringtypes "github.com/sentinel-official/cli-client/types/keyring" + resttypes "github.com/sentinel-official/cli-client/types/rest" + fileutils "github.com/sentinel-official/cli-client/utils/file" + keyringutils "github.com/sentinel-official/cli-client/utils/keyring" +) + +func PrepareHTTPClientFromCmd(cmd *cobra.Command) (c http.Client, err error) { + timeout, err := cmd.Flags().GetDuration(clitypes.FlagTimeout) + if err != nil { + return c, err + } + + return http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + }, + Timeout: timeout, + }, nil +} + +type ClientContext struct { + http.Client + TxContext + KeyringBackend string + KeyringHome string + KeyringURL string + ServiceHome string + ServiceURL string +} + +func NewClientContextFromCmd(cmd *cobra.Command) (ctx ClientContext, err error) { + ctx.Client, err = PrepareHTTPClientFromCmd(cmd) + if err != nil { + return ctx, err + } + + ctx.TxContext, err = NewTxContextFromCmd(cmd) + if err != nil { + return ctx, err + } + + ctx.KeyringBackend, err = cmd.Flags().GetString(clitypes.FlagKeyringBackend) + if err != nil { + return ctx, err + } + + ctx.KeyringHome, err = cmd.Flags().GetString(clitypes.FlagKeyringHome) + if err != nil { + return ctx, err + } + + ctx.KeyringURL, err = fileutils.ReadLine(filepath.Join(ctx.KeyringHome, "url.txt")) + if err != nil { + return ctx, err + } + + ctx.ServiceHome, err = cmd.Flags().GetString(clitypes.FlagServiceHome) + if err != nil { + return ctx, err + } + + ctx.ServiceURL, err = fileutils.ReadLine(filepath.Join(ctx.ServiceHome, "url.txt")) + if err != nil { + return ctx, err + } + + return ctx, nil +} + +func (c ClientContext) WithHTTPClient(v http.Client) ClientContext { + c.Client = v + return c +} + +func (c ClientContext) WithTxContext(v TxContext) ClientContext { + c.TxContext = v + return c +} + +func (c ClientContext) WithKeyringBackend(v string) ClientContext { + c.KeyringBackend = v + return c +} + +func (c ClientContext) WithKeyringHome(v string) ClientContext { + c.KeyringHome = v + return c +} + +func (c ClientContext) WithKeyringURL(v string) ClientContext { + c.KeyringURL = v + return c +} + +func (c ClientContext) WithServiceHome(v string) ClientContext { + c.ServiceHome = v + return c +} + +func (c ClientContext) WithServiceURL(v string) ClientContext { + c.ServiceURL = v + return c +} + +func (c *ClientContext) ReadPasswordAndGetAddress(r *bufio.Reader, name string) (string, sdk.AccAddress, error) { + password, err := keyringutils.ReadPassword(c.KeyringBackend, r) + if err != nil { + return "", nil, err + } + + address, err := c.GetAddress(password, name) + if err != nil { + return "", nil, err + } + + return password, address, nil +} + +func (c *ClientContext) GetAddress(password, name string) (sdk.AccAddress, error) { + key, err := c.GetKey(password, name) + if err != nil { + return nil, err + } + + address, err := base64.StdEncoding.DecodeString(key.Address) + if err != nil { + return nil, err + } + + return address, nil +} + +func (c *ClientContext) GetKeys(password string) (keyringtypes.Keys, error) { + var ( + resp resttypes.Response + result keyringtypes.Keys + endpoint = c.KeyringURL + restroutes.GetKeys + ) + + buf, err := json.Marshal( + &restrequests.GeyKeys{ + Backend: c.KeyringBackend, + Password: password, + }, + ) + if err != nil { + return nil, err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, err + } + if resp.Error != nil { + return nil, fmt.Errorf(resp.Error.Message) + } + + buf, err = json.Marshal(resp.Result) + if err != nil { + return nil, err + } + if err := json.Unmarshal(buf, &result); err != nil { + return nil, err + } + + return result, nil +} + +func (c *ClientContext) GetKey(password, name string) (*keyringtypes.Key, error) { + var ( + resp resttypes.Response + result keyringtypes.Key + endpoint = c.KeyringURL + restroutes.GetKey + ) + + buf, err := json.Marshal( + &restrequests.GeyKey{ + Backend: c.KeyringBackend, + Password: password, + Name: name, + }, + ) + if err != nil { + return nil, err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, err + } + if resp.Error != nil { + return nil, fmt.Errorf(resp.Error.Message) + } + + buf, err = json.Marshal(resp.Result) + if err != nil { + return nil, err + } + if err := json.Unmarshal(buf, &result); err != nil { + return nil, err + } + + return &result, nil +} + +func (c *ClientContext) AddKey(password, name, mnemonic, bip39Password string, coinType, account, index uint32) (*keyringtypes.Key, error) { + var ( + resp resttypes.Response + result keyringtypes.Key + endpoint = c.KeyringURL + restroutes.AddKey + ) + + buf, err := json.Marshal( + &restrequests.AddKey{ + Backend: c.KeyringBackend, + Password: password, + Name: name, + Mnemonic: mnemonic, + CoinType: coinType, + Account: account, + Index: index, + BIP39Password: bip39Password, + }, + ) + if err != nil { + return nil, err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, err + } + if resp.Error != nil { + return nil, fmt.Errorf(resp.Error.Message) + } + + buf, err = json.Marshal(resp.Result) + if err != nil { + return nil, err + } + if err := json.Unmarshal(buf, &result); err != nil { + return nil, err + } + + return &result, nil +} + +func (c *ClientContext) DeleteKey(password, name string) error { + var ( + resp resttypes.Response + endpoint = c.KeyringURL + restroutes.Delete + ) + + buf, err := json.Marshal( + &restrequests.DeleteKey{ + Backend: c.KeyringBackend, + Password: password, + Name: name, + }, + ) + if err != nil { + return err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return err + } + if resp.Error != nil { + return fmt.Errorf(resp.Error.Message) + } + + return nil +} + +func (c *ClientContext) SignBytes(password, name string, data []byte) (*restresponses.SignBytes, error) { + var ( + resp resttypes.Response + result restresponses.SignBytes + endpoint = c.KeyringURL + restroutes.SignBytes + ) + + buf, err := json.Marshal( + &restrequests.SignBytes{ + Backend: c.KeyringBackend, + Password: password, + Name: name, + Bytes: data, + }, + ) + if err != nil { + return nil, err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, err + } + if resp.Error != nil { + return nil, fmt.Errorf(resp.Error.Message) + } + + buf, err = json.Marshal(resp.Result) + if err != nil { + return nil, err + } + if err := json.Unmarshal(buf, &result); err != nil { + return nil, err + } + + return &result, nil +} + +func (c *ClientContext) GetStatus() (*clitypes.Status, error) { + var ( + resp resttypes.Response + result clitypes.Status + endpoint = c.ServiceURL + restroutes.GetStatus + ) + + r, err := c.Post(endpoint, jsonrpc.ContentType, nil) + if err != nil { + return nil, err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return nil, err + } + if resp.Error != nil { + return nil, fmt.Errorf(resp.Error.Message) + } + + buf, err := json.Marshal(resp.Result) + if err != nil { + return nil, err + } + if err := json.Unmarshal(buf, &result); err != nil { + return nil, err + } + + return &result, nil +} + +func (c *ClientContext) Connect(password, from, to string, id uint64, info []byte, keys [][]byte, resolvers []net.IP) error { + var ( + resp resttypes.Response + endpoint = c.ServiceURL + restroutes.Connect + ) + + buf, err := json.Marshal( + &restrequests.Connect{ + Backend: c.KeyringBackend, + Password: password, + ID: id, + From: from, + To: to, + Info: info, + Keys: keys, + Resolvers: resolvers, + }, + ) + if err != nil { + return err + } + + r, err := c.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { + return err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return err + } + if resp.Error != nil { + return fmt.Errorf(resp.Error.Message) + } + + return nil +} + +func (c *ClientContext) Disconnect() error { + var ( + resp resttypes.Response + endpoint = c.ServiceURL + restroutes.Disconnect + ) + + r, err := c.Post(endpoint, jsonrpc.ContentType, nil) + if err != nil { + return err + } + + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { + return err + } + if resp.Error != nil { + return fmt.Errorf(resp.Error.Message) + } + + return nil +} + +func (c *ClientContext) SignAndBroadcastTx(password string, messages ...sdk.Msg) (*sdk.TxResponse, error) { + from, err := c.GetKey(password, c.From) + if err != nil { + return nil, err + } + + address, err := base64.StdEncoding.DecodeString(from.Address) + if err != nil { + return nil, err + } + + pubKey, err := base64.StdEncoding.DecodeString(from.PubKey) + if err != nil { + return nil, err + } + + account, err := c.QueryAccount(address) + if err != nil { + return nil, err + } + + txb := c.TxConfig.NewTxBuilder() + if err := txb.SetMsgs(messages...); err != nil { + return nil, err + } + + txb.SetGasLimit(c.Gas) + txb.SetMemo(c.Memo) + + if !c.GasPrices.IsZero() { + var ( + gas = sdk.NewDec(int64(c.Gas)) + fees = make(sdk.Coins, len(c.GasPrices)) + ) + + for i, price := range c.GasPrices { + fee := price.Amount.Mul(gas) + fees[i] = sdk.NewCoin(price.Denom, fee.Ceil().RoundInt()) + } + + txb.SetFeeAmount(fees) + } + + var ( + txSignature = txsigning.SignatureV2{ + PubKey: &secp256k1.PubKey{ + Key: pubKey, + }, + Data: &txsigning.SingleSignatureData{ + SignMode: c.TxConfig.SignModeHandler().DefaultMode(), + Signature: nil, + }, + Sequence: account.GetSequence(), + } + ) + + if err := txb.SetSignatures(txSignature); err != nil { + return nil, err + } + + buf, err := c.TxConfig.SignModeHandler().GetSignBytes( + c.TxConfig.SignModeHandler().DefaultMode(), + authsigning.SignerData{ + ChainID: c.ChainID, + AccountNumber: account.GetAccountNumber(), + Sequence: account.GetSequence(), + }, + txb.GetTx(), + ) + if err != nil { + return nil, err + } + + result, err := c.SignBytes(password, c.From, buf) + if err != nil { + return nil, err + } + + signature, err := base64.StdEncoding.DecodeString(result.Signature) + if err != nil { + return nil, err + } + + txSignature.Data = &txsigning.SingleSignatureData{ + SignMode: c.TxConfig.SignModeHandler().DefaultMode(), + Signature: signature, + } + + if err := txb.SetSignatures(txSignature); err != nil { + return nil, err + } + + buf, err = c.TxConfig.TxEncoder()(txb.GetTx()) + if err != nil { + return nil, err + } + + res, err := c.QueryContext.BroadcastTx(buf) + if err != nil { + return nil, err + } + + return res, nil +} diff --git a/context/context.go b/context/context.go deleted file mode 100644 index cd58713..0000000 --- a/context/context.go +++ /dev/null @@ -1,26 +0,0 @@ -package context - -import ( - "github.com/cosmos/cosmos-sdk/client/flags" - hubparams "github.com/sentinel-official/hub/params" - "github.com/spf13/viper" - - configtypes "github.com/sentinel-official/cli-client/types/config" -) - -type Context struct { - config *configtypes.Config - encoding *hubparams.EncodingConfig -} - -func NewContext() *Context { - return &Context{} -} - -func (c *Context) WithConfig(v *configtypes.Config) *Context { c.config = v; return c } -func (c *Context) WithEncoding(v *hubparams.EncodingConfig) *Context { c.encoding = v; return c } - -func (c *Context) Config() *configtypes.Config { return c.config } -func (c *Context) Encoding() *hubparams.EncodingConfig { return c.encoding } - -func (c *Context) Home() string { return viper.GetString(flags.FlagHome) } diff --git a/context/query_context.go b/context/query_context.go new file mode 100644 index 0000000..bbaef43 --- /dev/null +++ b/context/query_context.go @@ -0,0 +1,466 @@ +package context + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/client" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + hubtypes "github.com/sentinel-official/hub/types" + deposittypes "github.com/sentinel-official/hub/x/deposit/types" + nodetypes "github.com/sentinel-official/hub/x/node/types" + plantypes "github.com/sentinel-official/hub/x/plan/types" + providertypes "github.com/sentinel-official/hub/x/provider/types" + sessiontypes "github.com/sentinel-official/hub/x/session/types" + subscriptiontypes "github.com/sentinel-official/hub/x/subscription/types" + "github.com/spf13/cobra" + rpchttp "github.com/tendermint/tendermint/rpc/client/http" + + clitypes "github.com/sentinel-official/cli-client/types" +) + +type QueryContext struct { + client.Context +} + +func NewQueryContextFromCmd(cmd *cobra.Command) (ctx QueryContext, err error) { + ctx.Context = client.GetClientContextFromCmd(cmd) + + ctx.NodeURI, err = cmd.Flags().GetString(clitypes.FlagRPCAddress) + if err != nil { + return ctx, err + } + + ctx.Client, err = rpchttp.New(ctx.NodeURI, "/websocket") + if err != nil { + return ctx, err + } + + return ctx, nil +} + +func (c QueryContext) WithContext(v client.Context) QueryContext { + c.Context = v + return c +} + +func (c *QueryContext) QueryAccount(address sdk.AccAddress) (authtypes.AccountI, error) { + var ( + account authtypes.AccountI + qc = authtypes.NewQueryClient(c) + result, err = qc.Account( + context.Background(), + &authtypes.QueryAccountRequest{ + Address: address.String(), + }, + ) + ) + + if err != nil { + return nil, err + } + if err := c.InterfaceRegistry.UnpackAny(result.Account, &account); err != nil { + return nil, err + } + + return account, nil +} + +func (c *QueryContext) QueryDeposit(address sdk.AccAddress) (*deposittypes.Deposit, error) { + var ( + qsc = deposittypes.NewQueryServiceClient(c) + result, err = qsc.QueryDeposit( + context.Background(), + deposittypes.NewQueryDepositRequest( + address, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Deposit, nil +} + +func (c *QueryContext) QueryDeposits(pagination *query.PageRequest) (deposittypes.Deposits, error) { + var ( + qsc = deposittypes.NewQueryServiceClient(c) + result, err = qsc.QueryDeposits( + context.Background(), + deposittypes.NewQueryDepositsRequest( + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Deposits, nil +} + +func (c *QueryContext) QueryNode(address hubtypes.NodeAddress) (*nodetypes.Node, error) { + var ( + qsc = nodetypes.NewQueryServiceClient(c) + result, err = qsc.QueryNode( + context.Background(), + nodetypes.NewQueryNodeRequest( + address, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Node, nil +} + +func (c *QueryContext) QueryNodes(status hubtypes.Status, pagination *query.PageRequest) (nodetypes.Nodes, error) { + var ( + qsc = nodetypes.NewQueryServiceClient(c) + result, err = qsc.QueryNodes( + context.Background(), + nodetypes.NewQueryNodesRequest( + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Nodes, nil +} + +func (c *QueryContext) QueryNodesForProvider(address hubtypes.ProvAddress, status hubtypes.Status, pagination *query.PageRequest) (nodetypes.Nodes, error) { + var ( + qsc = nodetypes.NewQueryServiceClient(c) + result, err = qsc.QueryNodesForProvider( + context.Background(), + nodetypes.NewQueryNodesForProviderRequest( + address, + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Nodes, nil +} + +func (c *QueryContext) QueryPlan(id uint64) (*plantypes.Plan, error) { + var ( + qsc = plantypes.NewQueryServiceClient(c) + result, err = qsc.QueryPlan( + context.Background(), + plantypes.NewQueryPlanRequest( + id, + ), + ) + ) + if err != nil { + return nil, err + } + + return &result.Plan, nil +} + +func (c *QueryContext) QueryPlans(status hubtypes.Status, pagination *query.PageRequest) (plantypes.Plans, error) { + var ( + qsc = plantypes.NewQueryServiceClient(c) + result, err = qsc.QueryPlans( + context.Background(), + plantypes.NewQueryPlansRequest( + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Plans, nil +} + +func (c *QueryContext) QueryPlansForProvider(address hubtypes.ProvAddress, status hubtypes.Status, pagination *query.PageRequest) (plantypes.Plans, error) { + var ( + qsc = plantypes.NewQueryServiceClient(c) + result, err = qsc.QueryPlansForProvider( + context.Background(), + plantypes.NewQueryPlansForProviderRequest( + address, + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Plans, nil +} + +func (c *QueryContext) QueryProvider(address hubtypes.ProvAddress) (*providertypes.Provider, error) { + var ( + qsc = providertypes.NewQueryServiceClient(c) + result, err = qsc.QueryProvider( + context.Background(), + providertypes.NewQueryProviderRequest( + address, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Provider, nil +} + +func (c *QueryContext) QueryProviders(pagination *query.PageRequest) (providertypes.Providers, error) { + var ( + qsc = providertypes.NewQueryServiceClient(c) + result, err = qsc.QueryProviders( + context.Background(), + providertypes.NewQueryProvidersRequest( + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Providers, nil +} + +func (c *QueryContext) QuerySession(id uint64) (*sessiontypes.Session, error) { + var ( + qsc = sessiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySession( + context.Background(), + sessiontypes.NewQuerySessionRequest( + id, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Session, nil +} + +func (c *QueryContext) QuerySessions(pagination *query.PageRequest) (sessiontypes.Sessions, error) { + var ( + qsc = sessiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySessions( + context.Background(), + sessiontypes.NewQuerySessionsRequest( + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Sessions, nil +} + +func (c *QueryContext) QuerySessionsForSubscription(id uint64, pagination *query.PageRequest) (sessiontypes.Sessions, error) { + var ( + qsc = sessiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySessionsForSubscription( + context.Background(), + sessiontypes.NewQuerySessionsForSubscriptionRequest( + id, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Sessions, nil +} + +func (c *QueryContext) QuerySessionsForAddress(address sdk.AccAddress, status hubtypes.Status, pagination *query.PageRequest) (sessiontypes.Sessions, error) { + var ( + qsc = sessiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySessionsForAddress( + context.Background(), + sessiontypes.NewQuerySessionsForAddressRequest( + address, + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Sessions, nil +} + +func (c *QueryContext) QuerySubscription(id uint64) (*subscriptiontypes.Subscription, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySubscription( + context.Background(), + subscriptiontypes.NewQuerySubscriptionRequest( + id, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Subscription, nil +} + +func (c *QueryContext) QuerySubscriptions(pagination *query.PageRequest) (subscriptiontypes.Subscriptions, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySubscriptions( + context.Background(), + subscriptiontypes.NewQuerySubscriptionsRequest( + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Subscriptions, nil +} + +func (c *QueryContext) QuerySubscriptionsForAddress(address sdk.AccAddress, status hubtypes.Status, pagination *query.PageRequest) (subscriptiontypes.Subscriptions, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySubscriptionsForAddress( + context.Background(), + subscriptiontypes.NewQuerySubscriptionsForAddressRequest( + address, + status, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Subscriptions, nil +} + +func (c *QueryContext) QuerySubscriptionsForPlan(id uint64, pagination *query.PageRequest) (subscriptiontypes.Subscriptions, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySubscriptionsForPlan( + context.Background(), + subscriptiontypes.NewQuerySubscriptionsForPlanRequest( + id, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Subscriptions, nil +} + +func (c *QueryContext) QueryQuota(id uint64, address sdk.AccAddress) (*subscriptiontypes.Quota, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QueryQuota( + context.Background(), + subscriptiontypes.NewQueryQuotaRequest( + id, + address, + ), + ) + ) + + if err != nil { + return nil, err + } + + return &result.Quota, nil +} + +func (c *QueryContext) QueryQuotas(id uint64, pagination *query.PageRequest) (subscriptiontypes.Quotas, error) { + var ( + qsc = subscriptiontypes.NewQueryServiceClient(c) + result, err = qsc.QueryQuotas( + context.Background(), + subscriptiontypes.NewQueryQuotasRequest( + id, + pagination, + ), + ) + ) + + if err != nil { + return nil, err + } + + return result.Quotas, nil +} + +func (c *QueryContext) QueryActiveSession(address sdk.AccAddress) (*sessiontypes.Session, error) { + var ( + qsc = sessiontypes.NewQueryServiceClient(c) + result, err = qsc.QuerySessionsForAddress( + context.Background(), + sessiontypes.NewQuerySessionsForAddressRequest( + address, + hubtypes.StatusActive, + &query.PageRequest{ + Limit: 1, + }, + ), + ) + ) + + if err != nil { + return nil, err + } + if len(result.Sessions) == 0 { + return nil, nil + } + + return &result.Sessions[0], nil +} diff --git a/context/tx_context.go b/context/tx_context.go new file mode 100644 index 0000000..1f15447 --- /dev/null +++ b/context/tx_context.go @@ -0,0 +1,79 @@ +package context + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + + clitypes "github.com/sentinel-official/cli-client/types" +) + +type TxContext struct { + QueryContext + Gas uint64 + GasPrices sdk.DecCoins + Memo string +} + +func NewTxContextFromCmd(cmd *cobra.Command) (ctx TxContext, err error) { + ctx.QueryContext, err = NewQueryContextFromCmd(cmd) + if err != nil { + return ctx, err + } + + ctx.BroadcastMode, err = cmd.Flags().GetString(clitypes.FlagBroadcastMode) + if err != nil { + return ctx, err + } + + ctx.ChainID, err = cmd.Flags().GetString(clitypes.FlagChainID) + if err != nil { + return ctx, err + } + + ctx.From, err = cmd.Flags().GetString(clitypes.FlagFrom) + if err != nil { + return ctx, err + } + + ctx.Gas, err = cmd.Flags().GetUint64(clitypes.FlagGas) + if err != nil { + return ctx, err + } + + s, err := cmd.Flags().GetString(clitypes.FlagGasPrices) + if err != nil { + return ctx, err + } + + ctx.GasPrices, err = sdk.ParseDecCoins(s) + if err != nil { + return ctx, err + } + + ctx.Memo, err = cmd.Flags().GetString(clitypes.FlagMemo) + if err != nil { + return ctx, err + } + + return ctx, nil +} + +func (c TxContext) WithQueryContext(v QueryContext) TxContext { + c.QueryContext = v + return c +} + +func (c TxContext) WithGas(v uint64) TxContext { + c.Gas = v + return c +} + +func (c TxContext) WithGasPrices(v sdk.DecCoins) TxContext { + c.GasPrices = v + return c +} + +func (c TxContext) WithMemo(v string) TxContext { + c.Memo = v + return c +} From 955ce8cf1c5dde712d3bf848f52892aa4efc4629 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Tue, 10 Aug 2021 17:52:06 +0530 Subject: [PATCH 11/18] Updated query commands with Query context --- x/deposit/client/cmd/query.go | 38 ++++------ x/node/client/cmd/query.go | 57 +++++---------- x/plan/client/cmd/query.go | 57 ++++++--------- x/provider/client/cmd/query.go | 38 ++++------ x/session/client/cmd/query.go | 52 +++++-------- x/subscription/client/cmd/query.go | 113 +++++++++++------------------ 6 files changed, 133 insertions(+), 222 deletions(-) diff --git a/x/deposit/client/cmd/query.go b/x/deposit/client/cmd/query.go index f840f40..e7f3ba8 100644 --- a/x/deposit/client/cmd/query.go +++ b/x/deposit/client/cmd/query.go @@ -1,15 +1,14 @@ package cmd import ( - "context" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/olekukonko/tablewriter" - deposittypes "github.com/sentinel-official/hub/x/deposit/types" "github.com/spf13/cobra" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" "github.com/sentinel-official/cli-client/x/deposit/types" ) @@ -26,7 +25,7 @@ func QueryDeposit() *cobra.Command { Short: "Query a deposit", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -36,20 +35,13 @@ func QueryDeposit() *cobra.Command { return err } - var ( - qsc = deposittypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryDeposit( - context.Background(), - deposittypes.NewQueryDepositRequest(address), - ) + result, err := qc.QueryDeposit(address) if err != nil { return err } var ( - item = types.NewDepositFromRaw(&result.Deposit) + item = types.NewDepositFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -66,7 +58,8 @@ func QueryDeposit() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -76,7 +69,7 @@ func QueryDeposits() *cobra.Command { Use: "deposits", Short: "Query deposits", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -86,20 +79,13 @@ func QueryDeposits() *cobra.Command { return err } - var ( - qsc = deposittypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryDeposits( - context.Background(), - deposittypes.NewQueryDepositsRequest(pagination), - ) + result, err := qc.QueryDeposits(pagination) if err != nil { return err } var ( - items = types.NewDepositsFromRaw(result.Deposits) + items = types.NewDepositsFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -118,8 +104,10 @@ func QueryDeposits() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "deposits") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + return cmd } diff --git a/x/node/client/cmd/query.go b/x/node/client/cmd/query.go index fee6b7a..c5b6d52 100644 --- a/x/node/client/cmd/query.go +++ b/x/node/client/cmd/query.go @@ -1,7 +1,6 @@ package cmd import ( - "context" "crypto/tls" "encoding/json" "fmt" @@ -17,7 +16,8 @@ import ( nodetypes "github.com/sentinel-official/hub/x/node/types" "github.com/spf13/cobra" - clienttypes "github.com/sentinel-official/cli-client/types" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" resttypes "github.com/sentinel-official/cli-client/types/rest" "github.com/sentinel-official/cli-client/x/node/types" ) @@ -83,7 +83,7 @@ func QueryNode() *cobra.Command { Short: "Query a node", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -93,26 +93,19 @@ func QueryNode() *cobra.Command { return err } - timeout, err := cmd.Flags().GetDuration(clienttypes.FlagTimeout) + timeout, err := cmd.Flags().GetDuration(clitypes.FlagTimeout) if err != nil { return err } - var ( - qsc = nodetypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryNode( - context.Background(), - nodetypes.NewQueryNodeRequest(address), - ) + result, err := qc.QueryNode(address) if err != nil { return err } var ( - info, _ = fetchNodeInfo(result.Node.RemoteURL, timeout) - item = types.NewNodeFromRaw(&result.Node).WithInfo(info) + info, _ = fetchNodeInfo(result.RemoteURL, timeout) + item = types.NewNodeFromRaw(result).WithInfo(info) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -138,9 +131,7 @@ func QueryNode() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) - - cmd.Flags().Duration(clienttypes.FlagTimeout, 15*time.Second, "time limit for requests made by the HTTP client") + clitypes.AddQueryFlagsToCmd(cmd) return cmd } @@ -150,7 +141,7 @@ func QueryNodes() *cobra.Command { Use: "nodes", Short: "Query nodes", RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -165,7 +156,7 @@ func QueryNodes() *cobra.Command { return err } - timeout, err := cmd.Flags().GetDuration(clienttypes.FlagTimeout) + timeout, err := cmd.Flags().GetDuration(clitypes.FlagTimeout) if err != nil { return err } @@ -177,7 +168,6 @@ func QueryNodes() *cobra.Command { var ( items []nodetypes.Node - qsc = nodetypes.NewQueryServiceClient(ctx) status = hubtypes.StatusFromString(s) ) @@ -187,32 +177,26 @@ func QueryNodes() *cobra.Command { return err } - result, err := qsc.QueryNodesForProvider( - context.Background(), - nodetypes.NewQueryNodesForProviderRequest( - address, - status, - pagination, - ), + result, err := qc.QueryNodesForProvider( + address, + status, + pagination, ) if err != nil { return err } - items = append(items, result.Nodes...) + items = append(items, result...) } else { - result, err := qsc.QueryNodes( - context.Background(), - nodetypes.NewQueryNodesRequest( - status, - pagination, - ), + result, err := qc.QueryNodes( + status, + pagination, ) if err != nil { return err } - items = append(items, result.Nodes...) + items = append(items, result...) } var ( @@ -260,12 +244,11 @@ func QueryNodes() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "nodes") + clitypes.AddQueryFlagsToCmd(cmd) cmd.Flags().String(flagProvider, "", "filter with provider address") cmd.Flags().String(flagStatus, "Active", "filter with status (Active|Inactive)") - cmd.Flags().Duration(clienttypes.FlagTimeout, 15*time.Second, "time limit for requests made by the HTTP client") return cmd } diff --git a/x/plan/client/cmd/query.go b/x/plan/client/cmd/query.go index e25f8a7..608c45a 100644 --- a/x/plan/client/cmd/query.go +++ b/x/plan/client/cmd/query.go @@ -1,7 +1,6 @@ package cmd import ( - "context" "fmt" "strconv" @@ -9,10 +8,11 @@ import ( "github.com/cosmos/cosmos-sdk/client/flags" "github.com/olekukonko/tablewriter" hubtypes "github.com/sentinel-official/hub/types" - plantypes "github.com/sentinel-official/hub/x/plan/types" "github.com/spf13/cobra" - netutil "github.com/sentinel-official/cli-client/utils/net" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" + netutils "github.com/sentinel-official/cli-client/utils/net" "github.com/sentinel-official/cli-client/x/plan/types" ) @@ -33,7 +33,7 @@ func QueryPlan() *cobra.Command { Short: "Query a plan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -43,20 +43,13 @@ func QueryPlan() *cobra.Command { return err } - var ( - qsc = plantypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryPlan( - context.Background(), - plantypes.NewQueryPlanRequest(id), - ) + result, err := qc.QueryPlan(id) if err != nil { return err } var ( - item = types.NewPlanFromRaw(&result.Plan) + item = types.NewPlanFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -66,7 +59,7 @@ func QueryPlan() *cobra.Command { fmt.Sprintf("%d", item.ID), item.Provider, item.Price.Raw().String(), - netutil.ToReadable(item.Bytes, 2), + netutils.ToReadable(item.Bytes, 2), item.Validity.String(), item.Status, }, @@ -77,7 +70,8 @@ func QueryPlan() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -87,7 +81,7 @@ func QueryPlans() *cobra.Command { Use: "plans", Short: "Query plans", RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -109,7 +103,6 @@ func QueryPlans() *cobra.Command { var ( items types.Plans - qsc = plantypes.NewQueryServiceClient(ctx) status = hubtypes.StatusFromString(s) ) @@ -119,32 +112,26 @@ func QueryPlans() *cobra.Command { return err } - result, err := qsc.QueryPlansForProvider( - context.Background(), - plantypes.NewQueryPlansForProviderRequest( - address, - status, - pagination, - ), + result, err := qc.QueryPlansForProvider( + address, + status, + pagination, ) if err != nil { return err } - items = append(items, types.NewPlansFromRaw(result.Plans)...) + items = append(items, types.NewPlansFromRaw(result)...) } else { - result, err := qsc.QueryPlans( - context.Background(), - plantypes.NewQueryPlansRequest( - status, - pagination, - ), + result, err := qc.QueryPlans( + status, + pagination, ) if err != nil { return err } - items = append(items, types.NewPlansFromRaw(result.Plans)...) + items = append(items, types.NewPlansFromRaw(result)...) } table := tablewriter.NewWriter(cmd.OutOrStdout()) @@ -156,7 +143,7 @@ func QueryPlans() *cobra.Command { fmt.Sprintf("%d", items[i].ID), items[i].Provider, items[i].Price.Raw().String(), - netutil.ToReadable(items[i].Bytes, 2), + netutils.ToReadable(items[i].Bytes, 2), items[i].Validity.String(), items[i].Status, }, @@ -168,9 +155,11 @@ func QueryPlans() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "plans") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + cmd.Flags().String(flagProvider, "", "filter with provider address") cmd.Flags().String(flagStatus, "Active", "filter with status") diff --git a/x/provider/client/cmd/query.go b/x/provider/client/cmd/query.go index fb3c6b9..9ddb0b1 100644 --- a/x/provider/client/cmd/query.go +++ b/x/provider/client/cmd/query.go @@ -1,15 +1,14 @@ package cmd import ( - "context" - "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/olekukonko/tablewriter" hubtypes "github.com/sentinel-official/hub/types" - providertypes "github.com/sentinel-official/hub/x/provider/types" "github.com/spf13/cobra" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" "github.com/sentinel-official/cli-client/x/provider/types" ) @@ -28,7 +27,7 @@ func QueryProvider() *cobra.Command { Short: "Query a provider", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -38,20 +37,13 @@ func QueryProvider() *cobra.Command { return err } - var ( - qsc = providertypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryProvider( - context.Background(), - providertypes.NewQueryProviderRequest(address), - ) + result, err := qc.QueryProvider(address) if err != nil { return err } var ( - item = types.NewProviderFromRaw(&result.Provider) + item = types.NewProviderFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -70,7 +62,8 @@ func QueryProvider() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -80,7 +73,7 @@ func QueryProviders() *cobra.Command { Use: "providers", Short: "Query providers", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -90,20 +83,13 @@ func QueryProviders() *cobra.Command { return err } - var ( - qsc = providertypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryProviders( - context.Background(), - providertypes.NewQueryProvidersRequest(pagination), - ) + result, err := qc.QueryProviders(pagination) if err != nil { return err } var ( - items = types.NewProvidersFromRaw(result.Providers) + items = types.NewProvidersFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -124,8 +110,10 @@ func QueryProviders() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "providers") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + return cmd } diff --git a/x/session/client/cmd/query.go b/x/session/client/cmd/query.go index 0eb9bed..5a9bc88 100644 --- a/x/session/client/cmd/query.go +++ b/x/session/client/cmd/query.go @@ -1,7 +1,6 @@ package cmd import ( - "context" "fmt" "strconv" "time" @@ -11,9 +10,10 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/olekukonko/tablewriter" hubtypes "github.com/sentinel-official/hub/types" - sessiontypes "github.com/sentinel-official/hub/x/session/types" "github.com/spf13/cobra" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" "github.com/sentinel-official/cli-client/x/session/types" ) @@ -35,7 +35,7 @@ func QuerySession() *cobra.Command { Short: "Query a session", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -45,20 +45,13 @@ func QuerySession() *cobra.Command { return err } - var ( - qsc = sessiontypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QuerySession( - context.Background(), - sessiontypes.NewQuerySessionRequest(id), - ) + result, err := qc.QuerySession(id) if err != nil { return err } var ( - item = types.NewSessionFromRaw(&result.Session) + item = types.NewSessionFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -80,7 +73,8 @@ func QuerySession() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -90,7 +84,7 @@ func QuerySessions() *cobra.Command { Use: "sessions", Short: "Query sessions", RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -112,22 +106,18 @@ func QuerySessions() *cobra.Command { var ( items types.Sessions - qc = sessiontypes.NewQueryServiceClient(ctx) ) if subscription != 0 { result, err := qc.QuerySessionsForSubscription( - context.Background(), - sessiontypes.NewQuerySessionsForSubscriptionRequest( - subscription, - pagination, - ), + subscription, + pagination, ) if err != nil { return err } - items = append(items, types.NewSessionsFromRaw(result.Sessions)...) + items = append(items, types.NewSessionsFromRaw(result)...) } else if bech32Address != "" { address, err := sdk.AccAddressFromBech32(bech32Address) if err != nil { @@ -140,28 +130,24 @@ func QuerySessions() *cobra.Command { } result, err := qc.QuerySessionsForAddress( - context.Background(), - sessiontypes.NewQuerySessionsForAddressRequest( - address, - hubtypes.StatusFromString(status), - pagination, - ), + address, + hubtypes.StatusFromString(status), + pagination, ) if err != nil { return err } - items = append(items, types.NewSessionsFromRaw(result.Sessions)...) + items = append(items, types.NewSessionsFromRaw(result)...) } else { result, err := qc.QuerySessions( - context.Background(), - sessiontypes.NewQuerySessionsRequest(pagination), + pagination, ) if err != nil { return err } - items = append(items, types.NewSessionsFromRaw(result.Sessions)...) + items = append(items, types.NewSessionsFromRaw(result)...) } table := tablewriter.NewWriter(cmd.OutOrStdout()) @@ -186,9 +172,11 @@ func QuerySessions() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "sessions") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + cmd.Flags().String(flagAddress, "", "filter with account address") cmd.Flags().Uint64(flagSubscription, 0, "filter with subscription identity") cmd.Flags().String(flagStatus, "Active", "filter with status (Active|Inactive)") diff --git a/x/subscription/client/cmd/query.go b/x/subscription/client/cmd/query.go index 95131ca..e8c7253 100644 --- a/x/subscription/client/cmd/query.go +++ b/x/subscription/client/cmd/query.go @@ -1,7 +1,6 @@ package cmd import ( - "context" "fmt" "strconv" @@ -10,10 +9,11 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/olekukonko/tablewriter" hubtypes "github.com/sentinel-official/hub/types" - subscriptiontypes "github.com/sentinel-official/hub/x/subscription/types" "github.com/spf13/cobra" - netutil "github.com/sentinel-official/cli-client/utils/net" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" + netutils "github.com/sentinel-official/cli-client/utils/net" "github.com/sentinel-official/cli-client/x/subscription/types" ) @@ -43,7 +43,7 @@ func QuerySubscription() *cobra.Command { Short: "Query a subscription", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -53,20 +53,13 @@ func QuerySubscription() *cobra.Command { return err } - var ( - qsc = subscriptiontypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QuerySubscription( - context.Background(), - subscriptiontypes.NewQuerySubscriptionRequest(id), - ) + result, err := qc.QuerySubscription(id) if err != nil { return err } var ( - item = types.NewSubscriptionFromRaw(&result.Subscription) + item = types.NewSubscriptionFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -81,7 +74,7 @@ func QuerySubscription() *cobra.Command { item.Node, item.Price.Raw().String(), item.Deposit.Raw().String(), - netutil.ToReadable(item.Free, 2), + netutils.ToReadable(item.Free, 2), item.Status, }, ) @@ -91,7 +84,8 @@ func QuerySubscription() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -101,7 +95,7 @@ func QuerySubscriptions() *cobra.Command { Use: "subscriptions", Short: "Query subscriptions", RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -128,7 +122,6 @@ func QuerySubscriptions() *cobra.Command { var ( items types.Subscriptions - qsc = subscriptiontypes.NewQueryServiceClient(ctx) ) if bech32Address != "" { @@ -137,42 +130,33 @@ func QuerySubscriptions() *cobra.Command { return err } - result, err := qsc.QuerySubscriptionsForAddress( - context.Background(), - subscriptiontypes.NewQuerySubscriptionsForAddressRequest( - address, - hubtypes.StatusFromString(status), - pagination, - ), + result, err := qc.QuerySubscriptionsForAddress( + address, + hubtypes.StatusFromString(status), + pagination, ) if err != nil { return err } - items = append(items, types.NewSubscriptionsFromRaw(result.Subscriptions)...) + items = append(items, types.NewSubscriptionsFromRaw(result)...) } else if plan != 0 { - result, err := qsc.QuerySubscriptionsForPlan( - context.Background(), - subscriptiontypes.NewQuerySubscriptionsForPlanRequest( - plan, - pagination, - ), + result, err := qc.QuerySubscriptionsForPlan( + plan, + pagination, ) if err != nil { return err } - items = append(items, types.NewSubscriptionsFromRaw(result.Subscriptions)...) + items = append(items, types.NewSubscriptionsFromRaw(result)...) } else { - result, err := qsc.QuerySubscriptions( - context.Background(), - subscriptiontypes.NewQuerySubscriptionsRequest(pagination), - ) + result, err := qc.QuerySubscriptions(pagination) if err != nil { return err } - items = append(items, types.NewSubscriptionsFromRaw(result.Subscriptions)...) + items = append(items, types.NewSubscriptionsFromRaw(result)...) } table := tablewriter.NewWriter(cmd.OutOrStdout()) @@ -189,7 +173,7 @@ func QuerySubscriptions() *cobra.Command { items[i].Node, items[i].Price.Raw().String(), items[i].Deposit.Raw().String(), - netutil.ToReadable(items[i].Free, 2), + netutils.ToReadable(items[i].Free, 2), items[i].Status, }, ) @@ -200,9 +184,11 @@ func QuerySubscriptions() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "subscriptions") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + cmd.Flags().String(flagAddress, "", "filter with account address") cmd.Flags().Uint64(flagPlan, 0, "filter with plan identity") cmd.Flags().String(flagStatus, "Active", "filter with status (Active|Inactive)") @@ -216,7 +202,7 @@ func QueryQuota() *cobra.Command { Short: "Query a quota", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -231,23 +217,16 @@ func QueryQuota() *cobra.Command { return err } - var ( - qsc = subscriptiontypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryQuota( - context.Background(), - subscriptiontypes.NewQueryQuotaRequest( - id, - address, - ), + result, err := qc.QueryQuota( + id, + address, ) if err != nil { return err } var ( - item = types.NewQuotaFromRaw(&result.Quota) + item = types.NewQuotaFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -255,8 +234,8 @@ func QueryQuota() *cobra.Command { table.Append( []string{ item.Address, - netutil.ToReadable(item.Allocated, 2), - netutil.ToReadable(item.Consumed, 2), + netutils.ToReadable(item.Allocated, 2), + netutils.ToReadable(item.Consumed, 2), }, ) @@ -265,7 +244,8 @@ func QueryQuota() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) return cmd } @@ -276,7 +256,7 @@ func QueryQuotas() *cobra.Command { Short: "Query quotas of a subscription", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) (err error) { - ctx, err := client.GetClientQueryContext(cmd) + qc, err := context.NewQueryContextFromCmd(cmd) if err != nil { return err } @@ -291,23 +271,16 @@ func QueryQuotas() *cobra.Command { return err } - var ( - qsc = subscriptiontypes.NewQueryServiceClient(ctx) - ) - - result, err := qsc.QueryQuotas( - context.Background(), - subscriptiontypes.NewQueryQuotasRequest( - id, - pagination, - ), + result, err := qc.QueryQuotas( + id, + pagination, ) if err != nil { return err } var ( - items = types.NewQuotasFromRaw(result.Quotas) + items = types.NewQuotasFromRaw(result) table = tablewriter.NewWriter(cmd.OutOrStdout()) ) @@ -316,8 +289,8 @@ func QueryQuotas() *cobra.Command { table.Append( []string{ items[i].Address, - netutil.ToReadable(items[i].Allocated, 2), - netutil.ToReadable(items[i].Consumed, 2), + netutils.ToReadable(items[i].Allocated, 2), + netutils.ToReadable(items[i].Consumed, 2), }, ) } @@ -327,8 +300,10 @@ func QueryQuotas() *cobra.Command { }, } - flags.AddQueryFlagsToCmd(cmd) flags.AddPaginationFlagsToCmd(cmd, "quotas") + clitypes.AddQueryFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagTimeout) + return cmd } From 2ae982d6d8e9b642b6bb47d4d2557ee60d195061 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Tue, 10 Aug 2021 19:02:43 +0530 Subject: [PATCH 12/18] Added required flag types --- types/cmd.go | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/types/cmd.go b/types/cmd.go index e609a00..5594b7d 100644 --- a/types/cmd.go +++ b/types/cmd.go @@ -1,6 +1,86 @@ package types +import ( + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keyring" + "github.com/spf13/cobra" +) + const ( - FlagTimeout = "timeout" + FlagAccount = "account" + FlagCoinType = "coin-type" + FlagIndex = "index" + FlagRating = "rating" + FlagRecover = "recover" FlagResolver = "resolver" ) + +const ( + FlagHome = "home" + FlagListen = "listen" + FlagTTY = "tty" + FlagWithKeyring = "with-keyring" + FlagWithService = "with-service" +) + +const ( + FlagBroadcastMode = "broadcast-mode" + FlagChainID = "chain-id" + FlagFrom = "from" + FlagGas = "gas" + FlagGasPrices = "gas-prices" + FlagKeyringBackend = "keyring-backend" + FlagKeyringHome = "keyring-home" + FlagMemo = "memo" + FlagServiceHome = "service-home" + FlagRPCAddress = "rpc-address" + FlagTimeout = "timeout" +) + +func AddFlagsToCmd(cmd *cobra.Command) { + cmd.Flags().String(FlagBroadcastMode, "block", "transaction broadcasting mode (sync|async|block)") + cmd.Flags().String(FlagChainID, "", "chain identity of the network") + cmd.Flags().String(FlagFrom, "", "name or address of private key with which to sign") + cmd.Flags().Uint64(FlagGas, 200000, "gas limit to set per-transaction") + cmd.Flags().String(FlagGasPrices, "", "gas prices in decimal format to determine the transaction fee") + cmd.Flags().String(FlagKeyringBackend, keyring.BackendOS, "the keyring backend backend (os|file|test)") + cmd.Flags().String(FlagKeyringHome, Home, "home directory of the keys") + cmd.Flags().String(FlagMemo, "", "memo to send along with transaction") + cmd.Flags().String(FlagServiceHome, Home, "home directory of the service") + cmd.Flags().String(FlagRPCAddress, "", "tendermint RPC interface address for this chain") + cmd.Flags().Duration(FlagTimeout, 15*time.Second, "time limit for requests made by the HTTP client") +} + +func AddKeyringFlagsToCmd(cmd *cobra.Command) { + AddFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(FlagBroadcastMode) + _ = cmd.Flags().MarkHidden(FlagChainID) + _ = cmd.Flags().MarkHidden(FlagFrom) + _ = cmd.Flags().MarkHidden(FlagGas) + _ = cmd.Flags().MarkHidden(FlagGasPrices) + _ = cmd.Flags().MarkHidden(FlagMemo) + _ = cmd.Flags().MarkHidden(FlagServiceHome) + _ = cmd.Flags().MarkHidden(FlagRPCAddress) +} + +func AddQueryFlagsToCmd(cmd *cobra.Command) { + AddFlagsToCmd(cmd) + _ = cmd.MarkFlagRequired(FlagRPCAddress) + _ = cmd.Flags().MarkHidden(FlagBroadcastMode) + _ = cmd.Flags().MarkHidden(FlagChainID) + _ = cmd.Flags().MarkHidden(FlagFrom) + _ = cmd.Flags().MarkHidden(FlagGas) + _ = cmd.Flags().MarkHidden(FlagGasPrices) + _ = cmd.Flags().MarkHidden(FlagKeyringBackend) + _ = cmd.Flags().MarkHidden(FlagKeyringHome) + _ = cmd.Flags().MarkHidden(FlagMemo) + _ = cmd.Flags().MarkHidden(FlagServiceHome) +} + +func AddTxFlagsToCmd(cmd *cobra.Command) { + AddFlagsToCmd(cmd) + _ = cmd.MarkFlagRequired(FlagChainID) + _ = cmd.MarkFlagRequired(FlagFrom) + _ = cmd.MarkFlagRequired(FlagRPCAddress) +} From 0c34af56bebdd2b18c9129d34b587a1e1de43e8a Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Wed, 11 Aug 2021 12:36:12 +0530 Subject: [PATCH 13/18] Updated tx commands with Client context --- x/node/client/cmd/tx.go | 39 +++++++--- x/plan/client/cmd/tx.go | 106 ++++++++++++++++++++++----- x/provider/client/cmd/tx.go | 63 +++++++++++++---- x/session/client/cmd/tx.go | 62 ++++++++++++---- x/subscription/client/cmd/tx.go | 122 ++++++++++++++++++++++++++------ 5 files changed, 321 insertions(+), 71 deletions(-) diff --git a/x/node/client/cmd/tx.go b/x/node/client/cmd/tx.go index 8bdc90c..4e6ec30 100644 --- a/x/node/client/cmd/tx.go +++ b/x/node/client/cmd/tx.go @@ -1,18 +1,25 @@ package cmd import ( + "bufio" + "fmt" + "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" hubtypes "github.com/sentinel-official/hub/types" nodetypes "github.com/sentinel-official/hub/x/node/types" "github.com/spf13/cobra" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func GetTxCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "node", - Short: "Node related subcommands", + Use: "node", + Short: "Node related subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } cmd.AddCommand( @@ -28,24 +35,40 @@ func txSetStatus() *cobra.Command { Short: "Set a node status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } msg := nodetypes.NewMsgSetStatusRequest( - ctx.FromAddress.Bytes(), + from.Bytes(), hubtypes.StatusFromString(args[0]), ) if err := msg.ValidateBasic(); err != nil { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } diff --git a/x/plan/client/cmd/tx.go b/x/plan/client/cmd/tx.go index 3efb968..2b55e38 100644 --- a/x/plan/client/cmd/tx.go +++ b/x/plan/client/cmd/tx.go @@ -1,23 +1,29 @@ package cmd import ( + "bufio" + "fmt" "strconv" "time" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" hubtypes "github.com/sentinel-official/hub/types" "github.com/sentinel-official/hub/x/plan/types" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func GetTxCommand() *cobra.Command { cmd := &cobra.Command{ Use: "plan", Short: "plan related subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } cmd.AddCommand( @@ -36,7 +42,16 @@ func txAdd() *cobra.Command { Short: "Add a plan", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -57,7 +72,7 @@ func txAdd() *cobra.Command { } msg := types.NewMsgAddRequest( - ctx.FromAddress.Bytes(), + from.Bytes(), price, validity, sdk.NewInt(bytes), @@ -66,11 +81,18 @@ func txAdd() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -81,7 +103,16 @@ func txSetStatus() *cobra.Command { Short: "Set a plan status", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -92,7 +123,7 @@ func txSetStatus() *cobra.Command { } msg := types.NewMsgSetStatusRequest( - ctx.FromAddress.Bytes(), + from.Bytes(), id, hubtypes.StatusFromString(args[1]), ) @@ -100,11 +131,18 @@ func txSetStatus() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -115,7 +153,16 @@ func txAddNode() *cobra.Command { Short: "Add a node for plan", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -131,7 +178,7 @@ func txAddNode() *cobra.Command { } msg := types.NewMsgAddNodeRequest( - ctx.FromAddress.Bytes(), + from.Bytes(), id, node, ) @@ -139,11 +186,18 @@ func txAddNode() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -154,7 +208,16 @@ func txRemoveNode() *cobra.Command { Short: "Remove a node for plan", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -170,7 +233,7 @@ func txRemoveNode() *cobra.Command { } msg := types.NewMsgRemoveNodeRequest( - ctx.FromAddress, + from, id, node, ) @@ -178,11 +241,18 @@ func txRemoveNode() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } diff --git a/x/provider/client/cmd/tx.go b/x/provider/client/cmd/tx.go index a35a0bc..9e9ef6c 100644 --- a/x/provider/client/cmd/tx.go +++ b/x/provider/client/cmd/tx.go @@ -1,18 +1,25 @@ package cmd import ( + "bufio" + "fmt" + "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/spf13/cobra" "github.com/sentinel-official/hub/x/provider/types" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func GetTxCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "provider", - Short: "Provider related subcommands", + Use: "provider", + Short: "Provider related subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } cmd.AddCommand( @@ -30,7 +37,16 @@ func txRegister() *cobra.Command { Args: cobra.ExactArgs(1), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -51,7 +67,7 @@ func txRegister() *cobra.Command { } msg := types.NewMsgRegisterRequest( - ctx.FromAddress, + from, args[0], identity, website, @@ -61,11 +77,18 @@ func txRegister() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) cmd.Flags().String(flagIdentity, "", "identity signature (optional)") cmd.Flags().String(flagWebsite, "", "website (optional)") @@ -79,7 +102,16 @@ func txUpdate() *cobra.Command { Use: "update", Short: "Update a provider", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -105,7 +137,7 @@ func txUpdate() *cobra.Command { } msg := types.NewMsgUpdateRequest( - ctx.FromAddress.Bytes(), + from.Bytes(), name, identity, website, @@ -115,11 +147,18 @@ func txUpdate() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) cmd.Flags().String(flagName, "", "name (optional)") cmd.Flags().String(flagIdentity, "", "identity signature (optional)") diff --git a/x/session/client/cmd/tx.go b/x/session/client/cmd/tx.go index 4089f00..0ed6fe8 100644 --- a/x/session/client/cmd/tx.go +++ b/x/session/client/cmd/tx.go @@ -1,21 +1,27 @@ package cmd import ( + "bufio" + "fmt" "strconv" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" "github.com/spf13/cobra" hubtypes "github.com/sentinel-official/hub/types" "github.com/sentinel-official/hub/x/session/types" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func GetTxCommand() *cobra.Command { cmd := &cobra.Command{ - Use: "session", - Short: "Session related subcommands", + Use: "session", + Short: "Session related subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } cmd.AddCommand( @@ -32,7 +38,16 @@ func txStart() *cobra.Command { Short: "Start a session", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -48,7 +63,7 @@ func txStart() *cobra.Command { } msg := types.NewMsgStartRequest( - ctx.FromAddress, + from, id, address, ) @@ -56,11 +71,18 @@ func txStart() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -71,7 +93,16 @@ func txEnd() *cobra.Command { Short: "End a session", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -87,7 +118,7 @@ func txEnd() *cobra.Command { } msg := types.NewMsgEndRequest( - ctx.FromAddress, + from, id, rating, ) @@ -95,11 +126,18 @@ func txEnd() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) cmd.Flags().Uint64(flagRating, 0, "rate the session quality [0, 10]") diff --git a/x/subscription/client/cmd/tx.go b/x/subscription/client/cmd/tx.go index 4811283..8e625e0 100644 --- a/x/subscription/client/cmd/tx.go +++ b/x/subscription/client/cmd/tx.go @@ -1,22 +1,28 @@ package cmd import ( + "bufio" + "fmt" "strconv" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" hubtypes "github.com/sentinel-official/hub/types" "github.com/sentinel-official/hub/x/subscription/types" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func GetTxCommand() *cobra.Command { cmd := &cobra.Command{ Use: "subscription", Short: "Subscription related subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, } cmd.AddCommand( @@ -36,7 +42,16 @@ func txSubscribeToNode() *cobra.Command { Short: "Subscribe to a node", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -52,7 +67,7 @@ func txSubscribeToNode() *cobra.Command { } msg := types.NewMsgSubscribeToNodeRequest( - ctx.FromAddress, + from, address, deposit, ) @@ -60,11 +75,18 @@ func txSubscribeToNode() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -75,7 +97,16 @@ func txSubscribeToPlan() *cobra.Command { Short: "Subscribe to a plan", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -86,7 +117,7 @@ func txSubscribeToPlan() *cobra.Command { } msg := types.NewMsgSubscribeToPlanRequest( - ctx.FromAddress, + from, id, args[1], ) @@ -94,11 +125,18 @@ func txSubscribeToPlan() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -109,7 +147,16 @@ func txAddQuota() *cobra.Command { Short: "Add a quota for subscription", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -130,7 +177,7 @@ func txAddQuota() *cobra.Command { } msg := types.NewMsgAddQuotaRequest( - ctx.FromAddress, + from, id, address, sdk.NewInt(bytes), @@ -139,11 +186,18 @@ func txAddQuota() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -154,7 +208,16 @@ func txUpdateQuota() *cobra.Command { Short: "Update a quota for subscription", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -175,7 +238,7 @@ func txUpdateQuota() *cobra.Command { } msg := types.NewMsgUpdateQuotaRequest( - ctx.FromAddress, + from, id, address, sdk.NewInt(bytes), @@ -184,11 +247,18 @@ func txUpdateQuota() *cobra.Command { return err } - return tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), msg) + result, err := cc.SignAndBroadcastTx(password, msg) + if err != nil { + return err + } + + fmt.Println(result) + return nil }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } @@ -200,7 +270,16 @@ func txCancel() *cobra.Command { Args: cobra.ExactArgs(1), Hidden: true, RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + _, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) if err != nil { return err } @@ -211,7 +290,7 @@ func txCancel() *cobra.Command { } msg := types.NewMsgCancelRequest( - ctx.FromAddress, + from, id, ) if err := msg.ValidateBasic(); err != nil { @@ -222,7 +301,8 @@ func txCancel() *cobra.Command { }, } - flags.AddTxFlagsToCmd(cmd) + clitypes.AddTxFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagServiceHome) return cmd } From 35feb73ef33c06b82abeb755394f349c039a3d99 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Wed, 11 Aug 2021 18:54:35 +0530 Subject: [PATCH 14/18] Updated keys subcommands --- cmd/keys.go | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 cmd/keys.go diff --git a/cmd/keys.go b/cmd/keys.go new file mode 100644 index 0000000..179d441 --- /dev/null +++ b/cmd/keys.go @@ -0,0 +1,209 @@ +package cmd + +import ( + "bufio" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/go-bip39" + "github.com/spf13/cobra" + + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" + keyringutils "github.com/sentinel-official/cli-client/utils/keyring" +) + +func KeysCmd() *cobra.Command { + var ( + cmd = &cobra.Command{ + Use: "keys", + Short: "Keys subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + ) + + cmd.AddCommand( + addCmd(), + deleteCmd(), + listCmd(), + showCmd(), + ) + + return cmd +} + +func addCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "add [name]", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + coinType, err := cmd.Flags().GetUint32(clitypes.FlagCoinType) + if err != nil { + return err + } + + account, err := cmd.Flags().GetUint32(clitypes.FlagAccount) + if err != nil { + return err + } + + index, err := cmd.Flags().GetUint32(clitypes.FlagIndex) + if err != nil { + return err + } + + recoverKey, err := cmd.Flags().GetBool(clitypes.FlagRecover) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, err := keyringutils.ReadPassword(cc.KeyringBackend, reader) + if err != nil { + return err + } + + entropy, err := bip39.NewEntropy(256) + if err != nil { + return err + } + + mnemonic, err := bip39.NewMnemonic(entropy) + if err != nil { + return err + } + + if recoverKey { + mnemonic, err = input.GetString("Enter your bip39 mnemonic", reader) + if err != nil { + return err + } + } + + result, err := cc.AddKey(password, args[0], mnemonic, "", coinType, account, index) + if err != nil { + return err + } + + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "**Important** write this mnemonic phrase in a safe place\n") + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "%s\n", mnemonic) + + fmt.Println(result) + return nil + }, + } + + clitypes.AddKeyringFlagsToCmd(cmd) + cmd.Flags().Bool(clitypes.FlagRecover, false, "provide mnemonic phrase to recover an existing key") + cmd.Flags().Uint32(clitypes.FlagCoinType, 118, "coin type number for HD derivation") + cmd.Flags().Uint32(clitypes.FlagAccount, 0, "account number for HD derivation") + cmd.Flags().Uint32(clitypes.FlagIndex, 0, "address index number for HD derivation") + + return cmd +} + +func deleteCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete [name]", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, err := keyringutils.ReadPassword(cc.KeyringBackend, reader) + if err != nil { + return err + } + + return cc.DeleteKey(password, args[0]) + }, + } + + clitypes.AddKeyringFlagsToCmd(cmd) + + return cmd +} + +func listCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "list", + RunE: func(cmd *cobra.Command, args []string) (err error) { + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, err := keyringutils.ReadPassword(cc.KeyringBackend, reader) + if err != nil { + return err + } + + result, err := cc.GetKeys(password) + if err != nil { + return err + } + + fmt.Println(result) + return nil + }, + } + + clitypes.AddKeyringFlagsToCmd(cmd) + + return cmd +} + +func showCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "show [name]", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err + } + + var ( + reader = bufio.NewReader(cmd.InOrStdin()) + ) + + password, err := keyringutils.ReadPassword(cc.KeyringBackend, reader) + if err != nil { + return err + } + + result, err := cc.GetKey(password, args[0]) + if err != nil { + return err + } + + fmt.Println(result) + return nil + }, + } + + clitypes.AddKeyringFlagsToCmd(cmd) + + return cmd +} From e015557f811d05f98380fc92a6f6934c47425e66 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 12 Aug 2021 12:01:56 +0530 Subject: [PATCH 15/18] Updated tx command --- cmd/tx.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/tx.go b/cmd/tx.go index 8a830a9..7446f6e 100644 --- a/cmd/tx.go +++ b/cmd/tx.go @@ -2,7 +2,6 @@ package cmd import ( "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" "github.com/spf13/cobra" nodecmd "github.com/sentinel-official/cli-client/x/node/client/cmd" @@ -27,7 +26,5 @@ func TxCommand() *cobra.Command { cmd.AddCommand(subscriptioncmd.GetTxCommand()) cmd.AddCommand(sessioncmd.GetTxCommand()) - cmd.PersistentFlags().String(flags.FlagChainID, "", "the network chain identity") - return cmd } From ec7f0a303b3412723f9bdb7c2e04658c59823539 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 12 Aug 2021 18:43:50 +0530 Subject: [PATCH 16/18] Integrated connect and disconnect commands with APIs --- cmd/connect.go | 267 +++++++++++++--------------------------------- cmd/disconnect.go | 53 ++++----- 2 files changed, 91 insertions(+), 229 deletions(-) diff --git a/cmd/connect.go b/cmd/connect.go index 1c24489..9a18a0d 100644 --- a/cmd/connect.go +++ b/cmd/connect.go @@ -1,76 +1,44 @@ package cmd import ( + "bufio" "bytes" - "context" - "crypto/tls" "encoding/base64" - "encoding/binary" "encoding/json" "fmt" "net" - "net/http" - "path/filepath" "strconv" "strings" - "time" - "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/tx" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" "github.com/go-kit/kit/transport/http/jsonrpc" - "github.com/pkg/errors" hubtypes "github.com/sentinel-official/hub/types" - nodetypes "github.com/sentinel-official/hub/x/node/types" sessiontypes "github.com/sentinel-official/hub/x/session/types" "github.com/spf13/cobra" - "github.com/sentinel-official/cli-client/services/wireguard" + "github.com/sentinel-official/cli-client/context" wireguardtypes "github.com/sentinel-official/cli-client/services/wireguard/types" - clienttypes "github.com/sentinel-official/cli-client/types" + clitypes "github.com/sentinel-official/cli-client/types" resttypes "github.com/sentinel-official/cli-client/types/rest" - netutil "github.com/sentinel-official/cli-client/utils/net" ) -func queryNode(qsc nodetypes.QueryServiceClient, address hubtypes.NodeAddress) (*nodetypes.Node, error) { - var ( - result, err = qsc.QueryNode( - context.Background(), - nodetypes.NewQueryNodeRequest(address), - ) - ) - +func parseResolversFromCmd(cmd *cobra.Command) ([]net.IP, error) { + v, err := cmd.Flags().GetStringArray(clitypes.FlagResolver) if err != nil { return nil, err } - return &result.Node, nil -} + items := make([]net.IP, 0, len(v)) + for _, s := range v { + item := net.ParseIP(s) + if item == nil { + return nil, fmt.Errorf("resolver ip %s is invalid", s) + } -func queryActiveSession(qsc sessiontypes.QueryServiceClient, address sdk.AccAddress) (*sessiontypes.Session, error) { - var ( - result, err = qsc.QuerySessionsForAddress( - context.Background(), - sessiontypes.NewQuerySessionsForAddressRequest( - address, - hubtypes.StatusActive, - &query.PageRequest{ - Limit: 1, - }, - ), - ) - ) - - if err != nil { - return nil, err - } - if len(result.Sessions) > 0 { - return &result.Sessions[0], nil + items = append(items, item) } - return nil, nil + return items, nil } func ConnectCmd() *cobra.Command { @@ -79,11 +47,6 @@ func ConnectCmd() *cobra.Command { Short: "Connect to a node", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) - if err != nil { - return err - } - id, err := strconv.ParseUint(args[0], 10, 64) if err != nil { return err @@ -94,65 +57,43 @@ func ConnectCmd() *cobra.Command { return err } - timeout, err := cmd.Flags().GetDuration(clienttypes.FlagTimeout) + rating, err := cmd.Flags().GetUint64(clitypes.FlagRating) if err != nil { return err } - ss, err := cmd.Flags().GetStringArray(clienttypes.FlagResolver) + resolvers, err := parseResolversFromCmd(cmd) if err != nil { return err } - var ( - resolvers []net.IP - status = clienttypes.NewStatus() - statusFilePath = filepath.Join(ctx.HomeDir, "status.json") - ) - - for _, s := range ss { - ip := net.ParseIP(s) - if ip == nil { - return fmt.Errorf("provided resolver ip %s is invalid", s) - } - - resolvers = append(resolvers, ip) + cc, err := context.NewClientContextFromCmd(cmd) + if err != nil { + return err } - if err := status.LoadFromPath(statusFilePath); err != nil { + status, err := cc.GetStatus() + if err != nil { return err } if status.IFace != "" { - var ( - service = wireguard.NewWireGuard(). - WithConfig( - &wireguardtypes.Config{ - Name: status.IFace, - }, - ) - ) - - if service.IsUp() { - if err := service.PreDown(); err != nil { - return err - } - if err := service.Down(); err != nil { - return err - } - if err := service.PostDown(); err != nil { - return err - } + if err := cc.Disconnect(); err != nil { + return err } } var ( - messages []sdk.Msg - nodeQueryClient = nodetypes.NewQueryServiceClient(ctx) - sessionQueryClient = sessiontypes.NewQueryServiceClient(ctx) + messages []sdk.Msg + reader = bufio.NewReader(cmd.InOrStdin()) ) - session, err := queryActiveSession(sessionQueryClient, ctx.FromAddress) + password, from, err := cc.ReadPasswordAndGetAddress(reader, cc.From) + if err != nil { + return err + } + + session, err := cc.QueryActiveSession(from) if err != nil { return err } @@ -161,9 +102,9 @@ func ConnectCmd() *cobra.Command { messages = append( messages, sessiontypes.NewMsgEndRequest( - ctx.FromAddress, + from, session.Id, - 0, + rating, ), ) } @@ -171,163 +112,101 @@ func ConnectCmd() *cobra.Command { messages = append( messages, sessiontypes.NewMsgStartRequest( - ctx.FromAddress, + from, id, address, ), ) - if err := tx.GenerateOrBroadcastTxCLI(ctx, cmd.Flags(), messages...); err != nil { + txRes, err := cc.SignAndBroadcastTx(password, messages...) + if err != nil { return err } - node, err := queryNode(nodeQueryClient, address) + fmt.Println(txRes) + + session, err = cc.QueryActiveSession(from) if err != nil { return err } + if session == nil { + return fmt.Errorf("active session does not exist for subscription %d", id) + } - session, err = queryActiveSession(sessionQueryClient, ctx.FromAddress) + node, err := cc.QueryNode(address) if err != nil { return err } - if session == nil { - return errors.New("no active session found") - } wgPrivateKey, err := wireguardtypes.NewPrivateKey() if err != nil { return err } - signature, _, err := ctx.Keyring.Sign(ctx.From, sdk.Uint64ToBigEndian(session.Id)) + signBytesRes, err := cc.SignBytes( + password, + cc.From, + sdk.Uint64ToBigEndian(session.Id), + ) if err != nil { return err } - req, err := json.Marshal( - map[string]interface{}{ - "key": wgPrivateKey.Public().String(), - "signature": signature, - }, - ) + signature, err := base64.StdEncoding.DecodeString(signBytesRes.Signature) if err != nil { return err } var ( - body resttypes.Response + resp resttypes.Response endpoint = fmt.Sprintf( "%s/accounts/%s/sessions/%d", - strings.Trim(node.RemoteURL, "/"), ctx.FromAddress, session.Id, + strings.Trim(node.RemoteURL, "/"), from, session.Id, ) - httpClient = http.Client{ - Transport: &http.Transport{ - TLSClientConfig: &tls.Config{ - InsecureSkipVerify: true, - }, - }, - Timeout: timeout, - } ) - resp, err := httpClient.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(req)) + buf, err := json.Marshal( + map[string]interface{}{ + "key": wgPrivateKey.Public().String(), + "signature": signature, + }, + ) if err != nil { return err } - defer resp.Body.Close() - - if err := json.NewDecoder(resp.Body).Decode(&body); err != nil { + r, err := cc.Post(endpoint, jsonrpc.ContentType, bytes.NewBuffer(buf)) + if err != nil { return err } - if body.Error != nil { - return errors.New(body.Error.Message) - } - result, err := base64.StdEncoding.DecodeString(body.Result.(string)) - if err != nil { + if err := json.NewDecoder(r.Body).Decode(&resp); err != nil { return err } - if len(result) != 58 { - return fmt.Errorf("incorrect result size %d", len(result)) + if resp.Error != nil { + return fmt.Errorf(resp.Error.Message) } - var ( - ipv4Address = net.IP(result[0:4]) - ipv6Address = net.IP(result[4:20]) - endpointHost = net.IP(result[20:24]) - endpointPort = binary.BigEndian.Uint16(result[24:26]) - endpointWGPublicKey = wireguardtypes.NewKey(result[26:58]) - ) - - listenPort, err := netutil.GetFreeUDPPort() + info, err := base64.StdEncoding.DecodeString(resp.Result.(string)) if err != nil { return err } - var ( - cfg = &wireguardtypes.Config{ - Name: wireguardtypes.DefaultInterface, - Interface: wireguardtypes.Interface{ - Addresses: []wireguardtypes.IPNet{ - {IP: ipv4Address, Net: 32}, - {IP: ipv6Address, Net: 128}, - }, - ListenPort: listenPort, - PrivateKey: *wgPrivateKey, - DNS: append( - []net.IP{net.ParseIP("10.8.0.1")}, - resolvers..., - ), - }, - Peers: []wireguardtypes.Peer{ - { - PublicKey: *endpointWGPublicKey, - AllowedIPs: []wireguardtypes.IPNet{ - {IP: net.ParseIP("0.0.0.0")}, - {IP: net.ParseIP("::")}, - }, - Endpoint: wireguardtypes.Endpoint{ - Host: endpointHost.String(), - Port: endpointPort, - }, - PersistentKeepalive: 15, - }, - }, - } - - service = wireguard.NewWireGuard(). - WithConfig(cfg) + return cc.Connect( + password, + from.String(), + address.String(), + session.Id, + info, + [][]byte{wgPrivateKey.Bytes()}, + resolvers, ) - - status = clienttypes.NewStatus(). - WithFrom(ctx.FromAddress.String()). - WithID(id). - WithIFace(cfg.Name). - WithTo(address.String()) - if err := status.SaveToPath(statusFilePath); err != nil { - return err - } - - if err := service.PreUp(); err != nil { - return err - } - if err := service.Up(); err != nil { - return err - } - if err := service.PostUp(); err != nil { - return err - } - - return nil }, } - flags.AddTxFlagsToCmd(cmd) - - cmd.Flags().String(flags.FlagChainID, "", "the network chain identity") - cmd.Flags().StringArray(clienttypes.FlagResolver, nil, "provide additional DNS servers") - cmd.Flags().Duration(clienttypes.FlagTimeout, 15*time.Second, "time limit for requests made by the HTTP client") + clitypes.AddTxFlagsToCmd(cmd) + cmd.Flags().StringArray(clitypes.FlagResolver, nil, "provide additional DNS servers") + cmd.Flags().Uint64(clitypes.FlagRating, 0, "rate the session quality [0, 10]") return cmd } diff --git a/cmd/disconnect.go b/cmd/disconnect.go index d6c1a70..ddf31dc 100644 --- a/cmd/disconnect.go +++ b/cmd/disconnect.go @@ -1,15 +1,10 @@ package cmd import ( - "os" - "path/filepath" - - "github.com/cosmos/cosmos-sdk/client" "github.com/spf13/cobra" - "github.com/sentinel-official/cli-client/services/wireguard" - wireguardtypes "github.com/sentinel-official/cli-client/services/wireguard/types" - clienttypes "github.com/sentinel-official/cli-client/types" + "github.com/sentinel-official/cli-client/context" + clitypes "github.com/sentinel-official/cli-client/types" ) func DisconnectCmd() *cobra.Command { @@ -17,48 +12,36 @@ func DisconnectCmd() *cobra.Command { Use: "disconnect", Short: "Disconnect from a node", RunE: func(cmd *cobra.Command, args []string) error { - ctx, err := client.GetClientTxContext(cmd) + cc, err := context.NewClientContextFromCmd(cmd) if err != nil { return err } - var ( - status = clienttypes.NewStatus() - statusFilePath = filepath.Join(ctx.HomeDir, "status.json") - ) - - if err := status.LoadFromPath(statusFilePath); err != nil { + status, err := cc.GetStatus() + if err != nil { return err } if status.IFace != "" { - var ( - service = wireguard.NewWireGuard(). - WithConfig( - &wireguardtypes.Config{ - Name: status.IFace, - }, - ) - ) - - if service.IsUp() { - if err := service.PreDown(); err != nil { - return err - } - if err := service.Down(); err != nil { - return err - } - if err := service.PostDown(); err != nil { - return err - } + if err := cc.Disconnect(); err != nil { + return err } - - return os.Remove(statusFilePath) } return nil }, } + clitypes.AddFlagsToCmd(cmd) + _ = cmd.Flags().MarkHidden(clitypes.FlagBroadcastMode) + _ = cmd.Flags().MarkHidden(clitypes.FlagChainID) + _ = cmd.Flags().MarkHidden(clitypes.FlagFrom) + _ = cmd.Flags().MarkHidden(clitypes.FlagGas) + _ = cmd.Flags().MarkHidden(clitypes.FlagGasPrices) + _ = cmd.Flags().MarkHidden(clitypes.FlagKeyringBackend) + _ = cmd.Flags().MarkHidden(clitypes.FlagKeyringHome) + _ = cmd.Flags().MarkHidden(clitypes.FlagMemo) + _ = cmd.Flags().MarkHidden(clitypes.FlagRPCAddress) + return cmd } From e850c4479175a0c06ee3de48cbc6476574cde6b9 Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 12 Aug 2021 18:44:33 +0530 Subject: [PATCH 17/18] Updated start server command --- cmd/start.go | 111 ++++++++++++++++++----------- services/wireguard/types/crypto.go | 4 ++ services/wireguard/wireguard.go | 13 ++-- types/bandwidth.go | 9 +-- types/keyring/key.go | 6 +- types/keys.go | 10 ++- types/service.go | 4 -- utils/file/read.go | 24 +++++++ utils/keyring/input.go | 19 +++++ utils/process/pid.go | 34 +++++++++ 10 files changed, 168 insertions(+), 66 deletions(-) create mode 100644 utils/file/read.go create mode 100644 utils/keyring/input.go create mode 100644 utils/process/pid.go diff --git a/cmd/start.go b/cmd/start.go index 18013bb..5739497 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -1,87 +1,114 @@ package cmd import ( + "io/ioutil" + "log" "net/http" + "os" "path/filepath" - "strings" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/std" "github.com/gorilla/mux" "github.com/rs/cors" - "github.com/sentinel-official/hub" - hubparams "github.com/sentinel-official/hub/params" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/sentinel-official/cli-client/context" - "github.com/sentinel-official/cli-client/middlewares" - keysrest "github.com/sentinel-official/cli-client/rest/keys" - servicerest "github.com/sentinel-official/cli-client/rest/service" - "github.com/sentinel-official/cli-client/types" - configtypes "github.com/sentinel-official/cli-client/types/config" - randutils "github.com/sentinel-official/cli-client/utils/rand" + restmiddlewares "github.com/sentinel-official/cli-client/rest/middlewares" + restmodules "github.com/sentinel-official/cli-client/rest/modules" + clitypes "github.com/sentinel-official/cli-client/types" ) func StartCmd() *cobra.Command { cmd := &cobra.Command{ Use: "start", - Short: "Start REST API server", - RunE: func(cmd *cobra.Command, args []string) error { - var ( - home = viper.GetString(flags.FlagHome) - configPath = filepath.Join(home, types.ConfigFilename) - buildPath = filepath.Join(home, types.BuildFolderName) - ) + Short: "Start the management server", + Args: cobra.NoArgs, + PreRunE: func(cmd *cobra.Command, _ []string) error { + home, err := cmd.Flags().GetString(clitypes.FlagHome) + if err != nil { + return err + } - v := viper.New() - v.SetConfigFile(configPath) + if err := os.MkdirAll(home, os.ModePerm); err != nil { + return err + } - config, err := configtypes.ReadInConfig(v) + tty, err := cmd.Flags().GetBool(clitypes.FlagTTY) if err != nil { return err } - if err := config.Validate(); err != nil { + + if !tty { + os.Stderr, os.Stdin, os.Stdout = nil, nil, nil + } + + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + home, err := cmd.Flags().GetString(clitypes.FlagHome) + if err != nil { return err } - config.Token = randutils.RandomStringHex(types.TokenLength) - if err := config.SaveToPath(configPath); err != nil { + listen, err := cmd.Flags().GetString(clitypes.FlagListen) + if err != nil { return err } - encoding := hubparams.MakeEncodingConfig() - std.RegisterInterfaces(encoding.InterfaceRegistry) - hub.ModuleBasics.RegisterInterfaces(encoding.InterfaceRegistry) + withKeyring, err := cmd.Flags().GetBool(clitypes.FlagWithKeyring) + if err != nil { + return err + } - var ( - ctx = context.NewContext(). - WithConfig(config). - WithEncoding(&encoding) + withService, err := cmd.Flags().GetBool(clitypes.FlagWithService) + if err != nil { + return err + } + var ( + ctx = context.NewServiceContext(). + WithHome(home) muxRouter = mux.NewRouter() - prefixRouter = muxRouter.PathPrefix(types.APIPathPrefix).Subrouter() + prefixRouter = muxRouter. + PathPrefix(clitypes.APIPathPrefix). + Subrouter() ) - muxRouter.Use(middlewares.Log) - muxRouter.PathPrefix("/"). - Handler(http.FileServer(http.Dir(buildPath))) + muxRouter.Use(restmiddlewares.Log) + prefixRouter.Use(restmiddlewares.AddHeaders) - prefixRouter.Use(middlewares.AddHeaders) - keysrest.RegisterRoutes(prefixRouter, ctx) - servicerest.RegisterRoutes(prefixRouter, ctx) + if withKeyring { + restmodules.RegisterKeyring(prefixRouter, &ctx) + } + if withService { + restmodules.RegisterService(prefixRouter, &ctx) + } + + if err := ioutil.WriteFile( + filepath.Join(home, "url.txt"), + []byte("http"+"://"+listen+clitypes.APIPathPrefix), + os.ModePerm, + ); err != nil { + return err + } router := cors.New( cors.Options{ - AllowedOrigins: strings.Split(config.CORS.AllowedOrigins, ","), - AllowedMethods: []string{http.MethodDelete, http.MethodGet, http.MethodPost}, + AllowedOrigins: []string{"*"}, + AllowedMethods: []string{http.MethodPost}, AllowedHeaders: []string{"Content-Type"}, }, ).Handler(muxRouter) - return http.ListenAndServe(config.ListenOn, router) + log.Printf("Listening on %s", listen) + return http.ListenAndServe(listen, router) }, } + cmd.Flags().Bool(clitypes.FlagWithKeyring, false, "include the endpoints of keyring module") + cmd.Flags().Bool(clitypes.FlagWithService, false, "include the endpoints of service module") + cmd.Flags().Bool(clitypes.FlagTTY, false, "enable the standard error, input and output") + cmd.Flags().String(clitypes.FlagListen, clitypes.Listen, "listen address of the server") + cmd.Flags().String(clitypes.FlagHome, clitypes.Home, "home directory of the server") + return cmd } diff --git a/services/wireguard/types/crypto.go b/services/wireguard/types/crypto.go index 8e1b504..e313036 100644 --- a/services/wireguard/types/crypto.go +++ b/services/wireguard/types/crypto.go @@ -45,6 +45,10 @@ func NewPrivateKey() (*Key, error) { return key, nil } +func (k *Key) Bytes() []byte { + return k[:] +} + func (k *Key) String() string { return base64.StdEncoding.EncodeToString(k[:]) } diff --git a/services/wireguard/wireguard.go b/services/wireguard/wireguard.go index c253d85..1d7b87e 100644 --- a/services/wireguard/wireguard.go +++ b/services/wireguard/wireguard.go @@ -9,8 +9,6 @@ import ( "strings" "github.com/alessio/shellescape" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/spf13/viper" "github.com/sentinel-official/cli-client/services/wireguard/types" clienttypes "github.com/sentinel-official/cli-client/types" @@ -23,6 +21,7 @@ var ( type WireGuard struct { cfg *types.Config info []byte + home string } func NewWireGuard() *WireGuard { @@ -31,8 +30,8 @@ func NewWireGuard() *WireGuard { func (w *WireGuard) WithConfig(v *types.Config) *WireGuard { w.cfg = v; return w } func (w *WireGuard) WithInfo(v []byte) *WireGuard { w.info = v; return w } +func (w *WireGuard) WithHome(v string) *WireGuard { w.home = v; return w } -func (w *WireGuard) Home() string { return viper.GetString(flags.FlagHome) } func (w *WireGuard) Info() []byte { return w.info } func (w *WireGuard) IsUp() bool { @@ -54,12 +53,12 @@ func (w *WireGuard) IsUp() bool { } func (w *WireGuard) PreUp() error { - return w.cfg.WriteToFile(w.Home()) + return w.cfg.WriteToFile(w.home) } func (w *WireGuard) Up() error { var ( - path = filepath.Join(w.Home(), fmt.Sprintf("%s.conf", w.cfg.Name)) + path = filepath.Join(w.home, fmt.Sprintf("%s.conf", w.cfg.Name)) cmd = exec.Command("wg-quick", strings.Split( fmt.Sprintf("up %s", shellescape.Quote(path)), " ")...) ) @@ -74,7 +73,7 @@ func (w *WireGuard) PreDown() error { return nil } func (w *WireGuard) Down() error { var ( - path = filepath.Join(w.Home(), fmt.Sprintf("%s.conf", w.cfg.Name)) + path = filepath.Join(w.home, fmt.Sprintf("%s.conf", w.cfg.Name)) cmd = exec.Command("wg-quick", strings.Split( fmt.Sprintf("down %s", shellescape.Quote(path)), " ")...) ) @@ -85,7 +84,7 @@ func (w *WireGuard) Down() error { } func (w *WireGuard) PostDown() error { - path := filepath.Join(w.Home(), fmt.Sprintf("%s.conf", w.cfg.Name)) + path := filepath.Join(w.home, fmt.Sprintf("%s.conf", w.cfg.Name)) if _, err := os.Stat(path); err == nil { return os.Remove(path) } diff --git a/types/bandwidth.go b/types/bandwidth.go index 6af4a42..d5ed1ee 100644 --- a/types/bandwidth.go +++ b/types/bandwidth.go @@ -5,7 +5,7 @@ import ( hubtypes "github.com/sentinel-official/hub/types" - netutil "github.com/sentinel-official/cli-client/utils/net" + netutils "github.com/sentinel-official/cli-client/utils/net" ) type Bandwidth struct { @@ -14,9 +14,10 @@ type Bandwidth struct { } func (b Bandwidth) String() string { - return fmt.Sprintf("%s+%s", - netutil.ToReadable(b.Upload, 2), - netutil.ToReadable(b.Download, 2), + return fmt.Sprintf( + "%s+%s", + netutils.ToReadable(b.Upload, 2), + netutils.ToReadable(b.Download, 2), ) } diff --git a/types/keyring/key.go b/types/keyring/key.go index fb52712..7954871 100644 --- a/types/keyring/key.go +++ b/types/keyring/key.go @@ -1,7 +1,7 @@ package keyring import ( - "encoding/hex" + "encoding/base64" "github.com/cosmos/cosmos-sdk/crypto/keyring" ) @@ -15,8 +15,8 @@ type Key struct { func NewKeyFromRaw(v keyring.Info) Key { return Key{ Name: v.GetName(), - PubKey: hex.EncodeToString(v.GetPubKey().Bytes()), - Address: hex.EncodeToString(v.GetAddress().Bytes()), + PubKey: base64.StdEncoding.EncodeToString(v.GetPubKey().Bytes()), + Address: base64.StdEncoding.EncodeToString(v.GetAddress().Bytes()), } } diff --git a/types/keys.go b/types/keys.go index e38f9a9..3357de5 100644 --- a/types/keys.go +++ b/types/keys.go @@ -6,15 +6,13 @@ import ( ) const ( - APIPathPrefix = "/api/v1" - BuildFolderName = "build" - ConfigFilename = "config.toml" - StatusFilename = "status.json" - TokenLength = 32 + APIPathPrefix = "/api/v1" + StatusFilename = "status.json" + Listen = "127.0.0.1:11112" ) var ( - DefaultHomeDirectory = func() string { + Home = func() string { home, err := os.UserHomeDir() if err != nil { panic(err) diff --git a/types/service.go b/types/service.go index c03ca96..8629382 100644 --- a/types/service.go +++ b/types/service.go @@ -19,20 +19,16 @@ type Service interface { } type Status struct { - From string `json:"from"` ID uint64 `json:"id"` IFace string `json:"iface"` - To string `json:"to"` } func NewStatus() *Status { return &Status{} } -func (s *Status) WithFrom(v string) *Status { s.From = v; return s } func (s *Status) WithID(v uint64) *Status { s.ID = v; return s } func (s *Status) WithIFace(v string) *Status { s.IFace = v; return s } -func (s *Status) WithTo(v string) *Status { s.To = v; return s } func (s *Status) LoadFromPath(path string) error { if _, err := os.Stat(path); err != nil { diff --git a/utils/file/read.go b/utils/file/read.go new file mode 100644 index 0000000..6df642a --- /dev/null +++ b/utils/file/read.go @@ -0,0 +1,24 @@ +package file + +import ( + "bufio" + "os" +) + +func ReadLine(filename string) (string, error) { + file, err := os.Open(filename) + if err != nil { + return "", err + } + + var ( + reader = bufio.NewReader(file) + ) + + buf, _, err := reader.ReadLine() + if err != nil { + return "", err + } + + return string(buf), nil +} diff --git a/utils/keyring/input.go b/utils/keyring/input.go new file mode 100644 index 0000000..1e118f6 --- /dev/null +++ b/utils/keyring/input.go @@ -0,0 +1,19 @@ +package keyring + +import ( + "bufio" + + "github.com/cosmos/cosmos-sdk/client/input" + "github.com/cosmos/cosmos-sdk/crypto/keyring" +) + +func ReadPassword(backend string, r *bufio.Reader) (s string, err error) { + if backend == keyring.BackendFile { + s, err = input.GetPassword("Enter keyring passphrase: ", r) + if err != nil { + return "", err + } + } + + return s, nil +} diff --git a/utils/process/pid.go b/utils/process/pid.go new file mode 100644 index 0000000..2f6a597 --- /dev/null +++ b/utils/process/pid.go @@ -0,0 +1,34 @@ +package process + +import ( + "fmt" + "io/ioutil" + "os" + "strconv" + "strings" + + "github.com/natefinch/atomic" +) + +func ReadPID(path string) (int, error) { + bytes, err := ioutil.ReadFile(path) + if err != nil { + return 0, err + } + + id, err := strconv.Atoi(string(bytes)) + if err != nil { + return 0, err + } + + return id, nil +} + +func WritePID(path string) error { + return atomic.WriteFile( + path, + strings.NewReader( + fmt.Sprintf("%d", os.Getpid()), + ), + ) +} From 49fe44fd39c82fb83d19b3f8fba53f12b67beede Mon Sep 17 00:00:00 2001 From: Srinivas Baride Date: Thu, 12 Aug 2021 18:45:13 +0530 Subject: [PATCH 18/18] Removed unnecessary code in main file --- go.mod | 3 +- go.sum | 241 +++----------------------------------------------------- main.go | 48 +++-------- 3 files changed, 22 insertions(+), 270 deletions(-) diff --git a/go.mod b/go.mod index 8b44d85..44aa025 100644 --- a/go.mod +++ b/go.mod @@ -8,12 +8,13 @@ require ( github.com/cosmos/go-bip39 v1.0.0 github.com/go-kit/kit v0.10.0 github.com/gorilla/mux v1.8.0 + github.com/natefinch/atomic v1.0.1 github.com/olekukonko/tablewriter v0.0.5 github.com/pkg/errors v0.9.1 github.com/rs/cors v1.7.0 github.com/sentinel-official/hub v0.7.0 github.com/spf13/cobra v1.1.3 - github.com/spf13/viper v1.8.0 + github.com/tendermint/tendermint v0.34.10 golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e ) diff --git a/go.sum b/go.sum index 01ce406..5a7532c 100644 --- a/go.sum +++ b/go.sum @@ -4,37 +4,11 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/keyring v1.1.7-0.20210324095724-d9b6b92e219f h1:zbtw5v6NFpS8LuyXuY9vqpnf5yQj2GqIZQCbIuf5yG0= github.com/99designs/keyring v1.1.7-0.20210324095724-d9b6b92e219f/go.mod h1:0mkLWIoZuQ7uBoospo5Q9zIpqq6rYCPJDSUdeCJvPM8= @@ -84,7 +58,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d/go.mod h1:d3C0AkH6BRcvO8T0UEPu53cnw4IbV63x1bEjildYhO0= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= @@ -108,9 +81,6 @@ github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -129,7 +99,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= @@ -197,7 +166,6 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -212,29 +180,21 @@ github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/gateway v1.1.0 h1:u0SuhL9+Il+UbjM9VIE3ntfRujKbvVpFvNB4HbjeVQ0= github.com/gogo/gateway v1.1.0/go.mod h1:S7rR8FRQyG3QFESeSv4l2WnsyzlCLG0CzBbUUo/mbic= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -245,7 +205,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -259,11 +218,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -272,21 +227,10 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -357,8 +301,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -375,9 +317,7 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= @@ -427,9 +367,8 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -438,6 +377,8 @@ github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A= +github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -486,9 +427,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= @@ -585,9 +525,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.3.4 h1:8q6vk3hthlpb2SouZcnBVKboxWQWMDNF38bwholZrJc= github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -607,9 +546,8 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.0 h1:QRwDgoG8xX+kp69di68D+YYTCWfYEckbZRfUlEIAal0= -github.com/spf13/viper v1.8.0/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -653,11 +591,8 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -665,29 +600,19 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -715,11 +640,6 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -729,11 +649,7 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -742,9 +658,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -763,59 +676,31 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -842,56 +727,35 @@ golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -916,41 +780,13 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -962,30 +798,10 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -997,45 +813,16 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200324203455-a04cca1dde73/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0= google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1063,9 +850,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10= gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1080,18 +866,13 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/main.go b/main.go index 6644729..52f1af3 100644 --- a/main.go +++ b/main.go @@ -2,61 +2,34 @@ package main import ( "context" - "os" - "path/filepath" "github.com/cosmos/cosmos-sdk/client" - "github.com/cosmos/cosmos-sdk/client/flags" - "github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/version" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/sentinel-official/hub" hubtypes "github.com/sentinel-official/hub/types" "github.com/spf13/cobra" - "github.com/spf13/viper" "github.com/sentinel-official/cli-client/cmd" - "github.com/sentinel-official/cli-client/types" - configtypes "github.com/sentinel-official/cli-client/types/config" ) func main() { hubtypes.GetConfig().Seal() + root := &cobra.Command{ - Use: "sentinelcli", - SilenceUsage: true, + Use: "sentinelcli", + SilenceUsage: true, + SuggestionsMinimumDistance: 2, PersistentPreRunE: func(cmd *cobra.Command, args []string) error { var ( - home = viper.GetString(flags.FlagHome) - configPath = filepath.Join(home, "config.toml") - ) - - if _, err := os.Stat(configPath); err != nil { - if err := os.MkdirAll(home, 0700); err != nil { - return err - } - - config := configtypes.NewConfig(). - WithDefaultValues() - if err := config.SaveToPath(configPath); err != nil { - return err - } - } - - var ( - config = hub.MakeEncodingConfig() - clientCtx = client.Context{}. + config = hub.MakeEncodingConfig() + ctx = client.Context{}. WithJSONMarshaler(config.Marshaler). WithInterfaceRegistry(config.InterfaceRegistry). WithTxConfig(config.TxConfig). - WithLegacyAmino(config.Amino). - WithInput(os.Stdin). - WithAccountRetriever(authtypes.AccountRetriever{}). - WithBroadcastMode(flags.BroadcastBlock). - WithHomeDir(types.DefaultHomeDirectory) + WithLegacyAmino(config.Amino) ) - if err := client.SetCmdClientContextHandler(clientCtx, cmd); err != nil { + if err := client.SetCmdClientContextHandler(ctx, cmd); err != nil { return err } @@ -67,16 +40,13 @@ func main() { root.AddCommand( cmd.ConnectCmd(), cmd.DisconnectCmd(), + cmd.KeysCmd(), cmd.QueryCommand(), cmd.StartCmd(), cmd.TxCommand(), - keys.Commands(types.DefaultHomeDirectory), version.NewVersionCommand(), ) - root.PersistentFlags().String(flags.FlagHome, types.DefaultHomeDirectory, "home directory of the application") - _ = viper.BindPFlag(flags.FlagHome, root.PersistentFlags().Lookup(flags.FlagHome)) - _ = root.ExecuteContext( context.WithValue( context.Background(),