diff --git a/README.md b/README.md index 680cf3d..30ec628 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,19 @@ Usage: derocli [command] Available Commands: - all Get all information from the node completion Generate the autocompletion script for the specified shell + console Start an interactive console height Get the current height of the blockchain help Help about any command info Get information about the node peers Get the connected peers from the node + txpool Get the transaction pool + version Print the version info Flags: - -r, --rpc string address of the node (default "localhost:10102") - -h, --help help for derocli + -c, --config string path to the config file + -h, --help help for derocli + -r, --rpc string address of the node (default "localhost:10102") Use "derocli [command] --help" for more information about a command. ``` \ No newline at end of file diff --git a/cmd/all.go b/cmd/all.go deleted file mode 100644 index 9c9e49e..0000000 --- a/cmd/all.go +++ /dev/null @@ -1,48 +0,0 @@ -package cmd - -import ( - "context" - "time" - - "github.com/spf13/cobra" -) - -var timeout = time.Second * 5 - -var allCmd = &cobra.Command{ - Use: "all", - Short: "Get all information from the node", - PreRunE: connectNode, - PostRun: func(cmd *cobra.Command, args []string) { client.Close() }, - RunE: all, -} - -func all(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - height, err := client.GetHeight(ctx) - if err != nil { - return err - } - prettyPrint(height) - - info, err := client.GetInfo(ctx) - if err != nil { - return err - } - prettyPrint(info) - - /* peers, err := client.GetPeers(ctx) - if err != nil { - return err - } - prettyPrint(peers) */ - - txPool, err := client.GetTxPool(ctx) - if err != nil { - return err - } - prettyPrint(txPool) - return nil -} diff --git a/cmd/console.go b/cmd/console.go new file mode 100644 index 0000000..b758bd2 --- /dev/null +++ b/cmd/console.go @@ -0,0 +1,54 @@ +package cmd + +import ( + "context" + "log" + "os" + "os/signal" + "syscall" + + "github.com/spf13/cobra" + "github.com/stratumfarm/derocli/internal/derocli" +) + +var consoleCmd = &cobra.Command{ + Use: "console", + Short: "Start an interactive console", + PreRunE: connectNode, + PostRun: func(cmd *cobra.Command, args []string) { client.Close() }, + RunE: runConsole, +} + +func runConsole(cmd *cobra.Command, args []string) error { + done := make(chan os.Signal, 1) + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + ctx, cancel := context.WithCancel(cmd.Context()) + defer cancel() + + c, err := derocli.New(ctx, client) + if err != nil { + log.Fatalln(err) + } + + errc := make(chan error, 1) + go func() { + defer close(errc) + defer c.Close() + if err := c.Start(); err != nil { + errc <- err + } + }() + + select { + case <-done: + cancel() + case err, ok := <-errc: + if !ok { + break + } + log.Fatalln(err) + } + + return nil +} diff --git a/cmd/height.go b/cmd/height.go index 6700c3b..90d74ff 100644 --- a/cmd/height.go +++ b/cmd/height.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var heightCmd = &cobra.Command{ } func height(cmd *cobra.Command, args []string) error { - height, err := client.GetHeight(context.Background()) + height, err := client.GetHeight(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(height) return nil diff --git a/cmd/info.go b/cmd/info.go index ea0a8a2..9821c56 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var infoCmd = &cobra.Command{ } func info(cmd *cobra.Command, args []string) error { - info, err := client.GetInfo(context.Background()) + info, err := client.GetInfo(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(info) return nil diff --git a/cmd/peers.go b/cmd/peers.go index c0651b5..551d3fe 100644 --- a/cmd/peers.go +++ b/cmd/peers.go @@ -1,6 +1,8 @@ package cmd import ( + "log" + "github.com/spf13/cobra" ) @@ -13,10 +15,10 @@ var peersCmd = &cobra.Command{ } func peers(cmd *cobra.Command, args []string) error { - /* info, err := client.GetPeers(context.Background()) + info, err := client.GetPeers(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } - prettyPrint(info) */ + prettyPrint(info) return nil } diff --git a/cmd/root.go b/cmd/root.go index 84de505..a251588 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -34,7 +34,11 @@ var rootCmd = &cobra.Command{ } func init() { - rootCmd.AddCommand(versionCmd, manCmd, allCmd, heightCmd, infoCmd, peersCmd, txPoolCmd) + rootCmd.AddCommand( + versionCmd, manCmd, + heightCmd, infoCmd, peersCmd, + txPoolCmd, consoleCmd, + ) rootCmd.PersistentFlags().StringVarP(&rootCmdFlags.config, "config", "c", "", "path to the config file") rootCmd.PersistentFlags().StringP("rpc", "r", "localhost:10102", "address of the node") diff --git a/cmd/txpool.go b/cmd/txpool.go index 1974902..b5faa5e 100644 --- a/cmd/txpool.go +++ b/cmd/txpool.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var txPoolCmd = &cobra.Command{ } func txPool(cmd *cobra.Command, args []string) error { - txpool, err := client.GetTxPool(context.Background()) + txpool, err := client.GetTxPool(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(txpool) return nil diff --git a/go.mod b/go.mod index d90905c..511920b 100644 --- a/go.mod +++ b/go.mod @@ -4,17 +4,19 @@ go 1.18 require ( github.com/creachadair/jrpc2 v0.41.0 - github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae github.com/gorilla/websocket v1.5.0 + github.com/jon4hz/console v0.2.1 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 + github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 ) require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/caarlos0/env/v6 v6.9.2 // indirect + github.com/charmbracelet/lipgloss v0.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect @@ -23,13 +25,20 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.10.3 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/muesli/mango v0.1.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect + github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect + github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/peterh/liner v1.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -48,3 +57,5 @@ require ( gopkg.in/yaml.v3 v3.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) + +//replace github.com/jon4hz/console => ../../console diff --git a/go.sum b/go.sum index 916a5ee..9de3271 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/caarlos0/env/v6 v6.9.2 h1:vYTmP7KPtHf3LqaQH5Z2AkUY8GmanDrTelXnFzxSK44= github.com/caarlos0/env/v6 v6.9.2/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= 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= @@ -56,8 +58,6 @@ github.com/creachadair/jrpc2 v0.41.0/go.mod h1:SwEPHK3zqbc5j6AVBVdGoc2QYwYDQUBGn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae h1:DRc6Ah1FlynghElpl++IOWTBQiOIYf2O2HmcifAj3HA= -github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae/go.mod h1:EWHh1VkXRnCHvyGML98kXhngDFYebmOhk/9kZ1ATJ1c= github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1 h1:nsiNx83HYmRmYpYO37pUzSTmB7p9PFtGBl4FyD+a0jg= github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1/go.mod h1:a4u6QJtGGIADg1JwujD77UtaAyhIxg14+I0C7xjyQcc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -164,6 +164,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: 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/jon4hz/console v0.2.1 h1:gTnkJnHaqHKGxUjyl0Uz8phc7IJYznVSzt1gHVAGTJY= +github.com/jon4hz/console v0.2.1/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -179,10 +181,17 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -195,17 +204,26 @@ github.com/muesli/mango-cobra v1.1.0 h1:j/mM5omhC2Vw8pim716aMJVElIRln089XZJ2JY7X github.com/muesli/mango-cobra v1.1.0/go.mod h1:lotV+49eKrAV0tTw/ONhLsiyKwM5uW5QP2OkYw4xlNc= github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe7Sg= github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= +github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -223,6 +241,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 h1:5iETeDNBTrIZj/RecN/WfRtCaanhXlTdfYyR4q2I/18= +github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8/go.mod h1:1fq6tvob4JwDQhdxuUX81DdlID1wYkx4TyJH2ve0J9A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -378,6 +398,8 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/derocli/blockheader.go b/internal/derocli/blockheader.go new file mode 100644 index 0000000..f225adc --- /dev/null +++ b/internal/derocli/blockheader.go @@ -0,0 +1,42 @@ +package derocli + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strconv" + + "github.com/jon4hz/console" +) + +func (c *Console) BlockHeaderByTopoHeight() *console.Cmd { + return &console.Cmd{ + Name: "block_header_by_topo_height", + Aliases: []string{"get_block_header_by_topo_height"}, + Description: "Get the height of the dero node", + Handler: c.blockHeaderByTopoHeightCmd, + } +} + +func (c *Console) blockHeaderByTopoHeightCmd(con *console.Console, args []string) error { + if len(args) != 1 { + return errors.New("exactly one arg is required") + } + height, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err + } + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + blockHeader, err := c.deroClient.GetBlockHeaderByTopoHeight(ctx, height) + if err != nil { + return err + } + data, err := json.MarshalIndent(blockHeader, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/connections.go b/internal/derocli/connections.go new file mode 100644 index 0000000..76625f8 --- /dev/null +++ b/internal/derocli/connections.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) ConnectionsCmd() *console.Cmd { + return &console.Cmd{ + Name: "connections", + Aliases: []string{"get_connections"}, + Description: "Get all connections from the dero node", + Handler: c.handleConnectionsCmd, + } +} + +func (c *Console) handleConnectionsCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + connections, err := c.deroClient.GetConnections(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(connections.Connections, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go new file mode 100644 index 0000000..e44f3cc --- /dev/null +++ b/internal/derocli/derocli.go @@ -0,0 +1,61 @@ +package derocli + +import ( + "context" + "fmt" + "time" + + "github.com/jon4hz/console" + "github.com/stratumfarm/derocli/pkg/dero" +) + +var requestTimeout = 5 * time.Second + +type Console struct { + deroClient *dero.Client + console *console.Console +} + +func New(ctx context.Context, client *dero.Client) (*Console, error) { + if client == nil { + return nil, fmt.Errorf("client is nil") + } + con, err := console.New( + console.WithWelcomeMsg("Welcome to derocli!"), + console.WithHandleCtrlC(false), + console.WithContext(ctx), + ) + if err != nil { + return nil, err + } + c := &Console{ + console: con, + deroClient: client, + } + if err := con.RegisterCommands(c.getCmds()...); err != nil { + return nil, err + } + return c, nil +} + +func (c *Console) Start() error { + return c.console.Start() +} + +func (c *Console) Close() error { + if err := c.deroClient.Close(); err != nil { + return err + } + return c.console.Close() +} + +func (c *Console) getCmds() []*console.Cmd { + return []*console.Cmd{ + c.InfoCmd(), + c.PeersCmd(), + c.ConnectionsCmd(), + c.HeightCmd(), + c.BlockHeaderByTopoHeight(), + c.TxPoolCmd(), + } +} diff --git a/internal/derocli/height.go b/internal/derocli/height.go new file mode 100644 index 0000000..169df1d --- /dev/null +++ b/internal/derocli/height.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) HeightCmd() *console.Cmd { + return &console.Cmd{ + Name: "height", + Aliases: []string{"get_height"}, + Description: "Get the height of the dero node", + Handler: c.heightCmd, + } +} + +func (c *Console) heightCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + height, err := c.deroClient.GetHeight(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(height, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/info.go b/internal/derocli/info.go new file mode 100644 index 0000000..afe78cf --- /dev/null +++ b/internal/derocli/info.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) InfoCmd() *console.Cmd { + return &console.Cmd{ + Name: "info", + Aliases: []string{"get_info"}, + Description: "Get info about the dero node", + Handler: c.handleInfoCmd, + } +} + +func (c *Console) handleInfoCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + info, err := c.deroClient.GetInfo(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(info, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/peers.go b/internal/derocli/peers.go new file mode 100644 index 0000000..a75d3f4 --- /dev/null +++ b/internal/derocli/peers.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) PeersCmd() *console.Cmd { + return &console.Cmd{ + Name: "peers", + Aliases: []string{"get_peers"}, + Description: "Get all peers connected to the dero node", + Handler: c.handlePeersCmd, + } +} + +func (c *Console) handlePeersCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + peers, err := c.deroClient.GetPeers(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(peers, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/txpool.go b/internal/derocli/txpool.go new file mode 100644 index 0000000..7b5a298 --- /dev/null +++ b/internal/derocli/txpool.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) TxPoolCmd() *console.Cmd { + return &console.Cmd{ + Name: "txpool", + Aliases: []string{"get_txpool"}, + Description: "Get the transaction pool", + Handler: c.txPoolCmd, + } +} + +func (c *Console) txPoolCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + txpool, err := c.deroClient.GetTxPool(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(txpool, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/pkg/dero/rpc.go b/pkg/dero/rpc.go index a760985..0583aa1 100644 --- a/pkg/dero/rpc.go +++ b/pkg/dero/rpc.go @@ -7,9 +7,9 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/channel" - "github.com/deroproject/derohe/glue/rwc" - derorpc "github.com/deroproject/derohe/rpc" "github.com/gorilla/websocket" + "github.com/stratumfarm/derohe/glue/rwc" + derorpc "github.com/stratumfarm/derohe/rpc" ) type Client struct { @@ -60,18 +60,37 @@ func (c *Client) GetInfo(ctx context.Context) (*derorpc.GetInfo_Result, error) { return res, nil } -/* func (c *Client) GetPeers(ctx context.Context) (*derop2p.PeersInfo, error) { - res := new(derop2p.PeersInfo) +func (c *Client) GetPeers(ctx context.Context) (*derorpc.GetPeersResult, error) { + res := new(derorpc.GetPeersResult) if err := c.rpc.CallResult(context.Background(), "DERO.GetPeers", nil, res); err != nil { return nil, fmt.Errorf("failed to call: %w", err) } return res, nil -} */ +} -func (c *Client) GetTxPool(ctx context.Context) (derorpc.GetTxPool_Result, error) { +func (c *Client) GetTxPool(ctx context.Context) (*derorpc.GetTxPool_Result, error) { res := new(derorpc.GetTxPool_Result) if err := c.rpc.CallResult(context.Background(), "DERO.GetTxPool", nil, res); err != nil { - return *res, fmt.Errorf("failed to call: %w", err) + return nil, fmt.Errorf("failed to call: %w", err) + } + return res, nil +} + +func (c *Client) GetConnections(ctx context.Context) (*derorpc.GetConnectionResult, error) { + res := new(derorpc.GetConnectionResult) + if err := c.rpc.CallResult(context.Background(), "DERO.GetConnections", nil, res); err != nil { + return nil, fmt.Errorf("failed to call: %w", err) } - return *res, nil + return res, nil +} + +func (c *Client) GetBlockHeaderByTopoHeight(ctx context.Context, height uint64) (*derorpc.GetBlockHeaderByHeight_Result, error) { + res := new(derorpc.GetBlockHeaderByHeight_Result) + req := derorpc.GetBlockHeaderByTopoHeight_Params{ + TopoHeight: height, + } + if err := c.rpc.CallResult(context.Background(), "DERO.GetBlockHeaderByTopoHeight", req, res); err != nil { + return nil, fmt.Errorf("failed to call: %w", err) + } + return res, nil }