github.com/KiraCore/sekai@v0.3.43/x/gov/client/cli/tx.go (about)

     1  package cli
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/cosmos/cosmos-sdk/client"
    11  	"github.com/cosmos/cosmos-sdk/client/flags"
    12  	"github.com/cosmos/cosmos-sdk/client/tx"
    13  	sdk "github.com/cosmos/cosmos-sdk/types"
    14  	"github.com/spf13/cobra"
    15  	"github.com/spf13/pflag"
    16  
    17  	"github.com/KiraCore/sekai/x/gov/types"
    18  	"github.com/KiraCore/sekai/x/staking/client/cli"
    19  )
    20  
    21  // define flags
    22  const (
    23  	FlagTitle             = "title"
    24  	FlagDescription       = "description"
    25  	FlagPermission        = "permission"
    26  	FlagMinTxFee          = "min_tx_fee"
    27  	FlagMaxTxFee          = "max_tx_fee"
    28  	FlagMinValidators     = "min_validators"
    29  	FlagMinCustodyReward  = "min_custody_reward"
    30  	FlagTxType            = "transaction_type"
    31  	FlagExecutionFee      = "execution_fee"
    32  	FlagFailureFee        = "failure_fee"
    33  	FlagTimeout           = "timeout"
    34  	FlagDefaultParameters = "default_parameters"
    35  	FlagMoniker           = "moniker"
    36  	FlagAddr              = "addr"
    37  	FlagWhitelistPerms    = "whitelist"
    38  	FlagBlacklistPerms    = "blacklist"
    39  	FlagInfosFile         = "infos-file"
    40  	FlagInfosJson         = "infos-json"
    41  	FlagKeys              = "keys"
    42  	FlagVerifier          = "verifier"
    43  	FlagRecordIds         = "record-ids"
    44  	FlagVerifierTip       = "verifier-tip"
    45  	FlagApprove           = "approve"
    46  	FlagSlash             = "slash"
    47  	FlagUsername          = "username"
    48  	FlagSocial            = "social"
    49  	FlagContact           = "contact"
    50  	FlagAvatar            = "avatar"
    51  	FlagPollRoles         = "poll-roles"
    52  	FlagPollOptions       = "poll-options"
    53  	FlagPollCount         = "poll-count"
    54  	FlagPollType          = "poll-type"
    55  	FlagPollChoices       = "poll-choices"
    56  	FlagPollDuration      = "poll-duration"
    57  	FlagPollReference     = "poll-reference"
    58  	FlagPollChecksum      = "poll-checksum"
    59  	FlagCustomPollValue   = "poll-custom-value"
    60  )
    61  
    62  // NewTxCmd returns a root CLI command handler for all x/bank transaction commands.
    63  func NewTxCmd() *cobra.Command {
    64  	txCmd := &cobra.Command{
    65  		Use:                        types.ModuleName,
    66  		Short:                      "Custom gov sub commands",
    67  		DisableFlagParsing:         true,
    68  		SuggestionsMinimumDistance: 2,
    69  		RunE:                       client.ValidateCmd,
    70  	}
    71  
    72  	txCmd.AddCommand(
    73  		NewTxCouncilorCmds(),
    74  		NewTxProposalCmds(),
    75  		NewTxPollCmds(),
    76  		NewTxRoleCmds(),
    77  		NewTxPermissionCmds(),
    78  		NewTxSetNetworkProperties(),
    79  		NewTxSetExecutionFee(),
    80  		GetTxRegisterIdentityRecords(),
    81  		GetTxDeleteIdentityRecords(),
    82  		GetTxRequestIdentityRecordsVerify(),
    83  		GetTxHandleIdentityRecordsVerifyRequest(),
    84  		GetTxCancelIdentityRecordsVerifyRequest(),
    85  	)
    86  
    87  	return txCmd
    88  }
    89  
    90  // NewTxPollCmds returns the subcommands of poll related commands.
    91  func NewTxPollCmds() *cobra.Command {
    92  	pollCmd := &cobra.Command{
    93  		Use:                        "poll",
    94  		Short:                      "Governance poll management subcommands",
    95  		DisableFlagParsing:         true,
    96  		SuggestionsMinimumDistance: 2,
    97  		RunE:                       client.ValidateCmd,
    98  	}
    99  
   100  	pollCmd.AddCommand(GetTxPollCreate())
   101  	pollCmd.AddCommand(GetTxVotePoll())
   102  
   103  	return pollCmd
   104  }
   105  
   106  // NewTxProposalCmds returns the subcommands of proposal related commands.
   107  func NewTxProposalCmds() *cobra.Command {
   108  	proposalCmd := &cobra.Command{
   109  		Use:                        "proposal",
   110  		Short:                      "Governance proposals management subcommands",
   111  		DisableFlagParsing:         true,
   112  		SuggestionsMinimumDistance: 2,
   113  		RunE:                       client.ValidateCmd,
   114  	}
   115  
   116  	accountProposalCmd := &cobra.Command{
   117  		Use:                        "account",
   118  		Short:                      "Account proposals management subcommands",
   119  		DisableFlagParsing:         true,
   120  		SuggestionsMinimumDistance: 2,
   121  		RunE:                       client.ValidateCmd,
   122  	}
   123  
   124  	accountProposalCmd.AddCommand(GetTxProposalWhitelistAccountPermission())
   125  	accountProposalCmd.AddCommand(GetTxProposalBlacklistAccountPermission())
   126  	accountProposalCmd.AddCommand(GetTxProposalRemoveWhitelistedAccountPermission())
   127  	accountProposalCmd.AddCommand(GetTxProposalRemoveBlacklistedAccountPermission())
   128  	accountProposalCmd.AddCommand(GetTxProposalAssignRoleToAccount())
   129  	accountProposalCmd.AddCommand(GetTxProposalUnassignRoleFromAccount())
   130  
   131  	roleProposalCmd := &cobra.Command{
   132  		Use:                        "role",
   133  		Short:                      "Role proposals management subcommands",
   134  		DisableFlagParsing:         true,
   135  		SuggestionsMinimumDistance: 2,
   136  		RunE:                       client.ValidateCmd,
   137  	}
   138  
   139  	roleProposalCmd.AddCommand(GetTxProposalCreateRole())
   140  	roleProposalCmd.AddCommand(GetTxProposalRemoveRole())
   141  	roleProposalCmd.AddCommand(GetTxProposalWhitelistRolePermission())
   142  	roleProposalCmd.AddCommand(GetTxProposalBlacklistRolePermission())
   143  	roleProposalCmd.AddCommand(GetTxProposalRemoveWhitelistedRolePermission())
   144  	roleProposalCmd.AddCommand(GetTxProposalRemoveBlacklistedRolePermission())
   145  
   146  	proposalCmd.AddCommand(GetTxVoteProposal())
   147  	proposalCmd.AddCommand(GetTxProposalSetNetworkProperty())
   148  	proposalCmd.AddCommand(GetTxProposalSetPoorNetworkMessages())
   149  	proposalCmd.AddCommand(GetTxProposalUpsertDataRegistry())
   150  	proposalCmd.AddCommand(GetTxProposalSetProposalDurations())
   151  	proposalCmd.AddCommand(GetTxProposalResetWholeCouncilorRankCmd())
   152  	proposalCmd.AddCommand(GetTxProposalJailCouncilorCmd())
   153  
   154  	proposalCmd.AddCommand(accountProposalCmd)
   155  	proposalCmd.AddCommand(roleProposalCmd)
   156  
   157  	return proposalCmd
   158  }
   159  
   160  // NewTxRoleCmds returns the subcommands of role related commands.
   161  func NewTxRoleCmds() *cobra.Command {
   162  	roleCmd := &cobra.Command{
   163  		Use:                        "role",
   164  		Short:                      "Role management subcommands",
   165  		DisableFlagParsing:         true,
   166  		SuggestionsMinimumDistance: 2,
   167  		RunE:                       client.ValidateCmd,
   168  	}
   169  
   170  	roleCmd.AddCommand(GetTxCreateRole())
   171  	roleCmd.AddCommand(GetTxAssignRole())
   172  	roleCmd.AddCommand(GetTxUnassignRole())
   173  
   174  	roleCmd.AddCommand(GetTxBlacklistRolePermission())
   175  	roleCmd.AddCommand(GetTxWhitelistRolePermission())
   176  	roleCmd.AddCommand(GetTxRemoveWhitelistRolePermission())
   177  	roleCmd.AddCommand(GetTxRemoveBlacklistRolePermission())
   178  
   179  	return roleCmd
   180  }
   181  
   182  // NewTxPermissionCmds returns the subcommands of permission related commands.
   183  func NewTxPermissionCmds() *cobra.Command {
   184  	permCmd := &cobra.Command{
   185  		Use:                        "permission",
   186  		Short:                      "Permission management subcommands",
   187  		DisableFlagParsing:         true,
   188  		SuggestionsMinimumDistance: 2,
   189  		RunE:                       client.ValidateCmd,
   190  	}
   191  
   192  	permCmd.AddCommand(
   193  		GetTxSetWhitelistPermissions(),
   194  		GetTxRemoveWhitelistedPermissions(),
   195  		GetTxSetBlacklistPermissions(),
   196  		GetTxRemoveBlacklistedPermissions(),
   197  	)
   198  
   199  	return permCmd
   200  }
   201  
   202  func NewTxCouncilorCmds() *cobra.Command {
   203  	councilor := &cobra.Command{
   204  		Use:                        "councilor",
   205  		Short:                      "Councilor subcommands",
   206  		DisableFlagParsing:         true,
   207  		SuggestionsMinimumDistance: 2,
   208  		RunE:                       client.ValidateCmd,
   209  	}
   210  
   211  	councilor.AddCommand(
   212  		GetTxClaimCouncilorSeatCmd(),
   213  		GetTxCouncilorPauseCmd(),
   214  		GetTxCouncilorUnpauseCmd(),
   215  		GetTxCouncilorActivateCmd(),
   216  	)
   217  
   218  	return councilor
   219  }
   220  
   221  func GetTxSetWhitelistPermissions() *cobra.Command {
   222  	cmd := &cobra.Command{
   223  		Use:   "whitelist",
   224  		Short: "Assign permission to a kira address whitelist",
   225  		RunE: func(cmd *cobra.Command, args []string) error {
   226  			clientCtx, err := client.GetClientTxContext(cmd)
   227  
   228  			perm, err := cmd.Flags().GetUint32(FlagPermission)
   229  			if err != nil {
   230  				return fmt.Errorf("invalid permissions")
   231  			}
   232  
   233  			addr, err := getAddressFromFlag(cmd)
   234  			if err != nil {
   235  				return fmt.Errorf("error getting address: %w", err)
   236  			}
   237  
   238  			msg := types.NewMsgWhitelistPermissions(
   239  				clientCtx.FromAddress,
   240  				addr,
   241  				perm,
   242  			)
   243  
   244  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   245  		},
   246  	}
   247  
   248  	setPermissionFlags(cmd)
   249  
   250  	flags.AddTxFlagsToCmd(cmd)
   251  	cmd.MarkFlagRequired(flags.FlagFrom)
   252  
   253  	return cmd
   254  }
   255  
   256  func GetTxRemoveWhitelistedPermissions() *cobra.Command {
   257  	cmd := &cobra.Command{
   258  		Use:   "remove-whitelisted",
   259  		Short: "Remove whitelisted permission from an address",
   260  		RunE: func(cmd *cobra.Command, args []string) error {
   261  			clientCtx, err := client.GetClientTxContext(cmd)
   262  
   263  			perm, err := cmd.Flags().GetUint32(FlagPermission)
   264  			if err != nil {
   265  				return fmt.Errorf("invalid permissions")
   266  			}
   267  
   268  			addr, err := getAddressFromFlag(cmd)
   269  			if err != nil {
   270  				return fmt.Errorf("error getting address: %w", err)
   271  			}
   272  
   273  			msg := types.NewMsgRemoveWhitelistedPermissions(
   274  				clientCtx.FromAddress,
   275  				addr,
   276  				perm,
   277  			)
   278  
   279  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   280  		},
   281  	}
   282  
   283  	setPermissionFlags(cmd)
   284  
   285  	flags.AddTxFlagsToCmd(cmd)
   286  	cmd.MarkFlagRequired(flags.FlagFrom)
   287  
   288  	return cmd
   289  }
   290  
   291  func GetTxSetBlacklistPermissions() *cobra.Command {
   292  	cmd := &cobra.Command{
   293  		Use:   "blacklist",
   294  		Short: "Assign permission to a kira account blacklist",
   295  		RunE: func(cmd *cobra.Command, args []string) error {
   296  			clientCtx, err := client.GetClientTxContext(cmd)
   297  			if err != nil {
   298  				return err
   299  			}
   300  
   301  			perm, err := cmd.Flags().GetUint32(FlagPermission)
   302  			if err != nil {
   303  				return fmt.Errorf("invalid permissions")
   304  			}
   305  
   306  			addr, err := getAddressFromFlag(cmd)
   307  			if err != nil {
   308  				return fmt.Errorf("error getting address: %w", err)
   309  			}
   310  
   311  			msg := types.NewMsgBlacklistPermissions(
   312  				clientCtx.FromAddress,
   313  				addr,
   314  				perm,
   315  			)
   316  
   317  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   318  		},
   319  	}
   320  
   321  	setPermissionFlags(cmd)
   322  
   323  	flags.AddTxFlagsToCmd(cmd)
   324  	cmd.MarkFlagRequired(flags.FlagFrom)
   325  
   326  	return cmd
   327  }
   328  
   329  func GetTxRemoveBlacklistedPermissions() *cobra.Command {
   330  	cmd := &cobra.Command{
   331  		Use:   "remove-blacklisted",
   332  		Short: "Remove blacklisted permission from an address",
   333  		RunE: func(cmd *cobra.Command, args []string) error {
   334  			clientCtx, err := client.GetClientTxContext(cmd)
   335  			if err != nil {
   336  				return err
   337  			}
   338  
   339  			perm, err := cmd.Flags().GetUint32(FlagPermission)
   340  			if err != nil {
   341  				return fmt.Errorf("invalid permissions")
   342  			}
   343  
   344  			addr, err := getAddressFromFlag(cmd)
   345  			if err != nil {
   346  				return fmt.Errorf("error getting address: %w", err)
   347  			}
   348  
   349  			msg := types.NewMsgRemoveBlacklistedPermissions(
   350  				clientCtx.FromAddress,
   351  				addr,
   352  				perm,
   353  			)
   354  
   355  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   356  		},
   357  	}
   358  
   359  	setPermissionFlags(cmd)
   360  
   361  	flags.AddTxFlagsToCmd(cmd)
   362  	cmd.MarkFlagRequired(flags.FlagFrom)
   363  
   364  	return cmd
   365  }
   366  
   367  // NewTxSetNetworkProperties is a function to set network properties tx command
   368  func NewTxSetNetworkProperties() *cobra.Command {
   369  	cmd := &cobra.Command{
   370  		Use:   "set-network-properties",
   371  		Short: "Submit a transaction to set network properties",
   372  		RunE: func(cmd *cobra.Command, args []string) error {
   373  			clientCtx, err := client.GetClientTxContext(cmd)
   374  			if err != nil {
   375  				return err
   376  			}
   377  
   378  			minTxFee, err := cmd.Flags().GetUint64(FlagMinTxFee)
   379  			if err != nil {
   380  				return fmt.Errorf("invalid minimum tx fee")
   381  			}
   382  			maxTxFee, err := cmd.Flags().GetUint64(FlagMaxTxFee)
   383  			if err != nil {
   384  				return fmt.Errorf("invalid maximum tx fee")
   385  			}
   386  			minValidators, err := cmd.Flags().GetUint64(FlagMinValidators)
   387  			if err != nil {
   388  				return fmt.Errorf("invalid min validators")
   389  			}
   390  			minCustodyReward, err := cmd.Flags().GetUint64(FlagMinCustodyReward)
   391  			if err != nil {
   392  				return fmt.Errorf("invalid min custody reward")
   393  			}
   394  
   395  			// TODO: should set more by flags
   396  			msg := types.NewMsgSetNetworkProperties(
   397  				clientCtx.FromAddress,
   398  				&types.NetworkProperties{
   399  					MinTxFee:                    minTxFee,
   400  					MaxTxFee:                    maxTxFee,
   401  					VoteQuorum:                  33,
   402  					MinimumProposalEndTime:      300, // 5min
   403  					ProposalEnactmentTime:       300, // 5min
   404  					EnableForeignFeePayments:    true,
   405  					MischanceRankDecreaseAmount: 10,
   406  					InactiveRankDecreasePercent: sdk.NewDecWithPrec(50, 2), // 50%
   407  					PoorNetworkMaxBankSend:      1000000,                   // 1M ukex
   408  					MinValidators:               minValidators,
   409  					MinCustodyReward:            minCustodyReward,
   410  				},
   411  			)
   412  
   413  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   414  		},
   415  	}
   416  	cmd.Flags().Uint64(FlagMinTxFee, 1, "min tx fee")
   417  	cmd.Flags().Uint64(FlagMaxTxFee, 10000, "max tx fee")
   418  	cmd.Flags().Uint64(FlagMinValidators, 2, "min validators")
   419  	cmd.Flags().Uint64(FlagMinCustodyReward, 200, "min custody reward")
   420  	flags.AddTxFlagsToCmd(cmd)
   421  	cmd.MarkFlagRequired(flags.FlagFrom)
   422  
   423  	return cmd
   424  }
   425  
   426  func GetTxWhitelistRolePermission() *cobra.Command {
   427  	cmd := &cobra.Command{
   428  		Use:   "whitelist-permission [role_sid] [permission_id]",
   429  		Short: "Whitelist a permission to a role",
   430  		Args:  cobra.ExactArgs(2),
   431  		RunE: func(cmd *cobra.Command, args []string) error {
   432  			clientCtx, err := client.GetClientTxContext(cmd)
   433  			if err != nil {
   434  				return err
   435  			}
   436  
   437  			permission, err := strconv.Atoi(args[1])
   438  			if err != nil {
   439  				return fmt.Errorf("invalid permission: %w", err)
   440  			}
   441  
   442  			msg := types.NewMsgWhitelistRolePermission(
   443  				clientCtx.FromAddress,
   444  				args[0],
   445  				uint32(permission),
   446  			)
   447  
   448  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   449  		},
   450  	}
   451  
   452  	flags.AddTxFlagsToCmd(cmd)
   453  	cmd.MarkFlagRequired(flags.FlagFrom)
   454  
   455  	return cmd
   456  }
   457  
   458  // NewTxSetExecutionFee is a function to set network properties tx command
   459  func NewTxSetExecutionFee() *cobra.Command {
   460  	cmd := &cobra.Command{
   461  		Use:   "set-execution-fee",
   462  		Short: "Submit a transaction to set execution fee",
   463  		RunE: func(cmd *cobra.Command, args []string) error {
   464  			clientCtx, err := client.GetClientTxContext(cmd)
   465  			if err != nil {
   466  				return err
   467  			}
   468  
   469  			txType, err := cmd.Flags().GetString(FlagTxType)
   470  			if err != nil {
   471  				return fmt.Errorf("invalid transaction type")
   472  			}
   473  
   474  			execFee, err := cmd.Flags().GetUint64(FlagExecutionFee)
   475  			if err != nil {
   476  				return fmt.Errorf("invalid execution fee")
   477  			}
   478  			failureFee, err := cmd.Flags().GetUint64(FlagFailureFee)
   479  			if err != nil {
   480  				return fmt.Errorf("invalid failure fee")
   481  			}
   482  			timeout, err := cmd.Flags().GetUint64(FlagTimeout)
   483  			if err != nil {
   484  				return fmt.Errorf("invalid timeout")
   485  			}
   486  			defaultParams, err := cmd.Flags().GetUint64(FlagDefaultParameters)
   487  			if err != nil {
   488  				return fmt.Errorf("invalid default parameters")
   489  			}
   490  
   491  			msg := types.NewMsgSetExecutionFee(
   492  				txType,
   493  				execFee,
   494  				failureFee,
   495  				timeout,
   496  				defaultParams,
   497  				clientCtx.FromAddress,
   498  			)
   499  
   500  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   501  		},
   502  	}
   503  	cmd.Flags().String(FlagTxType, "", "execution type")
   504  	cmd.Flags().Uint64(FlagExecutionFee, 10, "execution fee")
   505  	cmd.Flags().Uint64(FlagFailureFee, 1, "failure fee")
   506  	cmd.Flags().Uint64(FlagTimeout, 0, "timeout")
   507  	cmd.Flags().Uint64(FlagDefaultParameters, 0, "default parameters")
   508  	flags.AddTxFlagsToCmd(cmd)
   509  	cmd.MarkFlagRequired(flags.FlagFrom)
   510  
   511  	return cmd
   512  }
   513  
   514  func GetTxBlacklistRolePermission() *cobra.Command {
   515  	cmd := &cobra.Command{
   516  		Use:   "blacklist-permission [role_sid] [permission_id]",
   517  		Short: "Blacklist a permission for the governance role",
   518  		Args:  cobra.ExactArgs(2),
   519  		RunE: func(cmd *cobra.Command, args []string) error {
   520  			clientCtx, err := client.GetClientTxContext(cmd)
   521  			if err != nil {
   522  				return err
   523  			}
   524  
   525  			permission, err := strconv.Atoi(args[1])
   526  			if err != nil {
   527  				return fmt.Errorf("invalid permission: %w", err)
   528  			}
   529  
   530  			msg := types.NewMsgBlacklistRolePermission(
   531  				clientCtx.FromAddress,
   532  				args[0],
   533  				uint32(permission),
   534  			)
   535  
   536  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   537  		},
   538  	}
   539  
   540  	flags.AddTxFlagsToCmd(cmd)
   541  	cmd.MarkFlagRequired(flags.FlagFrom)
   542  
   543  	return cmd
   544  }
   545  
   546  func GetTxRemoveWhitelistRolePermission() *cobra.Command {
   547  	cmd := &cobra.Command{
   548  		Use:   "remove-whitelisted-permission [role_sid] [permission_id]",
   549  		Short: "Remove a whitelisted permission from a governance role",
   550  		Args:  cobra.ExactArgs(2),
   551  		RunE: func(cmd *cobra.Command, args []string) error {
   552  			clientCtx, err := client.GetClientTxContext(cmd)
   553  			if err != nil {
   554  				return err
   555  			}
   556  
   557  			permission, err := strconv.Atoi(args[1])
   558  			if err != nil {
   559  				return fmt.Errorf("invalid permission: %w", err)
   560  			}
   561  
   562  			msg := types.NewMsgRemoveWhitelistRolePermission(
   563  				clientCtx.FromAddress,
   564  				args[0],
   565  				uint32(permission),
   566  			)
   567  
   568  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   569  		},
   570  	}
   571  
   572  	flags.AddTxFlagsToCmd(cmd)
   573  	cmd.MarkFlagRequired(flags.FlagFrom)
   574  
   575  	return cmd
   576  }
   577  
   578  func GetTxRemoveBlacklistRolePermission() *cobra.Command {
   579  	cmd := &cobra.Command{
   580  		Use:   "remove-blacklisted-permission [role_sid] [permission_id]",
   581  		Short: "Remove a blacklisted permission from a governance role",
   582  		Args:  cobra.ExactArgs(2),
   583  		RunE: func(cmd *cobra.Command, args []string) error {
   584  			clientCtx, err := client.GetClientTxContext(cmd)
   585  			if err != nil {
   586  				return err
   587  			}
   588  
   589  			permission, err := strconv.Atoi(args[1])
   590  			if err != nil {
   591  				return fmt.Errorf("invalid permission: %w", err)
   592  			}
   593  
   594  			msg := types.NewMsgRemoveBlacklistRolePermission(
   595  				clientCtx.FromAddress,
   596  				args[0],
   597  				uint32(permission),
   598  			)
   599  
   600  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   601  		},
   602  	}
   603  
   604  	flags.AddTxFlagsToCmd(cmd)
   605  	cmd.MarkFlagRequired(flags.FlagFrom)
   606  
   607  	return cmd
   608  }
   609  
   610  func GetTxCreateRole() *cobra.Command {
   611  	cmd := &cobra.Command{
   612  		Use:   "create [role_sid] [role_description]",
   613  		Short: "Create new role",
   614  		Args:  cobra.ExactArgs(2),
   615  		RunE: func(cmd *cobra.Command, args []string) error {
   616  			clientCtx, err := client.GetClientTxContext(cmd)
   617  			if err != nil {
   618  				return err
   619  			}
   620  
   621  			msg := types.NewMsgCreateRole(
   622  				clientCtx.FromAddress,
   623  				args[0],
   624  				args[1],
   625  			)
   626  
   627  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   628  		},
   629  	}
   630  
   631  	flags.AddTxFlagsToCmd(cmd)
   632  	cmd.MarkFlagRequired(flags.FlagFrom)
   633  
   634  	return cmd
   635  }
   636  
   637  func GetTxAssignRole() *cobra.Command {
   638  	cmd := &cobra.Command{
   639  		Use:   "assign [role_id]",
   640  		Short: "Assign role to account",
   641  		Args:  cobra.ExactArgs(1),
   642  		RunE: func(cmd *cobra.Command, args []string) error {
   643  			clientCtx, err := client.GetClientTxContext(cmd)
   644  			if err != nil {
   645  				return err
   646  			}
   647  
   648  			role, err := strconv.Atoi(args[0])
   649  			if err != nil {
   650  				return fmt.Errorf("invalid role: %w", err)
   651  			}
   652  
   653  			addr, err := getAddressFromFlag(cmd)
   654  			if err != nil {
   655  				return fmt.Errorf("error getting address: %w", err)
   656  			}
   657  
   658  			msg := types.NewMsgAssignRole(
   659  				clientCtx.GetFromAddress(),
   660  				addr,
   661  				uint32(role),
   662  			)
   663  
   664  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   665  		},
   666  	}
   667  
   668  	flags.AddTxFlagsToCmd(cmd)
   669  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
   670  
   671  	cmd.MarkFlagRequired(flags.FlagFrom)
   672  	cmd.MarkFlagRequired(cli.FlagAddr)
   673  
   674  	return cmd
   675  }
   676  
   677  func GetTxUnassignRole() *cobra.Command {
   678  	cmd := &cobra.Command{
   679  		Use:   "unassign role",
   680  		Short: "Unassign a role from account",
   681  		Args:  cobra.ExactArgs(1),
   682  		RunE: func(cmd *cobra.Command, args []string) error {
   683  			clientCtx, err := client.GetClientTxContext(cmd)
   684  			if err != nil {
   685  				return err
   686  			}
   687  
   688  			role, err := strconv.Atoi(args[0])
   689  			if err != nil {
   690  				return fmt.Errorf("invalid role: %w", err)
   691  			}
   692  
   693  			addr, err := getAddressFromFlag(cmd)
   694  			if err != nil {
   695  				return fmt.Errorf("error getting address: %w", err)
   696  			}
   697  
   698  			msg := types.NewMsgUnassignRole(
   699  				clientCtx.FromAddress,
   700  				addr,
   701  				uint32(role),
   702  			)
   703  
   704  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   705  		},
   706  	}
   707  
   708  	flags.AddTxFlagsToCmd(cmd)
   709  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
   710  
   711  	cmd.MarkFlagRequired(flags.FlagFrom)
   712  	cmd.MarkFlagRequired(cli.FlagAddr)
   713  
   714  	return cmd
   715  }
   716  
   717  // GetTxProposalSetPoorNetworkMessages defines command to send proposal tx to modify poor network messages
   718  func GetTxProposalSetPoorNetworkMessages() *cobra.Command {
   719  	cmd := &cobra.Command{
   720  		Use:   "set-poor-network-msgs <messages>",
   721  		Short: "Create a proposal to set a value on a network property.",
   722  		Long: `
   723  		$ %s tx customgov proposal set-poor-network-msgs XXXX,YYY --from=<key_or_address>
   724  
   725  		All the message types supported could be added here
   726  			create-role
   727  			assign-role
   728  			remove-role
   729  			...
   730  		`,
   731  		Args: cobra.ExactArgs(1),
   732  		RunE: func(cmd *cobra.Command, args []string) error {
   733  			clientCtx, err := client.GetClientTxContext(cmd)
   734  			if err != nil {
   735  				return err
   736  			}
   737  
   738  			messages := strings.Split(args[0], ",")
   739  
   740  			title, err := cmd.Flags().GetString(FlagTitle)
   741  			if err != nil {
   742  				return fmt.Errorf("invalid title: %w", err)
   743  			}
   744  
   745  			description, err := cmd.Flags().GetString(FlagDescription)
   746  			if err != nil {
   747  				return fmt.Errorf("invalid description: %w", err)
   748  			}
   749  
   750  			msg, err := types.NewMsgSubmitProposal(
   751  				clientCtx.FromAddress,
   752  				title,
   753  				description,
   754  				types.NewSetPoorNetworkMessagesProposal(messages),
   755  			)
   756  			if err != nil {
   757  				return err
   758  			}
   759  
   760  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   761  		},
   762  	}
   763  
   764  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
   765  	cmd.MarkFlagRequired(FlagTitle)
   766  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
   767  	cmd.MarkFlagRequired(FlagDescription)
   768  
   769  	flags.AddTxFlagsToCmd(cmd)
   770  	cmd.MarkFlagRequired(flags.FlagFrom)
   771  
   772  	return cmd
   773  }
   774  
   775  // GetTxProposalSetNetworkProperty defines command to send proposal tx to modify a network property
   776  func GetTxProposalSetNetworkProperty() *cobra.Command {
   777  	cmd := &cobra.Command{
   778  		Use:   "set-network-property <property> <value> [flags]",
   779  		Short: "Create a proposal to set a value on a network property.",
   780  		Long: `
   781  		$ %s tx customgov proposal set-network-property MIN_TX_FEE 100 --from=<key_or_address>
   782  
   783  		Available properties:
   784  			MIN_TX_FEE
   785  			MAX_TX_FEE
   786  			VOTE_QUORUM
   787  			PROPOSAL_END_TIME
   788  			PROPOSAL_ENACTMENT_TIME
   789  			ENABLE_FOREIGN_TX_FEE_PAYMENTS
   790  		`,
   791  		Args: cobra.ExactArgs(2),
   792  		RunE: func(cmd *cobra.Command, args []string) error {
   793  			clientCtx, err := client.GetClientTxContext(cmd)
   794  			if err != nil {
   795  				return err
   796  			}
   797  
   798  			property, ok := types.NetworkProperty_value[args[0]]
   799  			if !ok {
   800  				return fmt.Errorf("invalid network property name: %s", args[0])
   801  			}
   802  
   803  			value := types.NetworkPropertyValue{}
   804  			switch types.NetworkProperty(property) {
   805  			case types.UniqueIdentityKeys:
   806  				value.StrValue = args[1]
   807  			case types.ValidatorsFeeShare:
   808  				value.StrValue = args[1]
   809  			default:
   810  				numVal, err := strconv.Atoi(args[1])
   811  				if err != nil {
   812  					return fmt.Errorf("invalid network property value: %w", err)
   813  				}
   814  				value.Value = uint64(numVal)
   815  			}
   816  
   817  			title, err := cmd.Flags().GetString(FlagTitle)
   818  			if err != nil {
   819  				return fmt.Errorf("invalid title: %w", err)
   820  			}
   821  
   822  			description, err := cmd.Flags().GetString(FlagDescription)
   823  			if err != nil {
   824  				return fmt.Errorf("invalid description: %w", err)
   825  			}
   826  
   827  			msg, err := types.NewMsgSubmitProposal(
   828  				clientCtx.FromAddress,
   829  				title,
   830  				description,
   831  				types.NewSetNetworkPropertyProposal(types.NetworkProperty(property), value),
   832  			)
   833  			if err != nil {
   834  				return err
   835  			}
   836  
   837  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   838  		},
   839  	}
   840  
   841  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
   842  	cmd.MarkFlagRequired(FlagTitle)
   843  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
   844  	cmd.MarkFlagRequired(FlagDescription)
   845  
   846  	flags.AddTxFlagsToCmd(cmd)
   847  	cmd.MarkFlagRequired(flags.FlagFrom)
   848  
   849  	return cmd
   850  }
   851  
   852  func GetTxProposalAssignRoleToAccount() *cobra.Command {
   853  	cmd := &cobra.Command{
   854  		Use:   "assign-role [role_identifier]",
   855  		Short: "Create a proposal to assign a role to an address.",
   856  		Args:  cobra.ExactArgs(1),
   857  		RunE: func(cmd *cobra.Command, args []string) error {
   858  			clientCtx, err := client.GetClientTxContext(cmd)
   859  			if err != nil {
   860  				return err
   861  			}
   862  
   863  			addr, err := getAddressFromFlag(cmd)
   864  			if err != nil {
   865  				return fmt.Errorf("error getting address: %w", err)
   866  			}
   867  
   868  			title, err := cmd.Flags().GetString(FlagTitle)
   869  			if err != nil {
   870  				return fmt.Errorf("invalid title: %w", err)
   871  			}
   872  
   873  			description, err := cmd.Flags().GetString(FlagDescription)
   874  			if err != nil {
   875  				return fmt.Errorf("invalid description: %w", err)
   876  			}
   877  
   878  			msg, err := types.NewMsgSubmitProposal(
   879  				clientCtx.FromAddress,
   880  				title,
   881  				description,
   882  				types.NewAssignRoleToAccountProposal(addr, args[0]),
   883  			)
   884  			if err != nil {
   885  				return err
   886  			}
   887  
   888  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   889  		},
   890  	}
   891  
   892  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
   893  	cmd.MarkFlagRequired(FlagTitle)
   894  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
   895  	cmd.MarkFlagRequired(FlagDescription)
   896  
   897  	flags.AddTxFlagsToCmd(cmd)
   898  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
   899  
   900  	cmd.MarkFlagRequired(flags.FlagFrom)
   901  	cmd.MarkFlagRequired(cli.FlagAddr)
   902  
   903  	return cmd
   904  }
   905  
   906  func GetTxProposalUnassignRoleFromAccount() *cobra.Command {
   907  	cmd := &cobra.Command{
   908  		Use:   "unassign-role [role]",
   909  		Short: "Create a proposal to unassign a role from an address.",
   910  		Args:  cobra.ExactArgs(1),
   911  		RunE: func(cmd *cobra.Command, args []string) error {
   912  			clientCtx, err := client.GetClientTxContext(cmd)
   913  			if err != nil {
   914  				return err
   915  			}
   916  
   917  			addr, err := getAddressFromFlag(cmd)
   918  			if err != nil {
   919  				return fmt.Errorf("error getting address: %w", err)
   920  			}
   921  
   922  			title, err := cmd.Flags().GetString(FlagTitle)
   923  			if err != nil {
   924  				return fmt.Errorf("invalid title: %w", err)
   925  			}
   926  
   927  			description, err := cmd.Flags().GetString(FlagDescription)
   928  			if err != nil {
   929  				return fmt.Errorf("invalid description: %w", err)
   930  			}
   931  
   932  			msg, err := types.NewMsgSubmitProposal(
   933  				clientCtx.FromAddress,
   934  				title,
   935  				description,
   936  				types.NewUnassignRoleFromAccountProposal(addr, args[0]),
   937  			)
   938  			if err != nil {
   939  				return err
   940  			}
   941  
   942  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
   943  		},
   944  	}
   945  
   946  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
   947  	cmd.MarkFlagRequired(FlagTitle)
   948  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
   949  	cmd.MarkFlagRequired(FlagDescription)
   950  
   951  	flags.AddTxFlagsToCmd(cmd)
   952  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
   953  
   954  	cmd.MarkFlagRequired(flags.FlagFrom)
   955  	cmd.MarkFlagRequired(cli.FlagAddr)
   956  
   957  	return cmd
   958  }
   959  
   960  func GetTxProposalWhitelistAccountPermission() *cobra.Command {
   961  	cmd := &cobra.Command{
   962  		Use:   "whitelist-permission [permission_id]",
   963  		Short: "Create a proposal to whitelist a permission to an address.",
   964  		Args:  cobra.ExactArgs(1),
   965  		RunE: func(cmd *cobra.Command, args []string) error {
   966  			clientCtx, err := client.GetClientTxContext(cmd)
   967  			if err != nil {
   968  				return err
   969  			}
   970  
   971  			perm, err := strconv.Atoi(args[0])
   972  			if err != nil {
   973  				return fmt.Errorf("invalid perm: %w", err)
   974  			}
   975  
   976  			addr, err := getAddressFromFlag(cmd)
   977  			if err != nil {
   978  				return fmt.Errorf("error getting address: %w", err)
   979  			}
   980  
   981  			title, err := cmd.Flags().GetString(FlagTitle)
   982  			if err != nil {
   983  				return fmt.Errorf("invalid title: %w", err)
   984  			}
   985  
   986  			description, err := cmd.Flags().GetString(FlagDescription)
   987  			if err != nil {
   988  				return fmt.Errorf("invalid description: %w", err)
   989  			}
   990  
   991  			msg, err := types.NewMsgSubmitProposal(
   992  				clientCtx.FromAddress,
   993  				title,
   994  				description,
   995  				types.NewWhitelistAccountPermissionProposal(addr, types.PermValue(perm)),
   996  			)
   997  			if err != nil {
   998  				return err
   999  			}
  1000  
  1001  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1002  		},
  1003  	}
  1004  
  1005  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1006  	cmd.MarkFlagRequired(FlagTitle)
  1007  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1008  	cmd.MarkFlagRequired(FlagDescription)
  1009  
  1010  	flags.AddTxFlagsToCmd(cmd)
  1011  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
  1012  
  1013  	cmd.MarkFlagRequired(flags.FlagFrom)
  1014  	cmd.MarkFlagRequired(cli.FlagAddr)
  1015  
  1016  	return cmd
  1017  }
  1018  
  1019  func GetTxProposalBlacklistAccountPermission() *cobra.Command {
  1020  	cmd := &cobra.Command{
  1021  		Use:   "blacklist-permission [permission_id]",
  1022  		Short: "Create a proposal to blacklist a permission to an address.",
  1023  		Args:  cobra.ExactArgs(1),
  1024  		RunE: func(cmd *cobra.Command, args []string) error {
  1025  			clientCtx, err := client.GetClientTxContext(cmd)
  1026  			if err != nil {
  1027  				return err
  1028  			}
  1029  
  1030  			perm, err := strconv.Atoi(args[0])
  1031  			if err != nil {
  1032  				return fmt.Errorf("invalid perm: %w", err)
  1033  			}
  1034  
  1035  			addr, err := getAddressFromFlag(cmd)
  1036  			if err != nil {
  1037  				return fmt.Errorf("error getting address: %w", err)
  1038  			}
  1039  
  1040  			title, err := cmd.Flags().GetString(FlagTitle)
  1041  			if err != nil {
  1042  				return fmt.Errorf("invalid title: %w", err)
  1043  			}
  1044  
  1045  			description, err := cmd.Flags().GetString(FlagDescription)
  1046  			if err != nil {
  1047  				return fmt.Errorf("invalid description: %w", err)
  1048  			}
  1049  
  1050  			msg, err := types.NewMsgSubmitProposal(
  1051  				clientCtx.FromAddress,
  1052  				title,
  1053  				description,
  1054  				types.NewBlacklistAccountPermissionProposal(addr, types.PermValue(perm)),
  1055  			)
  1056  			if err != nil {
  1057  				return err
  1058  			}
  1059  
  1060  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1061  		},
  1062  	}
  1063  
  1064  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1065  	cmd.MarkFlagRequired(FlagTitle)
  1066  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1067  	cmd.MarkFlagRequired(FlagDescription)
  1068  
  1069  	flags.AddTxFlagsToCmd(cmd)
  1070  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
  1071  
  1072  	cmd.MarkFlagRequired(flags.FlagFrom)
  1073  	cmd.MarkFlagRequired(cli.FlagAddr)
  1074  
  1075  	return cmd
  1076  }
  1077  
  1078  func GetTxProposalRemoveWhitelistedAccountPermission() *cobra.Command {
  1079  	cmd := &cobra.Command{
  1080  		Use:   "remove-whitelisted-permission [permission_id]",
  1081  		Short: "Create a proposal to remove a whitelisted permission from an address.",
  1082  		Args:  cobra.ExactArgs(1),
  1083  		RunE: func(cmd *cobra.Command, args []string) error {
  1084  			clientCtx, err := client.GetClientTxContext(cmd)
  1085  			if err != nil {
  1086  				return err
  1087  			}
  1088  
  1089  			perm, err := strconv.Atoi(args[0])
  1090  			if err != nil {
  1091  				return fmt.Errorf("invalid perm: %w", err)
  1092  			}
  1093  
  1094  			addr, err := getAddressFromFlag(cmd)
  1095  			if err != nil {
  1096  				return fmt.Errorf("error getting address: %w", err)
  1097  			}
  1098  
  1099  			title, err := cmd.Flags().GetString(FlagTitle)
  1100  			if err != nil {
  1101  				return fmt.Errorf("invalid title: %w", err)
  1102  			}
  1103  
  1104  			description, err := cmd.Flags().GetString(FlagDescription)
  1105  			if err != nil {
  1106  				return fmt.Errorf("invalid description: %w", err)
  1107  			}
  1108  
  1109  			msg, err := types.NewMsgSubmitProposal(
  1110  				clientCtx.FromAddress,
  1111  				title,
  1112  				description,
  1113  				types.NewRemoveWhitelistedAccountPermissionProposal(addr, types.PermValue(perm)),
  1114  			)
  1115  			if err != nil {
  1116  				return err
  1117  			}
  1118  
  1119  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1120  		},
  1121  	}
  1122  
  1123  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1124  	cmd.MarkFlagRequired(FlagTitle)
  1125  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1126  	cmd.MarkFlagRequired(FlagDescription)
  1127  
  1128  	flags.AddTxFlagsToCmd(cmd)
  1129  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
  1130  
  1131  	cmd.MarkFlagRequired(flags.FlagFrom)
  1132  	cmd.MarkFlagRequired(cli.FlagAddr)
  1133  
  1134  	return cmd
  1135  }
  1136  
  1137  func GetTxProposalRemoveBlacklistedAccountPermission() *cobra.Command {
  1138  	cmd := &cobra.Command{
  1139  		Use:   "remove-blacklisted-permission [permission_id]",
  1140  		Short: "Create a proposal to remove a blacklisted permission from an address.",
  1141  		Args:  cobra.ExactArgs(1),
  1142  		RunE: func(cmd *cobra.Command, args []string) error {
  1143  			clientCtx, err := client.GetClientTxContext(cmd)
  1144  			if err != nil {
  1145  				return err
  1146  			}
  1147  
  1148  			perm, err := strconv.Atoi(args[0])
  1149  			if err != nil {
  1150  				return fmt.Errorf("invalid perm: %w", err)
  1151  			}
  1152  
  1153  			addr, err := getAddressFromFlag(cmd)
  1154  			if err != nil {
  1155  				return fmt.Errorf("error getting address: %w", err)
  1156  			}
  1157  
  1158  			title, err := cmd.Flags().GetString(FlagTitle)
  1159  			if err != nil {
  1160  				return fmt.Errorf("invalid title: %w", err)
  1161  			}
  1162  
  1163  			description, err := cmd.Flags().GetString(FlagDescription)
  1164  			if err != nil {
  1165  				return fmt.Errorf("invalid description: %w", err)
  1166  			}
  1167  
  1168  			msg, err := types.NewMsgSubmitProposal(
  1169  				clientCtx.FromAddress,
  1170  				title,
  1171  				description,
  1172  				types.NewRemoveBlacklistedAccountPermissionProposal(addr, types.PermValue(perm)),
  1173  			)
  1174  			if err != nil {
  1175  				return err
  1176  			}
  1177  
  1178  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1179  		},
  1180  	}
  1181  
  1182  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1183  	cmd.MarkFlagRequired(FlagTitle)
  1184  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1185  	cmd.MarkFlagRequired(FlagDescription)
  1186  
  1187  	flags.AddTxFlagsToCmd(cmd)
  1188  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
  1189  
  1190  	cmd.MarkFlagRequired(flags.FlagFrom)
  1191  	cmd.MarkFlagRequired(cli.FlagAddr)
  1192  
  1193  	return cmd
  1194  }
  1195  
  1196  func GetTxProposalUpsertDataRegistry() *cobra.Command {
  1197  	cmd := &cobra.Command{
  1198  		Use:   "upsert-data-registry [key] [hash] [reference] [encoding] [size] [flags]",
  1199  		Short: "Create a proposal to upsert a key in the data registry",
  1200  		Args:  cobra.ExactArgs(5),
  1201  		RunE: func(cmd *cobra.Command, args []string) error {
  1202  			clientCtx, err := client.GetClientTxContext(cmd)
  1203  			if err != nil {
  1204  				return err
  1205  			}
  1206  
  1207  			key := args[0]
  1208  			hash := args[1]
  1209  			reference := args[2]
  1210  			encoding := args[3]
  1211  			size, err := strconv.Atoi(args[4])
  1212  			if err != nil {
  1213  				return err
  1214  			}
  1215  
  1216  			title, err := cmd.Flags().GetString(FlagTitle)
  1217  			if err != nil {
  1218  				return fmt.Errorf("invalid title: %w", err)
  1219  			}
  1220  
  1221  			description, err := cmd.Flags().GetString(FlagDescription)
  1222  			if err != nil {
  1223  				return fmt.Errorf("invalid description: %w", err)
  1224  			}
  1225  
  1226  			msg, err := types.NewMsgSubmitProposal(
  1227  				clientCtx.FromAddress,
  1228  				title,
  1229  				description,
  1230  				types.NewUpsertDataRegistryProposal(
  1231  					key,
  1232  					hash,
  1233  					reference,
  1234  					encoding,
  1235  					uint64(size),
  1236  				),
  1237  			)
  1238  			if err != nil {
  1239  				return err
  1240  			}
  1241  
  1242  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1243  		},
  1244  	}
  1245  
  1246  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1247  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1248  	flags.AddTxFlagsToCmd(cmd)
  1249  
  1250  	cmd.MarkFlagRequired(FlagTitle)
  1251  	cmd.MarkFlagRequired(FlagDescription)
  1252  	cmd.MarkFlagRequired(flags.FlagFrom)
  1253  
  1254  	return cmd
  1255  }
  1256  
  1257  func GetTxVoteProposal() *cobra.Command {
  1258  	cmd := &cobra.Command{
  1259  		Use:   "vote proposal-id vote-option",
  1260  		Short: "Vote a proposal.",
  1261  		Args:  cobra.ExactArgs(2),
  1262  		RunE: func(cmd *cobra.Command, args []string) error {
  1263  			clientCtx, err := client.GetClientTxContext(cmd)
  1264  			if err != nil {
  1265  				return err
  1266  			}
  1267  
  1268  			proposalID, err := strconv.Atoi(args[0])
  1269  			if err != nil {
  1270  				return fmt.Errorf("invalid proposal ID: %w", err)
  1271  			}
  1272  
  1273  			voteOption, err := strconv.Atoi(args[1])
  1274  			if err != nil {
  1275  				return fmt.Errorf("invalid vote option: %w", err)
  1276  			}
  1277  
  1278  			slashStr, err := cmd.Flags().GetString(FlagSlash)
  1279  			if err != nil {
  1280  				return err
  1281  			}
  1282  			slash, err := sdk.NewDecFromStr(slashStr)
  1283  			if err != nil {
  1284  				return err
  1285  			}
  1286  
  1287  			msg := types.NewMsgVoteProposal(
  1288  				uint64(proposalID),
  1289  				clientCtx.FromAddress,
  1290  				types.VoteOption(voteOption),
  1291  				slash,
  1292  			)
  1293  
  1294  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1295  		},
  1296  	}
  1297  
  1298  	flags.AddTxFlagsToCmd(cmd)
  1299  	cmd.MarkFlagRequired(flags.FlagFrom)
  1300  	cmd.Flags().String(FlagSlash, "0.01", "slash value on the proposal")
  1301  
  1302  	return cmd
  1303  }
  1304  
  1305  // setPermissionFlags sets the flags needed for set blacklist and set whitelist permission
  1306  // commands.
  1307  func setPermissionFlags(cmd *cobra.Command) {
  1308  	cmd.Flags().String(cli.FlagAddr, "", "the address to set permissions")
  1309  	cmd.Flags().Uint32(FlagPermission, 0, "the permission")
  1310  }
  1311  
  1312  // getAddressFromFlag returns the AccAddress from FlagAddr in Command.
  1313  func getAddressFromFlag(cmd *cobra.Command) (sdk.AccAddress, error) {
  1314  	addr, err := cmd.Flags().GetString(cli.FlagAddr)
  1315  	if err != nil {
  1316  		return nil, fmt.Errorf("error getting address")
  1317  	}
  1318  
  1319  	bech, err := sdk.AccAddressFromBech32(addr)
  1320  	if err != nil {
  1321  		return nil, fmt.Errorf("invalid Bech32 address")
  1322  	}
  1323  
  1324  	return bech, nil
  1325  }
  1326  
  1327  func GetTxClaimCouncilorSeatCmd() *cobra.Command {
  1328  	cmd := &cobra.Command{
  1329  		Use:   "claim-seat",
  1330  		Short: "Claim councilor seat",
  1331  		RunE: func(cmd *cobra.Command, args []string) error {
  1332  			clientCtx, err := client.GetClientTxContext(cmd)
  1333  			if err != nil {
  1334  				return err
  1335  			}
  1336  
  1337  			moniker, _ := cmd.Flags().GetString(FlagMoniker)
  1338  			username, _ := cmd.Flags().GetString(FlagUsername)
  1339  			description, _ := cmd.Flags().GetString(FlagDescription)
  1340  			social, _ := cmd.Flags().GetString(FlagSocial)
  1341  			contact, _ := cmd.Flags().GetString(FlagContact)
  1342  			avatar, _ := cmd.Flags().GetString(FlagAvatar)
  1343  
  1344  			msg := types.NewMsgClaimCouncilor(
  1345  				clientCtx.FromAddress,
  1346  				moniker,
  1347  				username,
  1348  				description,
  1349  				social,
  1350  				contact,
  1351  				avatar,
  1352  			)
  1353  
  1354  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1355  		},
  1356  	}
  1357  
  1358  	flags.AddTxFlagsToCmd(cmd)
  1359  
  1360  	cmd.Flags().String(FlagAddr, "", "the address")
  1361  	cmd.Flags().String(FlagMoniker, "", "the Moniker")
  1362  	cmd.Flags().String(FlagUsername, "", "the Username")
  1363  	cmd.Flags().String(FlagDescription, "", "the description")
  1364  	cmd.Flags().String(FlagSocial, "", "the social")
  1365  	cmd.Flags().String(FlagContact, "", "the contact")
  1366  	cmd.Flags().String(FlagAvatar, "", "the avatar")
  1367  
  1368  	cmd.MarkFlagRequired(flags.FlagFrom)
  1369  
  1370  	return cmd
  1371  }
  1372  
  1373  // CouncilorPause - signal to the network that Councilor will NOT be present for a prolonged period of time
  1374  func GetTxCouncilorPauseCmd() *cobra.Command {
  1375  	cmd := &cobra.Command{
  1376  		Use:   "pause",
  1377  		Short: "Pause councilor",
  1378  		RunE: func(cmd *cobra.Command, args []string) error {
  1379  			clientCtx, err := client.GetClientTxContext(cmd)
  1380  			if err != nil {
  1381  				return err
  1382  			}
  1383  
  1384  			msg := types.NewMsgCouncilorPause(
  1385  				clientCtx.GetFromAddress(),
  1386  			)
  1387  
  1388  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1389  		},
  1390  	}
  1391  
  1392  	flags.AddTxFlagsToCmd(cmd)
  1393  	cmd.MarkFlagRequired(flags.FlagFrom)
  1394  
  1395  	return cmd
  1396  }
  1397  
  1398  // CouncilorUnpause - signal to the network that Councilor wishes to regain voting ability after planned absence
  1399  func GetTxCouncilorUnpauseCmd() *cobra.Command {
  1400  	cmd := &cobra.Command{
  1401  		Use:   "unpause",
  1402  		Short: "Unpause councilor",
  1403  		RunE: func(cmd *cobra.Command, args []string) error {
  1404  			clientCtx, err := client.GetClientTxContext(cmd)
  1405  			if err != nil {
  1406  				return err
  1407  			}
  1408  
  1409  			msg := types.NewMsgCouncilorUnpause(
  1410  				clientCtx.GetFromAddress(),
  1411  			)
  1412  
  1413  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1414  		},
  1415  	}
  1416  
  1417  	flags.AddTxFlagsToCmd(cmd)
  1418  	cmd.MarkFlagRequired(flags.FlagFrom)
  1419  
  1420  	return cmd
  1421  }
  1422  
  1423  // CouncilorActivate - signal to the network that Councilor wishes to regain voting ability after planned absence
  1424  func GetTxCouncilorActivateCmd() *cobra.Command {
  1425  	cmd := &cobra.Command{
  1426  		Use:   "activate",
  1427  		Short: "Activate councilor",
  1428  		RunE: func(cmd *cobra.Command, args []string) error {
  1429  			clientCtx, err := client.GetClientTxContext(cmd)
  1430  			if err != nil {
  1431  				return err
  1432  			}
  1433  
  1434  			msg := types.NewMsgCouncilorActivate(
  1435  				clientCtx.GetFromAddress(),
  1436  			)
  1437  
  1438  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1439  		},
  1440  	}
  1441  
  1442  	flags.AddTxFlagsToCmd(cmd)
  1443  	cmd.MarkFlagRequired(flags.FlagFrom)
  1444  
  1445  	return cmd
  1446  }
  1447  
  1448  func GetTxProposalCreateRole() *cobra.Command {
  1449  	cmd := &cobra.Command{
  1450  		Use:   "create [role_sid] [role_description]",
  1451  		Short: "Raise governance proposal to create a new role.",
  1452  		Args:  cobra.ExactArgs(2),
  1453  		RunE: func(cmd *cobra.Command, args []string) error {
  1454  			clientCtx, err := client.GetClientTxContext(cmd)
  1455  			if err != nil {
  1456  				return err
  1457  			}
  1458  
  1459  			wAsInts, err := cmd.Flags().GetInt32Slice(FlagWhitelistPerms)
  1460  			if err != nil {
  1461  				return fmt.Errorf("invalid whitelist perms: %w", err)
  1462  			}
  1463  			whitelistPerms := convertAsPermValues(wAsInts)
  1464  
  1465  			bAsInts, err := cmd.Flags().GetInt32Slice(FlagBlacklistPerms)
  1466  			if err != nil {
  1467  				return fmt.Errorf("invalid blacklist perms: %w", err)
  1468  			}
  1469  			blacklistPerms := convertAsPermValues(bAsInts)
  1470  
  1471  			title, err := cmd.Flags().GetString(FlagTitle)
  1472  			if err != nil {
  1473  				return fmt.Errorf("invalid title: %w", err)
  1474  			}
  1475  
  1476  			description, err := cmd.Flags().GetString(FlagDescription)
  1477  			if err != nil {
  1478  				return fmt.Errorf("invalid description: %w", err)
  1479  			}
  1480  
  1481  			msg, err := types.NewMsgSubmitProposal(
  1482  				clientCtx.FromAddress,
  1483  				title,
  1484  				description,
  1485  				types.NewCreateRoleProposal(
  1486  					args[0],
  1487  					args[1],
  1488  					whitelistPerms,
  1489  					blacklistPerms,
  1490  				),
  1491  			)
  1492  			if err != nil {
  1493  				return err
  1494  			}
  1495  
  1496  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1497  		},
  1498  	}
  1499  
  1500  	flags.AddTxFlagsToCmd(cmd)
  1501  
  1502  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1503  	cmd.MarkFlagRequired(FlagTitle)
  1504  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1505  	cmd.MarkFlagRequired(FlagDescription)
  1506  	cmd.Flags().Int32Slice(FlagWhitelistPerms, []int32{}, "the whitelist value in format 1,2,3")
  1507  	cmd.Flags().Int32Slice(FlagBlacklistPerms, []int32{}, "the blacklist values in format 1,2,3")
  1508  	cmd.MarkFlagRequired(flags.FlagFrom)
  1509  
  1510  	return cmd
  1511  }
  1512  
  1513  func GetTxProposalRemoveRole() *cobra.Command {
  1514  	cmd := &cobra.Command{
  1515  		Use:   "remove [role_sid]",
  1516  		Short: "Raise governance proposal to remove a role.",
  1517  		Args:  cobra.ExactArgs(1),
  1518  		RunE: func(cmd *cobra.Command, args []string) error {
  1519  			clientCtx, err := client.GetClientTxContext(cmd)
  1520  			if err != nil {
  1521  				return err
  1522  			}
  1523  
  1524  			title, err := cmd.Flags().GetString(FlagTitle)
  1525  			if err != nil {
  1526  				return fmt.Errorf("invalid title: %w", err)
  1527  			}
  1528  
  1529  			description, err := cmd.Flags().GetString(FlagDescription)
  1530  			if err != nil {
  1531  				return fmt.Errorf("invalid description: %w", err)
  1532  			}
  1533  
  1534  			msg, err := types.NewMsgSubmitProposal(
  1535  				clientCtx.FromAddress,
  1536  				title,
  1537  				description,
  1538  				types.NewRemoveRoleProposal(
  1539  					args[0],
  1540  				),
  1541  			)
  1542  			if err != nil {
  1543  				return err
  1544  			}
  1545  
  1546  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1547  		},
  1548  	}
  1549  
  1550  	flags.AddTxFlagsToCmd(cmd)
  1551  
  1552  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1553  	cmd.MarkFlagRequired(FlagTitle)
  1554  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1555  	cmd.MarkFlagRequired(FlagDescription)
  1556  	cmd.MarkFlagRequired(flags.FlagFrom)
  1557  
  1558  	return cmd
  1559  }
  1560  
  1561  func GetTxProposalWhitelistRolePermission() *cobra.Command {
  1562  	cmd := &cobra.Command{
  1563  		Use:   "whitelist-permission [role_sid] [permission_id]",
  1564  		Short: "Raise governance proposal to whitelist a permission for a role.",
  1565  		Args:  cobra.ExactArgs(2),
  1566  		RunE: func(cmd *cobra.Command, args []string) error {
  1567  			clientCtx, err := client.GetClientTxContext(cmd)
  1568  			if err != nil {
  1569  				return err
  1570  			}
  1571  
  1572  			perm, err := strconv.Atoi(args[1])
  1573  			if err != nil {
  1574  				return err
  1575  			}
  1576  
  1577  			title, err := cmd.Flags().GetString(FlagTitle)
  1578  			if err != nil {
  1579  				return fmt.Errorf("invalid title: %w", err)
  1580  			}
  1581  
  1582  			description, err := cmd.Flags().GetString(FlagDescription)
  1583  			if err != nil {
  1584  				return fmt.Errorf("invalid description: %w", err)
  1585  			}
  1586  
  1587  			msg, err := types.NewMsgSubmitProposal(
  1588  				clientCtx.FromAddress,
  1589  				title,
  1590  				description,
  1591  				types.NewWhitelistRolePermissionProposal(
  1592  					args[0],
  1593  					types.PermValue(perm),
  1594  				),
  1595  			)
  1596  			if err != nil {
  1597  				return err
  1598  			}
  1599  
  1600  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1601  		},
  1602  	}
  1603  
  1604  	flags.AddTxFlagsToCmd(cmd)
  1605  
  1606  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1607  	cmd.MarkFlagRequired(FlagTitle)
  1608  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1609  	cmd.MarkFlagRequired(FlagDescription)
  1610  	cmd.MarkFlagRequired(flags.FlagFrom)
  1611  
  1612  	return cmd
  1613  }
  1614  
  1615  func GetTxProposalBlacklistRolePermission() *cobra.Command {
  1616  	cmd := &cobra.Command{
  1617  		Use:   "blacklist-permission [role_sid] [role_description]",
  1618  		Short: "Raise governance proposal to blacklist a permission for a role.",
  1619  		Args:  cobra.ExactArgs(2),
  1620  		RunE: func(cmd *cobra.Command, args []string) error {
  1621  			clientCtx, err := client.GetClientTxContext(cmd)
  1622  			if err != nil {
  1623  				return err
  1624  			}
  1625  
  1626  			perm, err := strconv.Atoi(args[1])
  1627  			if err != nil {
  1628  				return err
  1629  			}
  1630  
  1631  			title, err := cmd.Flags().GetString(FlagTitle)
  1632  			if err != nil {
  1633  				return fmt.Errorf("invalid title: %w", err)
  1634  			}
  1635  
  1636  			description, err := cmd.Flags().GetString(FlagDescription)
  1637  			if err != nil {
  1638  				return fmt.Errorf("invalid description: %w", err)
  1639  			}
  1640  
  1641  			msg, err := types.NewMsgSubmitProposal(
  1642  				clientCtx.FromAddress,
  1643  				title,
  1644  				description,
  1645  				types.NewBlacklistRolePermissionProposal(
  1646  					args[0],
  1647  					types.PermValue(perm),
  1648  				),
  1649  			)
  1650  			if err != nil {
  1651  				return err
  1652  			}
  1653  
  1654  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1655  		},
  1656  	}
  1657  
  1658  	flags.AddTxFlagsToCmd(cmd)
  1659  
  1660  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1661  	cmd.MarkFlagRequired(FlagTitle)
  1662  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1663  	cmd.MarkFlagRequired(FlagDescription)
  1664  	cmd.MarkFlagRequired(flags.FlagFrom)
  1665  
  1666  	return cmd
  1667  }
  1668  
  1669  func GetTxProposalRemoveWhitelistedRolePermission() *cobra.Command {
  1670  	cmd := &cobra.Command{
  1671  		Use:   "remove-whitelisted-permission [role_sid] [permission]",
  1672  		Short: "Raise governance proposal to remove whitelisted permission from a role.",
  1673  		Args:  cobra.ExactArgs(2),
  1674  		RunE: func(cmd *cobra.Command, args []string) error {
  1675  			clientCtx, err := client.GetClientTxContext(cmd)
  1676  			if err != nil {
  1677  				return err
  1678  			}
  1679  
  1680  			perm, err := strconv.Atoi(args[1])
  1681  			if err != nil {
  1682  				return err
  1683  			}
  1684  
  1685  			title, err := cmd.Flags().GetString(FlagTitle)
  1686  			if err != nil {
  1687  				return fmt.Errorf("invalid title: %w", err)
  1688  			}
  1689  
  1690  			description, err := cmd.Flags().GetString(FlagDescription)
  1691  			if err != nil {
  1692  				return fmt.Errorf("invalid description: %w", err)
  1693  			}
  1694  
  1695  			msg, err := types.NewMsgSubmitProposal(
  1696  				clientCtx.FromAddress,
  1697  				title,
  1698  				description,
  1699  				types.NewRemoveWhitelistedRolePermissionProposal(
  1700  					args[0],
  1701  					types.PermValue(perm),
  1702  				),
  1703  			)
  1704  			if err != nil {
  1705  				return err
  1706  			}
  1707  
  1708  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1709  		},
  1710  	}
  1711  
  1712  	flags.AddTxFlagsToCmd(cmd)
  1713  
  1714  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1715  	cmd.MarkFlagRequired(FlagTitle)
  1716  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1717  	cmd.MarkFlagRequired(FlagDescription)
  1718  	cmd.MarkFlagRequired(flags.FlagFrom)
  1719  
  1720  	return cmd
  1721  }
  1722  
  1723  func GetTxProposalRemoveBlacklistedRolePermission() *cobra.Command {
  1724  	cmd := &cobra.Command{
  1725  		Use:   "remove-blacklisted-permission [role_sid] [permission_id]",
  1726  		Short: "Raise governance proposal to remove a blacklisted permission from a role.",
  1727  		Args:  cobra.ExactArgs(2),
  1728  		RunE: func(cmd *cobra.Command, args []string) error {
  1729  			clientCtx, err := client.GetClientTxContext(cmd)
  1730  			if err != nil {
  1731  				return err
  1732  			}
  1733  
  1734  			perm, err := strconv.Atoi(args[1])
  1735  			if err != nil {
  1736  				return err
  1737  			}
  1738  
  1739  			title, err := cmd.Flags().GetString(FlagTitle)
  1740  			if err != nil {
  1741  				return fmt.Errorf("invalid title: %w", err)
  1742  			}
  1743  
  1744  			description, err := cmd.Flags().GetString(FlagDescription)
  1745  			if err != nil {
  1746  				return fmt.Errorf("invalid description: %w", err)
  1747  			}
  1748  
  1749  			msg, err := types.NewMsgSubmitProposal(
  1750  				clientCtx.FromAddress,
  1751  				title,
  1752  				description,
  1753  				types.NewRemoveBlacklistedRolePermissionProposal(
  1754  					args[0],
  1755  					types.PermValue(perm),
  1756  				),
  1757  			)
  1758  			if err != nil {
  1759  				return err
  1760  			}
  1761  
  1762  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1763  		},
  1764  	}
  1765  
  1766  	flags.AddTxFlagsToCmd(cmd)
  1767  
  1768  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1769  	cmd.MarkFlagRequired(FlagTitle)
  1770  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1771  	cmd.MarkFlagRequired(FlagDescription)
  1772  	cmd.MarkFlagRequired(flags.FlagFrom)
  1773  
  1774  	return cmd
  1775  }
  1776  
  1777  func GetTxProposalSetProposalDurations() *cobra.Command {
  1778  	cmd := &cobra.Command{
  1779  		Use:   "set-proposal-durations-proposal [proposal_types] [durations]",
  1780  		Short: "Create a proposal to set batch proposal durations.",
  1781  		Args:  cobra.ExactArgs(2),
  1782  		RunE: func(cmd *cobra.Command, args []string) error {
  1783  			clientCtx, err := client.GetClientTxContext(cmd)
  1784  			if err != nil {
  1785  				return err
  1786  			}
  1787  
  1788  			proposalTypes := strings.Split(args[0], ",")
  1789  			proposalDurationStrs := strings.Split(args[1], ",")
  1790  			proposalDurations := []uint64{}
  1791  			for _, durationStr := range proposalDurationStrs {
  1792  				duration, err := strconv.Atoi(durationStr)
  1793  				if err != nil {
  1794  					return err
  1795  				}
  1796  				proposalDurations = append(proposalDurations, uint64(duration))
  1797  			}
  1798  
  1799  			title, err := cmd.Flags().GetString(FlagTitle)
  1800  			if err != nil {
  1801  				return fmt.Errorf("invalid title: %w", err)
  1802  			}
  1803  
  1804  			description, err := cmd.Flags().GetString(FlagDescription)
  1805  			if err != nil {
  1806  				return fmt.Errorf("invalid description: %w", err)
  1807  			}
  1808  
  1809  			msg, err := types.NewMsgSubmitProposal(
  1810  				clientCtx.FromAddress,
  1811  				title,
  1812  				description,
  1813  				types.NewSetProposalDurationsProposal(
  1814  					proposalTypes,
  1815  					proposalDurations,
  1816  				),
  1817  			)
  1818  			if err != nil {
  1819  				return err
  1820  			}
  1821  
  1822  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1823  		},
  1824  	}
  1825  
  1826  	flags.AddTxFlagsToCmd(cmd)
  1827  
  1828  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  1829  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  1830  	cmd.MarkFlagRequired(FlagTitle)
  1831  	cmd.MarkFlagRequired(FlagDescription)
  1832  	cmd.MarkFlagRequired(flags.FlagFrom)
  1833  
  1834  	return cmd
  1835  }
  1836  
  1837  func GetTxRegisterIdentityRecords() *cobra.Command {
  1838  	cmd := &cobra.Command{
  1839  		Use:   "register-identity-records",
  1840  		Short: "Submit a transaction to create an identity record.",
  1841  		Args:  cobra.ExactArgs(0),
  1842  		RunE: func(cmd *cobra.Command, args []string) error {
  1843  			clientCtx, err := client.GetClientTxContext(cmd)
  1844  			if err != nil {
  1845  				return err
  1846  			}
  1847  
  1848  			infos, err := parseIdInfoJSON(cmd.Flags())
  1849  			if err != nil {
  1850  				return err
  1851  			}
  1852  
  1853  			msg := types.NewMsgRegisterIdentityRecords(
  1854  				clientCtx.FromAddress,
  1855  				infos,
  1856  			)
  1857  
  1858  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1859  		},
  1860  	}
  1861  
  1862  	flags.AddTxFlagsToCmd(cmd)
  1863  
  1864  	cmd.Flags().String(FlagInfosFile, "", "The infos file for identity request.")
  1865  	cmd.Flags().String(FlagInfosJson, "", "The infos json for identity request.")
  1866  	cmd.MarkFlagRequired(flags.FlagFrom)
  1867  
  1868  	return cmd
  1869  }
  1870  
  1871  func GetTxDeleteIdentityRecords() *cobra.Command {
  1872  	cmd := &cobra.Command{
  1873  		Use:   "delete-identity-records",
  1874  		Short: "Submit a transaction to delete an identity records.",
  1875  		Args:  cobra.ExactArgs(0),
  1876  		RunE: func(cmd *cobra.Command, args []string) error {
  1877  			clientCtx, err := client.GetClientTxContext(cmd)
  1878  			if err != nil {
  1879  				return err
  1880  			}
  1881  
  1882  			keysStr, err := cmd.Flags().GetString(FlagKeys)
  1883  			if err != nil {
  1884  				return err
  1885  			}
  1886  
  1887  			keys := strings.Split(keysStr, ",")
  1888  			if keysStr == "" {
  1889  				keys = []string{}
  1890  			}
  1891  
  1892  			msg := types.NewMsgDeleteIdentityRecords(
  1893  				clientCtx.FromAddress,
  1894  				keys,
  1895  			)
  1896  
  1897  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1898  		},
  1899  	}
  1900  
  1901  	flags.AddTxFlagsToCmd(cmd)
  1902  
  1903  	cmd.Flags().String(FlagKeys, "", "The keys to remove.")
  1904  	cmd.MarkFlagRequired(flags.FlagFrom)
  1905  
  1906  	return cmd
  1907  }
  1908  
  1909  func GetTxRequestIdentityRecordsVerify() *cobra.Command {
  1910  	cmd := &cobra.Command{
  1911  		Use:   "request-identity-record-verify",
  1912  		Short: "Submit a transaction to request an identity verify record.",
  1913  		Args:  cobra.ExactArgs(0),
  1914  		RunE: func(cmd *cobra.Command, args []string) error {
  1915  			clientCtx, err := client.GetClientTxContext(cmd)
  1916  			if err != nil {
  1917  				return err
  1918  			}
  1919  
  1920  			verifierText, err := cmd.Flags().GetString(FlagVerifier)
  1921  			if err != nil {
  1922  				return err
  1923  			}
  1924  			verifier, err := sdk.AccAddressFromBech32(verifierText)
  1925  
  1926  			recordIdsStr, err := cmd.Flags().GetString(FlagRecordIds)
  1927  			if err != nil {
  1928  				return err
  1929  			}
  1930  
  1931  			recordIdsSplit := strings.Split(recordIdsStr, ",")
  1932  			recordIds := []uint64{}
  1933  			for _, str := range recordIdsSplit {
  1934  				id, err := strconv.ParseUint(str, 10, 64)
  1935  				if err != nil {
  1936  					return err
  1937  				}
  1938  				recordIds = append(recordIds, id)
  1939  			}
  1940  
  1941  			tipStr, err := cmd.Flags().GetString(FlagVerifierTip)
  1942  			if err != nil {
  1943  				return err
  1944  			}
  1945  			coin, err := sdk.ParseCoinNormalized(tipStr)
  1946  			if err != nil {
  1947  				return err
  1948  			}
  1949  
  1950  			msg := types.NewMsgRequestIdentityRecordsVerify(
  1951  				clientCtx.FromAddress,
  1952  				verifier,
  1953  				recordIds,
  1954  				coin,
  1955  			)
  1956  
  1957  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  1958  		},
  1959  	}
  1960  
  1961  	flags.AddTxFlagsToCmd(cmd)
  1962  
  1963  	cmd.Flags().String(FlagVerifierTip, "", "The tip to be given to the verifier.")
  1964  	cmd.Flags().String(FlagRecordIds, "", "Concatenated identity record ids array. e.g. 1,2")
  1965  	cmd.Flags().String(FlagVerifier, "", "The verifier of the record ids")
  1966  	cmd.MarkFlagRequired(FlagRecordIds)
  1967  	cmd.MarkFlagRequired(FlagVerifier)
  1968  	cmd.MarkFlagRequired(flags.FlagFrom)
  1969  
  1970  	return cmd
  1971  }
  1972  
  1973  func GetTxHandleIdentityRecordsVerifyRequest() *cobra.Command {
  1974  	cmd := &cobra.Command{
  1975  		Use:   "handle-identity-records-verify-request [id]",
  1976  		Short: "Submit a transaction to approve or reject identity records verify request.",
  1977  		Args:  cobra.ExactArgs(1),
  1978  		RunE: func(cmd *cobra.Command, args []string) error {
  1979  			clientCtx, err := client.GetClientTxContext(cmd)
  1980  			if err != nil {
  1981  				return err
  1982  			}
  1983  
  1984  			requestId, err := strconv.ParseUint(args[0], 10, 64)
  1985  			if err != nil {
  1986  				return err
  1987  			}
  1988  
  1989  			isApprove, err := cmd.Flags().GetBool(FlagApprove)
  1990  			if err != nil {
  1991  				return err
  1992  			}
  1993  
  1994  			msg := types.NewMsgHandleIdentityRecordsVerifyRequest(
  1995  				clientCtx.FromAddress,
  1996  				requestId,
  1997  				isApprove,
  1998  			)
  1999  
  2000  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2001  		},
  2002  	}
  2003  
  2004  	cmd.Flags().Bool(FlagApprove, true, "The flag to approve or reject")
  2005  	cmd.MarkFlagRequired(FlagApprove)
  2006  	flags.AddTxFlagsToCmd(cmd)
  2007  	cmd.MarkFlagRequired(flags.FlagFrom)
  2008  
  2009  	return cmd
  2010  }
  2011  
  2012  func GetTxCancelIdentityRecordsVerifyRequest() *cobra.Command {
  2013  	cmd := &cobra.Command{
  2014  		Use:   "cancel-identity-records-verify-request [id]",
  2015  		Short: "Submit a transaction to cancel identity records verification request.",
  2016  		Args:  cobra.ExactArgs(1),
  2017  		RunE: func(cmd *cobra.Command, args []string) error {
  2018  			clientCtx, err := client.GetClientTxContext(cmd)
  2019  			if err != nil {
  2020  				return err
  2021  			}
  2022  
  2023  			requestId, err := strconv.ParseUint(args[0], 10, 64)
  2024  			if err != nil {
  2025  				return err
  2026  			}
  2027  
  2028  			msg := types.NewMsgCancelIdentityRecordsVerifyRequest(
  2029  				clientCtx.FromAddress,
  2030  				requestId,
  2031  			)
  2032  
  2033  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2034  		},
  2035  	}
  2036  
  2037  	flags.AddTxFlagsToCmd(cmd)
  2038  	cmd.MarkFlagRequired(flags.FlagFrom)
  2039  
  2040  	return cmd
  2041  }
  2042  
  2043  func GetTxPollCreate() *cobra.Command {
  2044  	cmd := &cobra.Command{
  2045  		Use:   "create",
  2046  		Short: "Create a poll.",
  2047  		Args:  cobra.ExactArgs(0),
  2048  		RunE: func(cmd *cobra.Command, args []string) error {
  2049  			clientCtx, err := client.GetClientTxContext(cmd)
  2050  			if err != nil {
  2051  				return err
  2052  			}
  2053  
  2054  			title, err := cmd.Flags().GetString(FlagTitle)
  2055  			if err != nil {
  2056  				return fmt.Errorf("invalid title: %w", err)
  2057  			}
  2058  
  2059  			description, err := cmd.Flags().GetString(FlagDescription)
  2060  			if err != nil {
  2061  				return fmt.Errorf("invalid description: %w", err)
  2062  			}
  2063  
  2064  			reference, err := cmd.Flags().GetString(FlagPollReference)
  2065  			if err != nil {
  2066  				return fmt.Errorf("invalid reference: %w", err)
  2067  			}
  2068  
  2069  			checksum, err := cmd.Flags().GetString(FlagPollChecksum)
  2070  			if err != nil {
  2071  				return fmt.Errorf("invalid checksum: %w", err)
  2072  			}
  2073  
  2074  			options, err := cmd.Flags().GetStringSlice(FlagPollOptions)
  2075  			if err != nil {
  2076  				return fmt.Errorf("invalid options: %w", err)
  2077  			}
  2078  
  2079  			var filteredOptions []string
  2080  			for _, v := range options {
  2081  				filteredOptions = append(filteredOptions, strings.ToLower(strings.TrimSpace(v)))
  2082  			}
  2083  
  2084  			roles, err := cmd.Flags().GetStringSlice(FlagPollRoles)
  2085  			if err != nil {
  2086  				return fmt.Errorf("invalid roles: %w", err)
  2087  			}
  2088  
  2089  			valueCount, err := cmd.Flags().GetUint64(FlagPollCount)
  2090  			if err != nil {
  2091  				return fmt.Errorf("invalid count: %w", err)
  2092  			}
  2093  
  2094  			valueType, err := cmd.Flags().GetString(FlagPollType)
  2095  			if err != nil {
  2096  				return fmt.Errorf("invalid type: %w", err)
  2097  			}
  2098  
  2099  			possibleChoices, err := cmd.Flags().GetUint64(FlagPollChoices)
  2100  			if err != nil {
  2101  				return fmt.Errorf("invalid choices: %w", err)
  2102  			}
  2103  
  2104  			duration, err := cmd.Flags().GetString(FlagPollDuration)
  2105  			if err != nil {
  2106  				return fmt.Errorf("invalid duration: %w", err)
  2107  			}
  2108  
  2109  			msg := types.NewMsgPollCreate(
  2110  				clientCtx.FromAddress,
  2111  				title,
  2112  				description,
  2113  				reference,
  2114  				checksum,
  2115  				filteredOptions,
  2116  				roles,
  2117  				valueCount,
  2118  				valueType,
  2119  				possibleChoices,
  2120  				duration,
  2121  			)
  2122  
  2123  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2124  		},
  2125  	}
  2126  
  2127  	flags.AddTxFlagsToCmd(cmd)
  2128  	cmd.Flags().String(FlagTitle, "", "The title of the poll.")
  2129  	cmd.MarkFlagRequired(FlagTitle)
  2130  	cmd.Flags().String(FlagDescription, "", "The description of the poll, it can be an url, some text, etc.")
  2131  	cmd.MarkFlagRequired(FlagDescription)
  2132  	cmd.Flags().String(FlagPollReference, "", "IPFS CID or URL reference to file describing poll and voting options in depth.")
  2133  	cmd.Flags().String(FlagPollChecksum, "", "Reference checksum.")
  2134  	cmd.Flags().StringSlice(FlagPollOptions, []string{}, "The options value in the format variant1,variant2.")
  2135  	cmd.MarkFlagRequired(FlagPollOptions)
  2136  	cmd.Flags().StringSlice(FlagPollRoles, []string{}, "List of roles that are allowed to take part in the poll vote in the format role1,role2.")
  2137  	cmd.MarkFlagRequired(FlagPollRoles)
  2138  	cmd.Flags().Uint64(FlagPollCount, 128, "Maximum number of voting options that poll can have.")
  2139  	cmd.Flags().String(FlagPollType, "", "Type of the options, all user supplied or predefined options must match its type.")
  2140  	cmd.MarkFlagRequired(FlagPollType)
  2141  	cmd.Flags().Uint64(FlagPollChoices, 1, "Should define maximum number of choices that voter can select.")
  2142  	cmd.Flags().String(FlagPollDuration, "", "The duration of the poll.")
  2143  	cmd.MarkFlagRequired(FlagPollDuration)
  2144  	cmd.MarkFlagRequired(flags.FlagFrom)
  2145  
  2146  	return cmd
  2147  }
  2148  
  2149  func GetTxVotePoll() *cobra.Command {
  2150  	cmd := &cobra.Command{
  2151  		Use:   "vote [poll-id] [poll-option] ",
  2152  		Short: "Vote a poll.",
  2153  		Args:  cobra.ExactArgs(2),
  2154  		RunE: func(cmd *cobra.Command, args []string) error {
  2155  			clientCtx, err := client.GetClientTxContext(cmd)
  2156  			if err != nil {
  2157  				return err
  2158  			}
  2159  
  2160  			pollID, err := strconv.Atoi(args[0])
  2161  			if err != nil {
  2162  				return fmt.Errorf("invalid poll ID: %w", err)
  2163  			}
  2164  
  2165  			optionID, err := strconv.Atoi(args[1])
  2166  			if err != nil {
  2167  				return fmt.Errorf("invalid option ID: %w", err)
  2168  			}
  2169  
  2170  			value, err := cmd.Flags().GetString(FlagCustomPollValue)
  2171  			if err != nil {
  2172  				return fmt.Errorf("invalid custom value: %w", err)
  2173  			}
  2174  
  2175  			msg := types.NewMsgVotePoll(
  2176  				uint64(pollID),
  2177  				clientCtx.FromAddress,
  2178  				types.PollVoteOption(optionID),
  2179  				value,
  2180  			)
  2181  
  2182  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2183  		},
  2184  	}
  2185  
  2186  	flags.AddTxFlagsToCmd(cmd)
  2187  	cmd.Flags().String(FlagCustomPollValue, "", "The custom poll value.")
  2188  	cmd.MarkFlagRequired(flags.FlagFrom)
  2189  
  2190  	return cmd
  2191  }
  2192  
  2193  func parseIdInfoJSON(fs *pflag.FlagSet) ([]types.IdentityInfoEntry, error) {
  2194  	var err error
  2195  	infos := make(map[string]string)
  2196  	infosFile, _ := fs.GetString(FlagInfosFile)
  2197  	infosJson, _ := fs.GetString(FlagInfosJson)
  2198  
  2199  	if infosFile == "" && infosJson == "" {
  2200  		return nil, fmt.Errorf("should input infos file json using the --%s flag or infos json using the --%s flag", FlagInfosFile, FlagInfosJson)
  2201  	}
  2202  
  2203  	if infosFile != "" && infosJson != "" {
  2204  		return nil, fmt.Errorf("should only set one of --%s flag or --%s flag", FlagInfosFile, FlagInfosJson)
  2205  	}
  2206  
  2207  	contents := []byte(infosJson)
  2208  
  2209  	if infosFile != "" {
  2210  		contents, err = ioutil.ReadFile(infosFile)
  2211  		if err != nil {
  2212  			return nil, err
  2213  		}
  2214  	}
  2215  
  2216  	// make exception if unknown field exists
  2217  	err = json.Unmarshal(contents, &infos)
  2218  	if err != nil {
  2219  		return nil, err
  2220  	}
  2221  
  2222  	return types.WrapInfos(infos), nil
  2223  }
  2224  
  2225  // GetTxProposalResetWholeCouncilorRankCmd implement cli command for ProposalResetWholeCouncilorRank
  2226  func GetTxProposalResetWholeCouncilorRankCmd() *cobra.Command {
  2227  	cmd := &cobra.Command{
  2228  		Use:   "proposal-reset-whole-councilor-rank",
  2229  		Short: "Create a proposal to reset whole councilor rank",
  2230  		Args:  cobra.ExactArgs(0),
  2231  		RunE: func(cmd *cobra.Command, args []string) error {
  2232  			clientCtx, err := client.GetClientTxContext(cmd)
  2233  			if err != nil {
  2234  				return err
  2235  			}
  2236  			title, err := cmd.Flags().GetString(FlagTitle)
  2237  			if err != nil {
  2238  				return fmt.Errorf("invalid title: %w", err)
  2239  			}
  2240  			description, err := cmd.Flags().GetString(FlagDescription)
  2241  			if err != nil {
  2242  				return fmt.Errorf("invalid description: %w", err)
  2243  			}
  2244  
  2245  			msg, err := types.NewMsgSubmitProposal(
  2246  				clientCtx.FromAddress,
  2247  				title,
  2248  				description,
  2249  				types.NewResetWholeCouncilorRankProposal(clientCtx.FromAddress),
  2250  			)
  2251  			if err != nil {
  2252  				return err
  2253  			}
  2254  
  2255  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2256  		},
  2257  	}
  2258  
  2259  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  2260  	cmd.MarkFlagRequired(FlagTitle)
  2261  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  2262  	cmd.MarkFlagRequired(FlagDescription)
  2263  
  2264  	flags.AddTxFlagsToCmd(cmd)
  2265  	_ = cmd.MarkFlagRequired(flags.FlagFrom)
  2266  
  2267  	return cmd
  2268  }
  2269  
  2270  // GetTxProposalJailCouncilorCmd implement cli command for ProposalJailCouncilor
  2271  func GetTxProposalJailCouncilorCmd() *cobra.Command {
  2272  	cmd := &cobra.Command{
  2273  		Use:   "proposal-jail-councilor [councilors]",
  2274  		Short: "Create a proposal to jail councilors",
  2275  		Args:  cobra.ExactArgs(1),
  2276  		RunE: func(cmd *cobra.Command, args []string) error {
  2277  			clientCtx, err := client.GetClientTxContext(cmd)
  2278  			if err != nil {
  2279  				return err
  2280  			}
  2281  			title, err := cmd.Flags().GetString(FlagTitle)
  2282  			if err != nil {
  2283  				return fmt.Errorf("invalid title: %w", err)
  2284  			}
  2285  			description, err := cmd.Flags().GetString(FlagDescription)
  2286  			if err != nil {
  2287  				return fmt.Errorf("invalid description: %w", err)
  2288  			}
  2289  
  2290  			councilors := strings.Split(args[0], ",")
  2291  
  2292  			msg, err := types.NewMsgSubmitProposal(
  2293  				clientCtx.FromAddress,
  2294  				title,
  2295  				description,
  2296  				types.NewJailCouncilorProposal(clientCtx.FromAddress, description, councilors),
  2297  			)
  2298  			if err != nil {
  2299  				return err
  2300  			}
  2301  
  2302  			return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
  2303  		},
  2304  	}
  2305  
  2306  	cmd.Flags().String(FlagTitle, "", "The title of the proposal.")
  2307  	cmd.MarkFlagRequired(FlagTitle)
  2308  	cmd.Flags().String(FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.")
  2309  	cmd.MarkFlagRequired(FlagDescription)
  2310  
  2311  	flags.AddTxFlagsToCmd(cmd)
  2312  	_ = cmd.MarkFlagRequired(flags.FlagFrom)
  2313  
  2314  	return cmd
  2315  }
  2316  
  2317  // convertAsPermValues convert array of int32 to PermValue array.
  2318  func convertAsPermValues(values []int32) []types.PermValue {
  2319  	var v []types.PermValue
  2320  	for _, perm := range values {
  2321  		v = append(v, types.PermValue(perm))
  2322  	}
  2323  
  2324  	return v
  2325  }
  2326  
  2327  // convertAsPermValues convert array of int32 to PermValue array.
  2328  func convertAsOptionValues(values []int32) []types.PollVoteOption {
  2329  	var v []types.PollVoteOption
  2330  	for _, option := range values {
  2331  		v = append(v, types.PollVoteOption(option))
  2332  	}
  2333  
  2334  	return v
  2335  }