github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/client/cli/query.go (about)

     1  package cli
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  
     8  	"github.com/spf13/cobra"
     9  	"github.com/spf13/viper"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    15  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    17  	gcutils "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/client/utils"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types"
    19  )
    20  
    21  // GetQueryCmd returns the cli query commands for this module
    22  func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
    23  	// Group gov queries under a subcommand
    24  	govQueryCmd := &cobra.Command{
    25  		Use:                        types.ModuleName,
    26  		Short:                      "Querying commands for the governance module",
    27  		DisableFlagParsing:         true,
    28  		SuggestionsMinimumDistance: 2,
    29  		RunE:                       client.ValidateCmd,
    30  	}
    31  
    32  	govQueryCmd.AddCommand(flags.GetCommands(
    33  		GetCmdQueryProposal(queryRoute, cdc),
    34  		GetCmdQueryProposals(queryRoute, cdc),
    35  		GetCmdQueryVote(queryRoute, cdc),
    36  		GetCmdQueryVotes(queryRoute, cdc),
    37  		GetCmdQueryParam(queryRoute, cdc),
    38  		GetCmdQueryParams(queryRoute, cdc),
    39  		GetCmdQueryProposer(queryRoute, cdc),
    40  		GetCmdQueryDeposit(queryRoute, cdc),
    41  		GetCmdQueryDeposits(queryRoute, cdc),
    42  		GetCmdQueryTally(queryRoute, cdc))...)
    43  
    44  	return govQueryCmd
    45  }
    46  
    47  // GetCmdQueryProposal implements the query proposal command.
    48  func GetCmdQueryProposal(queryRoute string, cdc *codec.Codec) *cobra.Command {
    49  	return &cobra.Command{
    50  		Use:   "proposal [proposal-id]",
    51  		Args:  cobra.ExactArgs(1),
    52  		Short: "Query details of a single proposal",
    53  		Long: strings.TrimSpace(
    54  			fmt.Sprintf(`Query details for a proposal. You can find the
    55  proposal-id by running "%s query gov proposals".
    56  
    57  Example:
    58  $ %s query gov proposal 1
    59  `,
    60  				version.ClientName, version.ClientName,
    61  			),
    62  		),
    63  		RunE: func(cmd *cobra.Command, args []string) error {
    64  			cliCtx := context.NewCLIContext().WithCodec(cdc)
    65  
    66  			// validate that the proposal id is a uint
    67  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
    68  			if err != nil {
    69  				return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
    70  			}
    71  
    72  			// Query the proposal
    73  			res, err := gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
    74  			if err != nil {
    75  				return err
    76  			}
    77  
    78  			var proposal types.Proposal
    79  			cdc.MustUnmarshalJSON(res, &proposal)
    80  			return cliCtx.PrintOutput(proposal) // nolint:errcheck
    81  		},
    82  	}
    83  }
    84  
    85  // GetCmdQueryProposals implements a query proposals command.
    86  func GetCmdQueryProposals(queryRoute string, cdc *codec.Codec) *cobra.Command {
    87  	cmd := &cobra.Command{
    88  		Use:   "proposals",
    89  		Short: "Query proposals with optional filters",
    90  		Long: strings.TrimSpace(
    91  			fmt.Sprintf(`Query for a all paginated proposals that match optional filters:
    92  
    93  Example:
    94  $ %s query gov proposals --depositor cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
    95  $ %s query gov proposals --voter cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
    96  $ %s query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Rejected)
    97  $ %s query gov proposals --page=2 --limit=100
    98  `,
    99  				version.ClientName, version.ClientName, version.ClientName, version.ClientName,
   100  			),
   101  		),
   102  		RunE: func(cmd *cobra.Command, args []string) error {
   103  			bechDepositorAddr := viper.GetString(flagDepositor)
   104  			bechVoterAddr := viper.GetString(flagVoter)
   105  			strProposalStatus := viper.GetString(flagStatus)
   106  			page := viper.GetInt(flags.FlagPage)
   107  			limit := viper.GetInt(flags.FlagLimit)
   108  
   109  			var depositorAddr sdk.AccAddress
   110  			var voterAddr sdk.AccAddress
   111  			var proposalStatus types.ProposalStatus
   112  
   113  			params := types.NewQueryProposalsParams(page, limit, proposalStatus, voterAddr, depositorAddr)
   114  
   115  			if len(bechDepositorAddr) != 0 {
   116  				depositorAddr, err := sdk.AccAddressFromBech32(bechDepositorAddr)
   117  				if err != nil {
   118  					return err
   119  				}
   120  				params.Depositor = depositorAddr
   121  			}
   122  
   123  			if len(bechVoterAddr) != 0 {
   124  				voterAddr, err := sdk.AccAddressFromBech32(bechVoterAddr)
   125  				if err != nil {
   126  					return err
   127  				}
   128  				params.Voter = voterAddr
   129  			}
   130  
   131  			if len(strProposalStatus) != 0 {
   132  				proposalStatus, err := types.ProposalStatusFromString(gcutils.NormalizeProposalStatus(strProposalStatus))
   133  				if err != nil {
   134  					return err
   135  				}
   136  				params.ProposalStatus = proposalStatus
   137  			}
   138  
   139  			bz, err := cdc.MarshalJSON(params)
   140  			if err != nil {
   141  				return err
   142  			}
   143  
   144  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   145  
   146  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/proposals", queryRoute), bz)
   147  			if err != nil {
   148  				return err
   149  			}
   150  
   151  			var matchingProposals types.Proposals
   152  			err = cdc.UnmarshalJSON(res, &matchingProposals)
   153  			if err != nil {
   154  				return err
   155  			}
   156  
   157  			if len(matchingProposals) == 0 {
   158  				return fmt.Errorf("no matching proposals found")
   159  			}
   160  
   161  			return cliCtx.PrintOutput(matchingProposals) // nolint:errcheck
   162  		},
   163  	}
   164  
   165  	cmd.Flags().Int(flags.FlagPage, 1, "pagination page of proposals to to query for")
   166  	cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of proposals to query for")
   167  	cmd.Flags().String(flagDepositor, "", "(optional) filter by proposals deposited on by depositor")
   168  	cmd.Flags().String(flagVoter, "", "(optional) filter by proposals voted on by voted")
   169  	cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status, status: deposit_period/voting_period/passed/rejected")
   170  
   171  	return cmd
   172  }
   173  
   174  // Command to Get a Proposal Information
   175  // GetCmdQueryVote implements the query proposal vote command.
   176  func GetCmdQueryVote(queryRoute string, cdc *codec.Codec) *cobra.Command {
   177  	return &cobra.Command{
   178  		Use:   "vote [proposal-id] [voter-addr]",
   179  		Args:  cobra.ExactArgs(2),
   180  		Short: "Query details of a single vote",
   181  		Long: strings.TrimSpace(
   182  			fmt.Sprintf(`Query details for a single vote on a proposal given its identifier.
   183  
   184  Example:
   185  $ %s query gov vote 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
   186  `,
   187  				version.ClientName,
   188  			),
   189  		),
   190  		RunE: func(cmd *cobra.Command, args []string) error {
   191  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   192  
   193  			// validate that the proposal id is a uint
   194  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   195  			if err != nil {
   196  				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
   197  			}
   198  
   199  			// check to see if the proposal is in the store
   200  			_, err = gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   201  			if err != nil {
   202  				return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   203  			}
   204  
   205  			voterAddr, err := sdk.AccAddressFromBech32(args[1])
   206  			if err != nil {
   207  				return err
   208  			}
   209  
   210  			params := types.NewQueryVoteParams(proposalID, voterAddr)
   211  			bz, err := cdc.MarshalJSON(params)
   212  			if err != nil {
   213  				return err
   214  			}
   215  
   216  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/vote", queryRoute), bz)
   217  			if err != nil {
   218  				return err
   219  			}
   220  
   221  			var vote types.Vote
   222  
   223  			// XXX: Allow the decoding to potentially fail as the vote may have been
   224  			// pruned from state. If so, decoding will fail and so we need to check the
   225  			// Empty() case. Consider updating Vote JSON decoding to not fail when empty.
   226  			_ = cdc.UnmarshalJSON(res, &vote)
   227  
   228  			if vote.Empty() {
   229  				res, err = gcutils.QueryVoteByTxQuery(cliCtx, params)
   230  				if err != nil {
   231  					return err
   232  				}
   233  
   234  				if err := cdc.UnmarshalJSON(res, &vote); err != nil {
   235  					return err
   236  				}
   237  			}
   238  
   239  			return cliCtx.PrintOutput(vote)
   240  		},
   241  	}
   242  }
   243  
   244  // GetCmdQueryVotes implements the command to query for proposal votes.
   245  func GetCmdQueryVotes(queryRoute string, cdc *codec.Codec) *cobra.Command {
   246  	cmd := &cobra.Command{
   247  		Use:   "votes [proposal-id]",
   248  		Args:  cobra.ExactArgs(1),
   249  		Short: "Query votes on a proposal",
   250  		Long: strings.TrimSpace(
   251  			fmt.Sprintf(`Query vote details for a single proposal by its identifier.
   252  
   253  Example:
   254  $ %[1]s query gov votes 1
   255  $ %[1]s query gov votes 1 --page=2 --limit=100
   256  `,
   257  				version.ClientName,
   258  			),
   259  		),
   260  		RunE: func(cmd *cobra.Command, args []string) error {
   261  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   262  
   263  			// validate that the proposal id is a uint
   264  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   265  			if err != nil {
   266  				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
   267  			}
   268  
   269  			page := viper.GetInt(flags.FlagPage)
   270  			limit := viper.GetInt(flags.FlagLimit)
   271  
   272  			params := types.NewQueryProposalVotesParams(proposalID, page, limit)
   273  			bz, err := cdc.MarshalJSON(params)
   274  			if err != nil {
   275  				return err
   276  			}
   277  
   278  			// check to see if the proposal is in the store
   279  			res, err := gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   280  			if err != nil {
   281  				return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   282  			}
   283  
   284  			var proposal types.Proposal
   285  			cdc.MustUnmarshalJSON(res, &proposal)
   286  
   287  			propStatus := proposal.Status
   288  			if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) {
   289  				res, err = gcutils.QueryVotesByTxQuery(cliCtx, params)
   290  			} else {
   291  				res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/votes", queryRoute), bz)
   292  			}
   293  
   294  			if err != nil {
   295  				return err
   296  			}
   297  
   298  			var votes types.Votes
   299  			cdc.MustUnmarshalJSON(res, &votes)
   300  			return cliCtx.PrintOutput(votes)
   301  		},
   302  	}
   303  	cmd.Flags().Int(flags.FlagPage, 1, "pagination page of votes to to query for")
   304  	cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of votes to query for")
   305  	return cmd
   306  }
   307  
   308  // Command to Get a specific Deposit Information
   309  // GetCmdQueryDeposit implements the query proposal deposit command.
   310  func GetCmdQueryDeposit(queryRoute string, cdc *codec.Codec) *cobra.Command {
   311  	return &cobra.Command{
   312  		Use:   "deposit [proposal-id] [depositer-addr]",
   313  		Args:  cobra.ExactArgs(2),
   314  		Short: "Query details of a deposit",
   315  		Long: strings.TrimSpace(
   316  			fmt.Sprintf(`Query details for a single proposal deposit on a proposal by its identifier.
   317  
   318  Example:
   319  $ %s query gov deposit 1 cosmos1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk
   320  `,
   321  				version.ClientName,
   322  			),
   323  		),
   324  		RunE: func(cmd *cobra.Command, args []string) error {
   325  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   326  
   327  			// validate that the proposal id is a uint
   328  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   329  			if err != nil {
   330  				return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
   331  			}
   332  
   333  			// check to see if the proposal is in the store
   334  			_, err = gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   335  			if err != nil {
   336  				return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   337  			}
   338  
   339  			depositorAddr, err := sdk.AccAddressFromBech32(args[1])
   340  			if err != nil {
   341  				return err
   342  			}
   343  
   344  			params := types.NewQueryDepositParams(proposalID, depositorAddr)
   345  			bz, err := cdc.MarshalJSON(params)
   346  			if err != nil {
   347  				return err
   348  			}
   349  
   350  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposit", queryRoute), bz)
   351  			if err != nil {
   352  				return err
   353  			}
   354  
   355  			var deposit types.Deposit
   356  			cdc.MustUnmarshalJSON(res, &deposit)
   357  
   358  			if deposit.Empty() {
   359  				res, err = gcutils.QueryDepositByTxQuery(cliCtx, params)
   360  				if err != nil {
   361  					return err
   362  				}
   363  				cdc.MustUnmarshalJSON(res, &deposit)
   364  			}
   365  
   366  			return cliCtx.PrintOutput(deposit)
   367  		},
   368  	}
   369  }
   370  
   371  // GetCmdQueryDeposits implements the command to query for proposal deposits.
   372  func GetCmdQueryDeposits(queryRoute string, cdc *codec.Codec) *cobra.Command {
   373  	return &cobra.Command{
   374  		Use:   "deposits [proposal-id]",
   375  		Args:  cobra.ExactArgs(1),
   376  		Short: "Query deposits on a proposal",
   377  		Long: strings.TrimSpace(
   378  			fmt.Sprintf(`Query details for all deposits on a proposal.
   379  You can find the proposal-id by running "%s query gov proposals".
   380  
   381  Example:
   382  $ %s query gov deposits 1
   383  `,
   384  				version.ClientName, version.ClientName,
   385  			),
   386  		),
   387  		RunE: func(cmd *cobra.Command, args []string) error {
   388  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   389  
   390  			// validate that the proposal id is a uint
   391  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   392  			if err != nil {
   393  				return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
   394  			}
   395  
   396  			params := types.NewQueryProposalParams(proposalID)
   397  			bz, err := cdc.MarshalJSON(params)
   398  			if err != nil {
   399  				return err
   400  			}
   401  
   402  			// check to see if the proposal is in the store
   403  			res, err := gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   404  			if err != nil {
   405  				return fmt.Errorf("failed to fetch proposal with id %d: %s", proposalID, err)
   406  			}
   407  
   408  			var proposal types.Proposal
   409  			cdc.MustUnmarshalJSON(res, &proposal)
   410  
   411  			propStatus := proposal.Status
   412  			if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) {
   413  				res, err = gcutils.QueryDepositsByTxQuery(cliCtx, params)
   414  			} else {
   415  				res, _, err = cliCtx.QueryWithData(fmt.Sprintf("custom/%s/deposits", queryRoute), bz)
   416  			}
   417  
   418  			if err != nil {
   419  				return err
   420  			}
   421  
   422  			var dep types.Deposits
   423  			cdc.MustUnmarshalJSON(res, &dep)
   424  			return cliCtx.PrintOutput(dep)
   425  		},
   426  	}
   427  }
   428  
   429  // GetCmdQueryTally implements the command to query for proposal tally result.
   430  func GetCmdQueryTally(queryRoute string, cdc *codec.Codec) *cobra.Command {
   431  	return &cobra.Command{
   432  		Use:   "tally [proposal-id]",
   433  		Args:  cobra.ExactArgs(1),
   434  		Short: "Get the tally of a proposal vote",
   435  		Long: strings.TrimSpace(
   436  			fmt.Sprintf(`Query tally of votes on a proposal. You can find
   437  the proposal-id by running "%s query gov proposals".
   438  
   439  Example:
   440  $ %s query gov tally 1
   441  `,
   442  				version.ClientName, version.ClientName,
   443  			),
   444  		),
   445  		RunE: func(cmd *cobra.Command, args []string) error {
   446  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   447  
   448  			// validate that the proposal id is a uint
   449  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   450  			if err != nil {
   451  				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
   452  			}
   453  
   454  			// check to see if the proposal is in the store
   455  			_, err = gcutils.QueryProposalByID(proposalID, cliCtx, queryRoute)
   456  			if err != nil {
   457  				return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err)
   458  			}
   459  
   460  			// Construct query
   461  			params := types.NewQueryProposalParams(proposalID)
   462  			bz, err := cdc.MarshalJSON(params)
   463  			if err != nil {
   464  				return err
   465  			}
   466  
   467  			// Query store
   468  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/tally", queryRoute), bz)
   469  			if err != nil {
   470  				return err
   471  			}
   472  
   473  			var tally types.TallyResult
   474  			cdc.MustUnmarshalJSON(res, &tally)
   475  			return cliCtx.PrintOutput(tally)
   476  		},
   477  	}
   478  }
   479  
   480  // GetCmdQueryProposal implements the query proposal command.
   481  func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
   482  	return &cobra.Command{
   483  		Use:   "params",
   484  		Short: "Query the parameters of the governance process",
   485  		Long: strings.TrimSpace(
   486  			fmt.Sprintf(`Query the all the parameters for the governance process.
   487  
   488  Example:
   489  $ %s query gov params
   490  `,
   491  				version.ClientName,
   492  			),
   493  		),
   494  		Args: cobra.NoArgs,
   495  		RunE: func(cmd *cobra.Command, args []string) error {
   496  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   497  			tp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/tallying", queryRoute), nil)
   498  			if err != nil {
   499  				return err
   500  			}
   501  			dp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/deposit", queryRoute), nil)
   502  			if err != nil {
   503  				return err
   504  			}
   505  			vp, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/voting", queryRoute), nil)
   506  			if err != nil {
   507  				return err
   508  			}
   509  
   510  			var tallyParams types.TallyParams
   511  			cdc.MustUnmarshalJSON(tp, &tallyParams)
   512  			var depositParams types.DepositParams
   513  			cdc.MustUnmarshalJSON(dp, &depositParams)
   514  			var votingParams types.VotingParams
   515  			cdc.MustUnmarshalJSON(vp, &votingParams)
   516  
   517  			return cliCtx.PrintOutput(types.NewParams(votingParams, tallyParams, depositParams))
   518  		},
   519  	}
   520  }
   521  
   522  // GetCmdQueryProposal implements the query proposal command.
   523  func GetCmdQueryParam(queryRoute string, cdc *codec.Codec) *cobra.Command {
   524  	return &cobra.Command{
   525  		Use:   "param [param-type]",
   526  		Args:  cobra.ExactArgs(1),
   527  		Short: "Query the parameters (voting|tallying|deposit) of the governance process",
   528  		Long: strings.TrimSpace(
   529  			fmt.Sprintf(`Query the all the parameters for the governance process.
   530  
   531  Example:
   532  $ %s query gov param voting
   533  $ %s query gov param tallying
   534  $ %s query gov param deposit
   535  `,
   536  				version.ClientName, version.ClientName, version.ClientName,
   537  			),
   538  		),
   539  		RunE: func(cmd *cobra.Command, args []string) error {
   540  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   541  
   542  			// Query store
   543  			res, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/params/%s", queryRoute, args[0]), nil)
   544  			if err != nil {
   545  				return err
   546  			}
   547  			var out fmt.Stringer
   548  			switch args[0] {
   549  			case "voting":
   550  				var param types.VotingParams
   551  				cdc.MustUnmarshalJSON(res, &param)
   552  				out = param
   553  			case "tallying":
   554  				var param types.TallyParams
   555  				cdc.MustUnmarshalJSON(res, &param)
   556  				out = param
   557  			case "deposit":
   558  				var param types.DepositParams
   559  				cdc.MustUnmarshalJSON(res, &param)
   560  				out = param
   561  			default:
   562  				return fmt.Errorf("argument must be one of (voting|tallying|deposit), was %s", args[0])
   563  			}
   564  
   565  			return cliCtx.PrintOutput(out)
   566  		},
   567  	}
   568  }
   569  
   570  // GetCmdQueryProposer implements the query proposer command.
   571  func GetCmdQueryProposer(queryRoute string, cdc *codec.Codec) *cobra.Command {
   572  	return &cobra.Command{
   573  		Use:   "proposer [proposal-id]",
   574  		Args:  cobra.ExactArgs(1),
   575  		Short: "Query the proposer of a governance proposal",
   576  		Long: strings.TrimSpace(
   577  			fmt.Sprintf(`Query which address proposed a proposal with a given ID.
   578  
   579  Example:
   580  $ %s query gov proposer 1
   581  `,
   582  				version.ClientName,
   583  			),
   584  		),
   585  		RunE: func(cmd *cobra.Command, args []string) error {
   586  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   587  
   588  			// validate that the proposalID is a uint
   589  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   590  			if err != nil {
   591  				return fmt.Errorf("proposal-id %s is not a valid uint", args[0])
   592  			}
   593  
   594  			prop, err := gcutils.QueryProposerByTxQuery(cliCtx, proposalID)
   595  			if err != nil {
   596  				return err
   597  			}
   598  
   599  			return cliCtx.PrintOutput(prop)
   600  		},
   601  	}
   602  }
   603  
   604  // DONTCOVER