diff --git a/main.go b/main.go index ffc823f..abd6436 100644 --- a/main.go +++ b/main.go @@ -14,11 +14,12 @@ var Version = "v0.0.0-dev" // generated at build time func main() { app := &cli.App{ - Name: "cosmos-validator-watcher", - Usage: "Real-time Cosmos-based chains monitoring tool", - Flags: app.Flags, - Action: app.RunFunc, - Version: Version, + Name: "cosmos-validator-watcher", + Usage: "Real-time Cosmos-based chains monitoring tool", + Flags: app.Flags, + Action: app.RunFunc, + Commands: app.Commands, + Version: Version, } if err := app.Run(os.Args); err != nil && !errors.Is(err, context.Canceled) { diff --git a/pkg/app/cmd.go b/pkg/app/cmd.go new file mode 100644 index 0000000..d5b98ac --- /dev/null +++ b/pkg/app/cmd.go @@ -0,0 +1,27 @@ +package app + +import "github.com/urfave/cli/v2" + +var Commands = []*cli.Command{ + { + Name: "debug", + Usage: "Debug utilities", + Subcommands: []*cli.Command{ + { + Name: "consensus-key", + Action: DebugConsensusKeyRun, + Flags: Flags, + }, + { + Name: "denom", + Action: DebugDenomRun, + Flags: Flags, + }, + { + Name: "validator", + Action: DebugValidatorRun, + Flags: Flags, + }, + }, + }, +} diff --git a/pkg/app/debug.go b/pkg/app/debug.go new file mode 100644 index 0000000..56500fa --- /dev/null +++ b/pkg/app/debug.go @@ -0,0 +1,130 @@ +package app + +import ( + "fmt" + + "github.com/cometbft/cometbft/rpc/client/http" + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + bank "github.com/cosmos/cosmos-sdk/x/bank/types" + staking "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/urfave/cli/v2" +) + +func DebugDenomRun(cCtx *cli.Context) error { + var ( + ctx = cCtx.Context + nodes = cCtx.StringSlice("node") + ) + + if len(nodes) < 1 { + return cli.Exit("at least one node must be specified", 1) + } + + endpoint := nodes[0] + + rpcClient, err := http.New(endpoint, "/websocket") + if err != nil { + return fmt.Errorf("failed to create client: %w", err) + } + + clientCtx := (client.Context{}).WithClient(rpcClient) + queryClient := bank.NewQueryClient(clientCtx) + + resp, err := queryClient.DenomsMetadata(ctx, &bank.QueryDenomsMetadataRequest{}) + if err != nil { + return err + } + + cdc := codec.NewLegacyAmino() + j, err := cdc.MarshalJSONIndent(resp.Metadatas, "", " ") + fmt.Println(string(j)) + + return nil +} + +func DebugValidatorRun(cCtx *cli.Context) error { + var ( + ctx = cCtx.Context + nodes = cCtx.StringSlice("node") + ) + + println("FIRST ARG", cCtx.Args().Get(0)) + + if cCtx.Args().Len() < 1 { + return cli.Exit("validator address must be specified", 1) + } + if len(nodes) < 1 { + return cli.Exit("at least one node must be specified", 1) + } + + endpoint := nodes[0] + validatorAddr := cCtx.Args().First() + + rpcClient, err := http.New(endpoint, "/websocket") + if err != nil { + return fmt.Errorf("failed to create client: %w", err) + } + + clientCtx := (client.Context{}).WithClient(rpcClient) + queryClient := staking.NewQueryClient(clientCtx) + + resp, err := queryClient.Validator(ctx, &staking.QueryValidatorRequest{ + ValidatorAddr: validatorAddr, + }) + if err != nil { + return err + } + + val := resp.Validator + + cdc := codec.NewLegacyAmino() + j, err := cdc.MarshalJSONIndent(val, "", " ") + if err != nil { + return err + } + fmt.Println(string(j)) + + return nil +} + +func DebugConsensusKeyRun(cCtx *cli.Context) error { + var ( + ctx = cCtx.Context + nodes = cCtx.StringSlice("node") + ) + + if cCtx.Args().Len() < 1 { + return cli.Exit("validator address must be specified", 1) + } + if len(nodes) < 1 { + return cli.Exit("at least one node must be specified", 1) + } + + endpoint := nodes[0] + validatorAddr := cCtx.Args().First() + + rpcClient, err := http.New(endpoint, "/websocket") + if err != nil { + return fmt.Errorf("failed to create client: %w", err) + } + + clientCtx := (client.Context{}).WithClient(rpcClient) + queryClient := staking.NewQueryClient(clientCtx) + + resp, err := queryClient.Validator(ctx, &staking.QueryValidatorRequest{ + ValidatorAddr: validatorAddr, + }) + if err != nil { + return err + } + + val := resp.Validator + pubkey := ed25519.PubKey{Key: val.ConsensusPubkey.Value[2:]} + address := pubkey.Address().String() + + fmt.Println(address) + + return nil +}