github.com/Finschia/finschia-sdk@v0.48.1/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 10 "github.com/Finschia/finschia-sdk/client" 11 "github.com/Finschia/finschia-sdk/client/flags" 12 sdk "github.com/Finschia/finschia-sdk/types" 13 "github.com/Finschia/finschia-sdk/version" 14 gcutils "github.com/Finschia/finschia-sdk/x/gov/client/utils" 15 "github.com/Finschia/finschia-sdk/x/gov/types" 16 ) 17 18 // GetQueryCmd returns the cli query commands for this module 19 func GetQueryCmd() *cobra.Command { 20 // Group gov queries under a subcommand 21 govQueryCmd := &cobra.Command{ 22 Use: types.ModuleName, 23 Short: "Querying commands for the governance module", 24 DisableFlagParsing: true, 25 SuggestionsMinimumDistance: 2, 26 RunE: client.ValidateCmd, 27 } 28 29 govQueryCmd.AddCommand( 30 GetCmdQueryProposal(), 31 GetCmdQueryProposals(), 32 GetCmdQueryVote(), 33 GetCmdQueryVotes(), 34 GetCmdQueryParam(), 35 GetCmdQueryParams(), 36 GetCmdQueryProposer(), 37 GetCmdQueryDeposit(), 38 GetCmdQueryDeposits(), 39 GetCmdQueryTally(), 40 ) 41 42 return govQueryCmd 43 } 44 45 // GetCmdQueryProposal implements the query proposal command. 46 func GetCmdQueryProposal() *cobra.Command { 47 cmd := &cobra.Command{ 48 Use: "proposal [proposal-id]", 49 Args: cobra.ExactArgs(1), 50 Short: "Query details of a single proposal", 51 Long: strings.TrimSpace( 52 fmt.Sprintf(`Query details for a proposal. You can find the 53 proposal-id by running "%s query gov proposals". 54 55 Example: 56 $ %s query gov proposal 1 57 `, 58 version.AppName, version.AppName, 59 ), 60 ), 61 RunE: func(cmd *cobra.Command, args []string) error { 62 clientCtx, err := client.GetClientQueryContext(cmd) 63 if err != nil { 64 return err 65 } 66 queryClient := types.NewQueryClient(clientCtx) 67 68 // validate that the proposal id is a uint 69 proposalID, err := strconv.ParseUint(args[0], 10, 64) 70 if err != nil { 71 return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0]) 72 } 73 74 // Query the proposal 75 res, err := queryClient.Proposal( 76 cmd.Context(), 77 &types.QueryProposalRequest{ProposalId: proposalID}, 78 ) 79 if err != nil { 80 return err 81 } 82 83 return clientCtx.PrintProto(&res.Proposal) 84 }, 85 } 86 87 flags.AddQueryFlagsToCmd(cmd) 88 89 return cmd 90 } 91 92 // GetCmdQueryProposals implements a query proposals command. Command to Get a 93 // Proposal Information. 94 func GetCmdQueryProposals() *cobra.Command { 95 cmd := &cobra.Command{ 96 Use: "proposals", 97 Args: cobra.NoArgs, 98 Short: "Query proposals with optional filters", 99 Long: strings.TrimSpace( 100 fmt.Sprintf(`Query for a all paginated proposals that match optional filters: 101 102 Example: 103 $ %s query gov proposals --depositor link1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk 104 $ %s query gov proposals --voter link1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk 105 $ %s query gov proposals --status (DepositPeriod|VotingPeriod|Passed|Rejected) 106 $ %s query gov proposals --page=2 --limit=100 107 `, 108 version.AppName, version.AppName, version.AppName, version.AppName, 109 ), 110 ), 111 RunE: func(cmd *cobra.Command, args []string) error { 112 bechDepositorAddr, _ := cmd.Flags().GetString(flagDepositor) 113 bechVoterAddr, _ := cmd.Flags().GetString(flagVoter) 114 strProposalStatus, _ := cmd.Flags().GetString(flagStatus) 115 116 var proposalStatus types.ProposalStatus 117 118 if len(bechDepositorAddr) != 0 { 119 _, err := sdk.AccAddressFromBech32(bechDepositorAddr) 120 if err != nil { 121 return err 122 } 123 } 124 125 if len(bechVoterAddr) != 0 { 126 _, err := sdk.AccAddressFromBech32(bechVoterAddr) 127 if err != nil { 128 return err 129 } 130 } 131 132 if len(strProposalStatus) != 0 { 133 proposalStatus1, err := types.ProposalStatusFromString(gcutils.NormalizeProposalStatus(strProposalStatus)) 134 proposalStatus = proposalStatus1 135 if err != nil { 136 return err 137 } 138 } 139 140 clientCtx, err := client.GetClientQueryContext(cmd) 141 if err != nil { 142 return err 143 } 144 queryClient := types.NewQueryClient(clientCtx) 145 146 pageReq, err := client.ReadPageRequest(cmd.Flags()) 147 if err != nil { 148 return err 149 } 150 151 res, err := queryClient.Proposals( 152 cmd.Context(), 153 &types.QueryProposalsRequest{ 154 ProposalStatus: proposalStatus, 155 Voter: bechVoterAddr, 156 Depositor: bechDepositorAddr, 157 Pagination: pageReq, 158 }, 159 ) 160 if err != nil { 161 return err 162 } 163 164 if len(res.GetProposals()) == 0 { 165 return fmt.Errorf("no proposals found") 166 } 167 168 return clientCtx.PrintProto(res) 169 }, 170 } 171 172 cmd.Flags().String(flagDepositor, "", "(optional) filter by proposals deposited on by depositor") 173 cmd.Flags().String(flagVoter, "", "(optional) filter by proposals voted on by voted") 174 cmd.Flags().String(flagStatus, "", "(optional) filter proposals by proposal status, status: deposit_period/voting_period/passed/rejected") 175 flags.AddPaginationFlagsToCmd(cmd, "proposals") 176 flags.AddQueryFlagsToCmd(cmd) 177 178 return cmd 179 } 180 181 // GetCmdQueryVote implements the query proposal vote command. Command to Get a 182 // Proposal Information. 183 func GetCmdQueryVote() *cobra.Command { 184 cmd := &cobra.Command{ 185 Use: "vote [proposal-id] [voter-addr]", 186 Args: cobra.ExactArgs(2), 187 Short: "Query details of a single vote", 188 Long: strings.TrimSpace( 189 fmt.Sprintf(`Query details for a single vote on a proposal given its identifier. 190 191 Example: 192 $ %s query gov vote 1 link1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk 193 `, 194 version.AppName, 195 ), 196 ), 197 RunE: func(cmd *cobra.Command, args []string) error { 198 clientCtx, err := client.GetClientQueryContext(cmd) 199 if err != nil { 200 return err 201 } 202 queryClient := types.NewQueryClient(clientCtx) 203 204 // validate that the proposal id is a uint 205 proposalID, err := strconv.ParseUint(args[0], 10, 64) 206 if err != nil { 207 return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0]) 208 } 209 210 // check to see if the proposal is in the store 211 ctx := cmd.Context() 212 _, err = queryClient.Proposal( 213 ctx, 214 &types.QueryProposalRequest{ProposalId: proposalID}, 215 ) 216 if err != nil { 217 return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err) 218 } 219 220 voterAddr, err := sdk.AccAddressFromBech32(args[1]) 221 if err != nil { 222 return err 223 } 224 225 res, err := queryClient.Vote( 226 ctx, 227 &types.QueryVoteRequest{ProposalId: proposalID, Voter: args[1]}, 228 ) 229 if err != nil { 230 return err 231 } 232 233 vote := res.GetVote() 234 if vote.Empty() { 235 params := types.NewQueryVoteParams(proposalID, voterAddr) 236 resByTxQuery, err := gcutils.QueryVoteByTxQuery(clientCtx, params) 237 if err != nil { 238 return err 239 } 240 241 if err := clientCtx.Codec.UnmarshalJSON(resByTxQuery, &vote); err != nil { 242 return err 243 } 244 } 245 246 return clientCtx.PrintProto(&res.Vote) 247 }, 248 } 249 250 flags.AddQueryFlagsToCmd(cmd) 251 252 return cmd 253 } 254 255 // GetCmdQueryVotes implements the command to query for proposal votes. 256 func GetCmdQueryVotes() *cobra.Command { 257 cmd := &cobra.Command{ 258 Use: "votes [proposal-id]", 259 Args: cobra.ExactArgs(1), 260 Short: "Query votes on a proposal", 261 Long: strings.TrimSpace( 262 fmt.Sprintf(`Query vote details for a single proposal by its identifier. 263 264 Example: 265 $ %[1]s query gov votes 1 266 $ %[1]s query gov votes 1 --page=2 --limit=100 267 `, 268 version.AppName, 269 ), 270 ), 271 RunE: func(cmd *cobra.Command, args []string) error { 272 clientCtx, err := client.GetClientQueryContext(cmd) 273 if err != nil { 274 return err 275 } 276 queryClient := types.NewQueryClient(clientCtx) 277 278 // validate that the proposal id is a uint 279 proposalID, err := strconv.ParseUint(args[0], 10, 64) 280 if err != nil { 281 return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0]) 282 } 283 284 // check to see if the proposal is in the store 285 ctx := cmd.Context() 286 proposalRes, err := queryClient.Proposal( 287 ctx, 288 &types.QueryProposalRequest{ProposalId: proposalID}, 289 ) 290 if err != nil { 291 return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err) 292 } 293 294 propStatus := proposalRes.GetProposal().Status 295 if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { 296 page, _ := cmd.Flags().GetInt(flags.FlagPage) 297 limit, _ := cmd.Flags().GetInt(flags.FlagLimit) 298 299 params := types.NewQueryProposalVotesParams(proposalID, page, limit) 300 resByTxQuery, err := gcutils.QueryVotesByTxQuery(clientCtx, params) 301 if err != nil { 302 return err 303 } 304 305 var votes types.Votes 306 // TODO migrate to use JSONCodec (implement MarshalJSONArray 307 // or wrap lists of proto.Message in some other message) 308 clientCtx.LegacyAmino.MustUnmarshalJSON(resByTxQuery, &votes) 309 return clientCtx.PrintObjectLegacy(votes) 310 311 } 312 313 pageReq, err := client.ReadPageRequest(cmd.Flags()) 314 if err != nil { 315 return err 316 } 317 318 res, err := queryClient.Votes( 319 ctx, 320 &types.QueryVotesRequest{ProposalId: proposalID, Pagination: pageReq}, 321 ) 322 if err != nil { 323 return err 324 } 325 326 return clientCtx.PrintProto(res) 327 }, 328 } 329 330 flags.AddPaginationFlagsToCmd(cmd, "votes") 331 flags.AddQueryFlagsToCmd(cmd) 332 333 return cmd 334 } 335 336 // GetCmdQueryDeposit implements the query proposal deposit command. Command to 337 // get a specific Deposit Information 338 func GetCmdQueryDeposit() *cobra.Command { 339 cmd := &cobra.Command{ 340 Use: "deposit [proposal-id] [depositer-addr]", 341 Args: cobra.ExactArgs(2), 342 Short: "Query details of a deposit", 343 Long: strings.TrimSpace( 344 fmt.Sprintf(`Query details for a single proposal deposit on a proposal by its identifier. 345 346 Example: 347 $ %s query gov deposit 1 link1skjwj5whet0lpe65qaq4rpq03hjxlwd9nf39lk 348 `, 349 version.AppName, 350 ), 351 ), 352 RunE: func(cmd *cobra.Command, args []string) error { 353 clientCtx, err := client.GetClientQueryContext(cmd) 354 if err != nil { 355 return err 356 } 357 queryClient := types.NewQueryClient(clientCtx) 358 359 // validate that the proposal id is a uint 360 proposalID, err := strconv.ParseUint(args[0], 10, 64) 361 if err != nil { 362 return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0]) 363 } 364 365 // check to see if the proposal is in the store 366 ctx := cmd.Context() 367 proposalRes, err := queryClient.Proposal( 368 ctx, 369 &types.QueryProposalRequest{ProposalId: proposalID}, 370 ) 371 if err != nil { 372 return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err) 373 } 374 375 depositorAddr, err := sdk.AccAddressFromBech32(args[1]) 376 if err != nil { 377 return err 378 } 379 380 var deposit types.Deposit 381 propStatus := proposalRes.Proposal.Status 382 if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { 383 params := types.NewQueryDepositParams(proposalID, depositorAddr) 384 resByTxQuery, err := gcutils.QueryDepositByTxQuery(clientCtx, params) 385 if err != nil { 386 return err 387 } 388 clientCtx.Codec.MustUnmarshalJSON(resByTxQuery, &deposit) 389 return clientCtx.PrintProto(&deposit) 390 } 391 392 res, err := queryClient.Deposit( 393 ctx, 394 &types.QueryDepositRequest{ProposalId: proposalID, Depositor: args[1]}, 395 ) 396 if err != nil { 397 return err 398 } 399 400 return clientCtx.PrintProto(&res.Deposit) 401 }, 402 } 403 404 flags.AddQueryFlagsToCmd(cmd) 405 406 return cmd 407 } 408 409 // GetCmdQueryDeposits implements the command to query for proposal deposits. 410 func GetCmdQueryDeposits() *cobra.Command { 411 cmd := &cobra.Command{ 412 Use: "deposits [proposal-id]", 413 Args: cobra.ExactArgs(1), 414 Short: "Query deposits on a proposal", 415 Long: strings.TrimSpace( 416 fmt.Sprintf(`Query details for all deposits on a proposal. 417 You can find the proposal-id by running "%s query gov proposals". 418 419 Example: 420 $ %s query gov deposits 1 421 `, 422 version.AppName, version.AppName, 423 ), 424 ), 425 RunE: func(cmd *cobra.Command, args []string) error { 426 clientCtx, err := client.GetClientQueryContext(cmd) 427 if err != nil { 428 return err 429 } 430 queryClient := types.NewQueryClient(clientCtx) 431 432 // validate that the proposal id is a uint 433 proposalID, err := strconv.ParseUint(args[0], 10, 64) 434 if err != nil { 435 return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0]) 436 } 437 438 // check to see if the proposal is in the store 439 ctx := cmd.Context() 440 proposalRes, err := queryClient.Proposal( 441 ctx, 442 &types.QueryProposalRequest{ProposalId: proposalID}, 443 ) 444 if err != nil { 445 return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err) 446 } 447 448 propStatus := proposalRes.GetProposal().Status 449 if !(propStatus == types.StatusVotingPeriod || propStatus == types.StatusDepositPeriod) { 450 params := types.NewQueryProposalParams(proposalID) 451 resByTxQuery, err := gcutils.QueryDepositsByTxQuery(clientCtx, params) 452 if err != nil { 453 return err 454 } 455 456 var dep types.Deposits 457 // TODO migrate to use JSONCodec (implement MarshalJSONArray 458 // or wrap lists of proto.Message in some other message) 459 clientCtx.LegacyAmino.MustUnmarshalJSON(resByTxQuery, &dep) 460 461 return clientCtx.PrintObjectLegacy(dep) 462 } 463 464 pageReq, err := client.ReadPageRequest(cmd.Flags()) 465 if err != nil { 466 return err 467 } 468 469 res, err := queryClient.Deposits( 470 ctx, 471 &types.QueryDepositsRequest{ProposalId: proposalID, Pagination: pageReq}, 472 ) 473 if err != nil { 474 return err 475 } 476 477 return clientCtx.PrintProto(res) 478 }, 479 } 480 481 flags.AddPaginationFlagsToCmd(cmd, "deposits") 482 flags.AddQueryFlagsToCmd(cmd) 483 484 return cmd 485 } 486 487 // GetCmdQueryTally implements the command to query for proposal tally result. 488 func GetCmdQueryTally() *cobra.Command { 489 cmd := &cobra.Command{ 490 Use: "tally [proposal-id]", 491 Args: cobra.ExactArgs(1), 492 Short: "Get the tally of a proposal vote", 493 Long: strings.TrimSpace( 494 fmt.Sprintf(`Query tally of votes on a proposal. You can find 495 the proposal-id by running "%s query gov proposals". 496 497 Example: 498 $ %s query gov tally 1 499 `, 500 version.AppName, version.AppName, 501 ), 502 ), 503 RunE: func(cmd *cobra.Command, args []string) error { 504 clientCtx, err := client.GetClientQueryContext(cmd) 505 if err != nil { 506 return err 507 } 508 queryClient := types.NewQueryClient(clientCtx) 509 510 // validate that the proposal id is a uint 511 proposalID, err := strconv.ParseUint(args[0], 10, 64) 512 if err != nil { 513 return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0]) 514 } 515 516 // check to see if the proposal is in the store 517 ctx := cmd.Context() 518 _, err = queryClient.Proposal( 519 ctx, 520 &types.QueryProposalRequest{ProposalId: proposalID}, 521 ) 522 if err != nil { 523 return fmt.Errorf("failed to fetch proposal-id %d: %s", proposalID, err) 524 } 525 526 // Query store 527 res, err := queryClient.TallyResult( 528 ctx, 529 &types.QueryTallyResultRequest{ProposalId: proposalID}, 530 ) 531 if err != nil { 532 return err 533 } 534 535 return clientCtx.PrintProto(&res.Tally) 536 }, 537 } 538 539 flags.AddQueryFlagsToCmd(cmd) 540 541 return cmd 542 } 543 544 // GetCmdQueryParams implements the query params command. 545 func GetCmdQueryParams() *cobra.Command { 546 cmd := &cobra.Command{ 547 Use: "params", 548 Short: "Query the parameters of the governance process", 549 Long: strings.TrimSpace( 550 fmt.Sprintf(`Query the all the parameters for the governance process. 551 552 Example: 553 $ %s query gov params 554 `, 555 version.AppName, 556 ), 557 ), 558 Args: cobra.NoArgs, 559 RunE: func(cmd *cobra.Command, args []string) error { 560 clientCtx, err := client.GetClientQueryContext(cmd) 561 if err != nil { 562 return err 563 } 564 queryClient := types.NewQueryClient(clientCtx) 565 566 // Query store for all 3 params 567 ctx := cmd.Context() 568 votingRes, err := queryClient.Params( 569 ctx, 570 &types.QueryParamsRequest{ParamsType: "voting"}, 571 ) 572 if err != nil { 573 return err 574 } 575 576 tallyRes, err := queryClient.Params( 577 ctx, 578 &types.QueryParamsRequest{ParamsType: "tallying"}, 579 ) 580 if err != nil { 581 return err 582 } 583 584 depositRes, err := queryClient.Params( 585 ctx, 586 &types.QueryParamsRequest{ParamsType: "deposit"}, 587 ) 588 if err != nil { 589 return err 590 } 591 592 params := types.NewParams( 593 votingRes.GetVotingParams(), 594 tallyRes.GetTallyParams(), 595 depositRes.GetDepositParams(), 596 ) 597 598 return clientCtx.PrintObjectLegacy(params) 599 }, 600 } 601 602 flags.AddQueryFlagsToCmd(cmd) 603 604 return cmd 605 } 606 607 // GetCmdQueryParam implements the query param command. 608 func GetCmdQueryParam() *cobra.Command { 609 cmd := &cobra.Command{ 610 Use: "param [param-type]", 611 Args: cobra.ExactArgs(1), 612 Short: "Query the parameters (voting|tallying|deposit) of the governance process", 613 Long: strings.TrimSpace( 614 fmt.Sprintf(`Query the all the parameters for the governance process. 615 616 Example: 617 $ %s query gov param voting 618 $ %s query gov param tallying 619 $ %s query gov param deposit 620 `, 621 version.AppName, version.AppName, version.AppName, 622 ), 623 ), 624 RunE: func(cmd *cobra.Command, args []string) error { 625 clientCtx, err := client.GetClientQueryContext(cmd) 626 if err != nil { 627 return err 628 } 629 queryClient := types.NewQueryClient(clientCtx) 630 631 // Query store 632 res, err := queryClient.Params( 633 cmd.Context(), 634 &types.QueryParamsRequest{ParamsType: args[0]}, 635 ) 636 if err != nil { 637 return err 638 } 639 640 var out fmt.Stringer 641 switch args[0] { 642 case "voting": 643 out = res.GetVotingParams() 644 case "tallying": 645 out = res.GetTallyParams() 646 case "deposit": 647 out = res.GetDepositParams() 648 default: 649 return fmt.Errorf("argument must be one of (voting|tallying|deposit), was %s", args[0]) 650 } 651 652 return clientCtx.PrintObjectLegacy(out) 653 }, 654 } 655 656 flags.AddQueryFlagsToCmd(cmd) 657 658 return cmd 659 } 660 661 // GetCmdQueryProposer implements the query proposer command. 662 func GetCmdQueryProposer() *cobra.Command { 663 cmd := &cobra.Command{ 664 Use: "proposer [proposal-id]", 665 Args: cobra.ExactArgs(1), 666 Short: "Query the proposer of a governance proposal", 667 Long: strings.TrimSpace( 668 fmt.Sprintf(`Query which address proposed a proposal with a given ID. 669 670 Example: 671 $ %s query gov proposer 1 672 `, 673 version.AppName, 674 ), 675 ), 676 RunE: func(cmd *cobra.Command, args []string) error { 677 clientCtx, err := client.GetClientQueryContext(cmd) 678 if err != nil { 679 return err 680 } 681 682 // validate that the proposalID is a uint 683 proposalID, err := strconv.ParseUint(args[0], 10, 64) 684 if err != nil { 685 return fmt.Errorf("proposal-id %s is not a valid uint", args[0]) 686 } 687 688 prop, err := gcutils.QueryProposerByTxQuery(clientCtx, proposalID) 689 if err != nil { 690 return err 691 } 692 693 return clientCtx.PrintObjectLegacy(prop) 694 }, 695 } 696 697 flags.AddQueryFlagsToCmd(cmd) 698 699 return cmd 700 }