github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/feesplit/client/cli/tx.go (about) 1 package cli 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "fmt" 7 "strings" 8 9 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client" 10 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context" 11 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags" 12 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 13 interfacetypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec/types" 14 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 15 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version" 16 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth" 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/client/utils" 18 fsutils "github.com/fibonacci-chain/fbc/x/feesplit/client/utils" 19 "github.com/fibonacci-chain/fbc/x/feesplit/types" 20 govTypes "github.com/fibonacci-chain/fbc/x/gov/types" 21 22 "github.com/spf13/cobra" 23 ) 24 25 // GetTxCmd returns a root CLI command handler for certain modules/feesplit 26 // transaction commands. 27 func GetTxCmd(cdc *codec.Codec) *cobra.Command { 28 cmd := &cobra.Command{ 29 Use: types.ModuleName, 30 Short: "feesplit subcommands", 31 DisableFlagParsing: true, 32 SuggestionsMinimumDistance: 2, 33 RunE: client.ValidateCmd, 34 } 35 36 cmd.AddCommand(flags.PostCommands( 37 GetRegisterFeeSplit(cdc), 38 GetCancelFeeSplit(cdc), 39 GetUpdateFeeSplit(cdc), 40 )...) 41 return cmd 42 } 43 44 // GetRegisterFeeSplit returns a CLI command handler for registering a 45 // contract for fee distribution 46 func GetRegisterFeeSplit(cdc *codec.Codec) *cobra.Command { 47 cmd := &cobra.Command{ 48 Use: "register [contract_hex] [nonces] [withdraw_bech32]", 49 Short: "Register a contract for fee distribution. **NOTE** Please ensure, that the deployer of the contract (or the factory that deployes the contract) is an account that is owned by your project, to avoid that an individual deployer who leaves your project becomes malicious.", 50 Long: "Register a contract for fee distribution.\nOnly the contract deployer can register a contract.\nProvide the account nonce(s) used to derive the contract address. E.g.: you have an account nonce of 4 when you send a deployment transaction for a contract A; you use this contract as a factory, to create another contract B. If you register A, the nonces value is \"4\". If you register B, the nonces value is \"4,1\" (B is the first contract created by A). \nThe withdraw address defaults to the deployer address if not provided.", 51 Args: cobra.RangeArgs(2, 3), 52 RunE: func(cmd *cobra.Command, args []string) error { 53 inBuf := bufio.NewReader(cmd.InOrStdin()) 54 txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) 55 cliCtx := context.NewCLIContext().WithCodec(cdc) 56 57 var withdraw string 58 deployer := cliCtx.GetFromAddress() 59 60 contract := args[0] 61 if err := types.ValidateNonZeroAddress(contract); err != nil { 62 return fmt.Errorf("invalid contract hex address %w", err) 63 } 64 65 var nonces []uint64 66 if err := json.Unmarshal([]byte("["+args[1]+"]"), &nonces); err != nil { 67 return fmt.Errorf("invalid nonces %w", err) 68 } 69 70 if len(args) == 3 { 71 withdraw = args[2] 72 if _, err := sdk.AccAddressFromBech32(withdraw); err != nil { 73 return fmt.Errorf("invalid withdraw bech32 address %w", err) 74 } 75 } 76 77 if withdraw == "" { 78 withdraw = deployer.String() 79 } 80 81 msg := &types.MsgRegisterFeeSplit{ 82 ContractAddress: contract, 83 DeployerAddress: deployer.String(), 84 WithdrawerAddress: withdraw, 85 Nonces: nonces, 86 } 87 if err := msg.ValidateBasic(); err != nil { 88 return err 89 } 90 91 return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) 92 }, 93 } 94 95 return cmd 96 } 97 98 // GetCancelFeeSplit returns a CLI command handler for canceling a 99 // contract for fee distribution 100 func GetCancelFeeSplit(cdc *codec.Codec) *cobra.Command { 101 cmd := &cobra.Command{ 102 Use: "cancel [contract_hex]", 103 Short: "Cancel a contract from fee distribution", 104 Long: "Cancel a contract from fee distribution. The deployer will no longer receive fees from users interacting with the contract. \nOnly the contract deployer can cancel a contract.", 105 Args: cobra.ExactArgs(1), 106 RunE: func(cmd *cobra.Command, args []string) error { 107 inBuf := bufio.NewReader(cmd.InOrStdin()) 108 txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) 109 cliCtx := context.NewCLIContext().WithCodec(cdc) 110 111 deployer := cliCtx.GetFromAddress() 112 113 contract := args[0] 114 if err := types.ValidateNonZeroAddress(contract); err != nil { 115 return fmt.Errorf("invalid contract hex address %w", err) 116 } 117 118 msg := &types.MsgCancelFeeSplit{ 119 ContractAddress: contract, 120 DeployerAddress: deployer.String(), 121 } 122 123 if err := msg.ValidateBasic(); err != nil { 124 return err 125 } 126 127 return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) 128 }, 129 } 130 131 return cmd 132 } 133 134 // GetUpdateFeeSplit returns a CLI command handler for updating the withdraw 135 // address of a contract for fee distribution 136 func GetUpdateFeeSplit(cdc *codec.Codec) *cobra.Command { 137 cmd := &cobra.Command{ 138 Use: "update [contract_hex] [withdraw_bech32]", 139 Short: "Update withdraw address for a contract registered for fee distribution.", 140 Long: "Update withdraw address for a contract registered for fee distribution. \nOnly the contract deployer can update the withdraw address.", 141 Args: cobra.ExactArgs(2), 142 RunE: func(cmd *cobra.Command, args []string) error { 143 inBuf := bufio.NewReader(cmd.InOrStdin()) 144 txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) 145 cliCtx := context.NewCLIContext().WithCodec(cdc) 146 147 deployer := cliCtx.GetFromAddress() 148 149 contract := args[0] 150 if err := types.ValidateNonZeroAddress(contract); err != nil { 151 return fmt.Errorf("invalid contract hex address %w", err) 152 } 153 154 withdraw := args[1] 155 if _, err := sdk.AccAddressFromBech32(withdraw); err != nil { 156 return fmt.Errorf("invalid withdraw bech32 address %w", err) 157 } 158 159 msg := &types.MsgUpdateFeeSplit{ 160 ContractAddress: contract, 161 DeployerAddress: deployer.String(), 162 WithdrawerAddress: withdraw, 163 } 164 165 if err := msg.ValidateBasic(); err != nil { 166 return err 167 } 168 169 return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) 170 }, 171 } 172 173 return cmd 174 } 175 176 // GetCmdFeeSplitSharesProposal implements a command handler for submitting a fee split change proposal transaction 177 func GetCmdFeeSplitSharesProposal(cdcP *codec.CodecProxy, reg interfacetypes.InterfaceRegistry) *cobra.Command { 178 cmd := &cobra.Command{ 179 Use: "fee-split-shares [proposal-file]", 180 Args: cobra.ExactArgs(1), 181 Short: "Submit a fee split shares proposal", 182 Long: strings.TrimSpace( 183 fmt.Sprintf(`Submit a fee split shares proposal along with an initial deposit. 184 The proposal details must be supplied via a JSON file. 185 186 Example: 187 $ %s tx gov submit-proposal fee-split-shares <path/to/proposal.json> --from=<key_or_address> 188 189 Where proposal.json contains: 190 191 { 192 "title": "Update the fee split shares for contract", 193 "description": "Update the fee split shares", 194 "shares": [ 195 { 196 "contract_addr": "0x0d021d10ab9E155Fc1e8705d12b73f9bd3de0a36", 197 "share": "0.5" 198 } 199 ], 200 "deposit": [ 201 { 202 "denom": "%s", 203 "amount": "10000" 204 } 205 ] 206 } 207 `, 208 version.ClientName, sdk.DefaultBondDenom, 209 ), 210 ), 211 RunE: func(cmd *cobra.Command, args []string) error { 212 cdc := cdcP.GetCdc() 213 inBuf := bufio.NewReader(cmd.InOrStdin()) 214 txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) 215 cliCtx := context.NewCLIContext().WithCodec(cdc) 216 217 proposal, err := fsutils.ParseFeeSplitSharesProposalJSON(cdc, args[0]) 218 if err != nil { 219 return err 220 } 221 222 from := cliCtx.GetFromAddress() 223 content := types.NewFeeSplitSharesProposal( 224 proposal.Title, 225 proposal.Description, 226 proposal.Shares, 227 ) 228 229 msg := govTypes.NewMsgSubmitProposal(content, proposal.Deposit, from) 230 if err := msg.ValidateBasic(); err != nil { 231 return err 232 } 233 234 return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}) 235 }, 236 } 237 238 return cmd 239 }