github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/distribution/client/cli/tx.go (about)

     1  // nolint
     2  package cli
     3  
     4  import (
     5  	"bufio"
     6  	"fmt"
     7  	interfacetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types"
     8  	"github.com/spf13/viper"
     9  	"os"
    10  	"strings"
    11  
    12  	"github.com/spf13/cobra"
    13  
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    18  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    19  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/client/utils"
    22  	"github.com/fibonacci-chain/fbc/x/distribution/client/common"
    23  	"github.com/fibonacci-chain/fbc/x/distribution/types"
    24  	"github.com/fibonacci-chain/fbc/x/gov"
    25  )
    26  
    27  // GetTxCmd returns the transaction commands for this module
    28  func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
    29  	distTxCmd := &cobra.Command{
    30  		Use:                        types.ShortUseByCli,
    31  		Short:                      "Distribution transactions subcommands",
    32  		DisableFlagParsing:         true,
    33  		SuggestionsMinimumDistance: 2,
    34  		RunE:                       client.ValidateCmd,
    35  	}
    36  
    37  	distTxCmd.AddCommand(flags.PostCommands(
    38  		GetCmdWithdrawRewards(cdc),
    39  		GetCmdSetWithdrawAddr(cdc),
    40  		GetCmdWithdrawAllRewards(cdc, storeKey),
    41  	)...)
    42  
    43  	return distTxCmd
    44  }
    45  
    46  // command to replace a delegator's withdrawal address
    47  func GetCmdSetWithdrawAddr(cdc *codec.Codec) *cobra.Command {
    48  	return &cobra.Command{
    49  		Use:   "set-withdraw-addr [withdraw-addr]",
    50  		Short: "change the default withdraw address for rewards associated with an address",
    51  		Long: strings.TrimSpace(
    52  			fmt.Sprintf(`Set the withdraw address for rewards associated with a delegator address.
    53  
    54  Example:
    55  $ %s tx distr set-withdraw-addr fb1cftp8q8g4aa65nw9s5trwexe77d9t6cr8ndu02 --from mykey
    56  `,
    57  				version.ClientName,
    58  			),
    59  		),
    60  		Args: cobra.ExactArgs(1),
    61  		RunE: func(cmd *cobra.Command, args []string) error {
    62  			inBuf := bufio.NewReader(cmd.InOrStdin())
    63  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
    64  			cliCtx := context.NewCLIContext().WithCodec(cdc)
    65  
    66  			delAddr := cliCtx.GetFromAddress()
    67  			withdrawAddr, err := sdk.AccAddressFromBech32(args[0])
    68  			if err != nil {
    69  				return fmt.Errorf("invalid address:%s", args[0])
    70  			}
    71  
    72  			msg := types.NewMsgSetWithdrawAddress(delAddr, withdrawAddr)
    73  			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
    74  		},
    75  	}
    76  }
    77  
    78  // GetCmdWithdrawRewards command to withdraw rewards
    79  func GetCmdWithdrawRewards(cdc *codec.Codec) *cobra.Command {
    80  	cmd := &cobra.Command{
    81  		Use:   "withdraw-rewards [validator-addr]",
    82  		Short: "withdraw rewards from a given delegation address, and optionally withdraw validator commission if the delegation address given is a validator operator",
    83  		Long: strings.TrimSpace(
    84  			fmt.Sprintf(`Withdraw rewards from a given delegation address, 
    85  and optionally withdraw validator commission if the delegation address given is a validator operator
    86  
    87  Example:
    88  $ %s tx distr withdraw-rewards fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg --from mykey 
    89  $ %s tx distr withdraw-rewards fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg --from mykey --commission
    90  
    91  If this command is used without "--commission", and the address you want to withdraw rewards is both validator and delegator, 
    92  only the delegator's rewards can be withdrqw. However, if the address you want to withdraw rewards is only the validator, 
    93  the validator commissions will be withdrqw.
    94  Example:
    95  $ %s tx distr withdraw-rewards fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg --from mykey(validator)	--commission    # withdraw mykey's commission only
    96  $ %s tx distr withdraw-rewards fbvaloper1alq9na49n9yycysh889rl90g9nhe58lcqkfpfg --from mykey(validator&delegator)	    # withdraw mykey's reward only
    97  `,
    98  				version.ClientName, version.ClientName, version.ClientName, version.ClientName,
    99  			),
   100  		),
   101  		Args: cobra.ExactArgs(1),
   102  		RunE: func(cmd *cobra.Command, args []string) error {
   103  			inBuf := bufio.NewReader(cmd.InOrStdin())
   104  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
   105  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   106  
   107  			delAddr := cliCtx.GetFromAddress()
   108  			valAddr, err := sdk.ValAddressFromBech32(args[0])
   109  			if err != nil {
   110  				return err
   111  			}
   112  
   113  			isVal := common.IsValidator(cliCtx, cdc, sdk.ValAddress(delAddr))
   114  			isDel := common.IsDelegator(cliCtx, cdc, delAddr)
   115  			needWarning := false
   116  
   117  			msgs := []sdk.Msg{}
   118  			if viper.GetBool(flagCommission) || (isVal && !isDel) {
   119  				msgs = append(msgs, types.NewMsgWithdrawValidatorCommission(valAddr))
   120  			} else {
   121  				msgs = append(msgs, types.NewMsgWithdrawDelegatorReward(delAddr, valAddr))
   122  				if isVal && isDel {
   123  					needWarning = true
   124  				}
   125  			}
   126  
   127  			result := transWrapError(common.NewWrapError(utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, msgs)), delAddr, valAddr)
   128  			if needWarning {
   129  				_, err = fmt.Fprintf(os.Stdout, "%s\n", fmt.Sprintf("\nFound address: \"%s\" is a validator, please add the `--commission` flag to the command line if you want to withdraw the commission, for example:\n"+
   130  					"%s ..... --commission.\n",
   131  					delAddr.String(), version.ClientName))
   132  				if err != nil {
   133  					return err
   134  				}
   135  			}
   136  			return result
   137  		},
   138  	}
   139  	cmd.Flags().Bool(flagCommission, false, "withdraw validator's commission")
   140  	return cmd
   141  }
   142  
   143  func transWrapError(wrapErr *common.WrapError, delAddr sdk.AccAddress, valAddr sdk.ValAddress) error {
   144  	if wrapErr == nil {
   145  		return nil
   146  	}
   147  
   148  	wrapErr.Trans(types.CodeEmptyDelegationDistInfo, fmt.Sprintf("found account %s is not a delegator, please check it first", delAddr.String()))
   149  	wrapErr.Trans(types.CodeNoValidatorCommission, fmt.Sprintf("found account %s is not a validator, please check it first", delAddr.String()))
   150  	wrapErr.Trans(types.CodeEmptyValidatorDistInfo, fmt.Sprintf("found validator address %s is not a validator, please check it first", valAddr.String()))
   151  	wrapErr.Trans(types.CodeEmptyDelegationVoteValidator, fmt.Sprintf("found validator address %s haven't been voted, please check it first", valAddr.String()))
   152  	if wrapErr.Changed {
   153  		return wrapErr
   154  	}
   155  
   156  	return wrapErr.RawError
   157  }
   158  
   159  // GetCmdCommunityPoolSpendProposal implements the command to submit a community-pool-spend proposal
   160  func GetCmdCommunityPoolSpendProposal(cdcP *codec.CodecProxy, reg interfacetypes.InterfaceRegistry) *cobra.Command {
   161  	cmd := &cobra.Command{
   162  		Use:   "community-pool-spend [proposal-file]",
   163  		Args:  cobra.ExactArgs(1),
   164  		Short: "Submit a community pool spend proposal",
   165  		Long: strings.TrimSpace(
   166  			fmt.Sprintf(`Submit a community pool spend proposal along with an initial deposit.
   167  The proposal details must be supplied via a JSON file.
   168  
   169  Example:
   170  $ %s tx gov submit-proposal community-pool-spend <path/to/proposal.json> --from=<key_or_address>
   171  
   172  Where proposal.json contains:
   173  
   174  {
   175    "title": "Community Pool Spend",
   176    "description": "Pay me some %s!",
   177    "recipient": "fb1cftp8q8g4aa65nw9s5trwexe77d9t6cr8ndu02",
   178    "amount": [
   179      {
   180        "denom": "%s",
   181        "amount": "10000"
   182      }
   183    ],
   184    "deposit": [
   185      {
   186        "denom": "%s",
   187        "amount": "10000"
   188      }
   189    ]
   190  }
   191  `,
   192  				version.ClientName, sdk.DefaultBondDenom, sdk.DefaultBondDenom, sdk.DefaultBondDenom,
   193  			),
   194  		),
   195  		RunE: func(cmd *cobra.Command, args []string) error {
   196  			cdc := cdcP.GetCdc()
   197  			inBuf := bufio.NewReader(cmd.InOrStdin())
   198  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
   199  			cliCtx := context.NewCLIContext().WithCodec(cdc)
   200  
   201  			proposal, err := ParseCommunityPoolSpendProposalJSON(cdc, args[0])
   202  			if err != nil {
   203  				return err
   204  			}
   205  
   206  			from := cliCtx.GetFromAddress()
   207  			content := types.NewCommunityPoolSpendProposal(proposal.Title, proposal.Description, proposal.Recipient, proposal.Amount)
   208  
   209  			msg := gov.NewMsgSubmitProposal(content, proposal.Deposit, from)
   210  			if err := msg.ValidateBasic(); err != nil {
   211  				return err
   212  			}
   213  
   214  			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
   215  		},
   216  	}
   217  
   218  	return cmd
   219  }