github.com/Finschia/finschia-sdk@v0.49.1/x/fswap/client/cli/tx.go (about) 1 package cli 2 3 import ( 4 "encoding/json" 5 "fmt" 6 7 "github.com/spf13/cobra" 8 9 "github.com/Finschia/finschia-sdk/client" 10 "github.com/Finschia/finschia-sdk/client/flags" 11 "github.com/Finschia/finschia-sdk/client/tx" 12 sdk "github.com/Finschia/finschia-sdk/types" 13 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 14 bank "github.com/Finschia/finschia-sdk/x/bank/types" 15 "github.com/Finschia/finschia-sdk/x/fswap/types" 16 ) 17 18 const ( 19 FlagFromDenom = "from-denom" 20 FlagToDenom = "to-denom" 21 FlagAmountCapForToDenom = "to-coin-amount-cap" 22 FlagSwapRate = "swap-rate" 23 ) 24 25 // GetTxCmd returns the transaction commands for this module 26 func GetTxCmd() *cobra.Command { 27 cmd := &cobra.Command{ 28 Use: types.ModuleName, 29 Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), 30 DisableFlagParsing: true, 31 SuggestionsMinimumDistance: 2, 32 RunE: client.ValidateCmd, 33 } 34 cmd.AddCommand( 35 CmdTxMsgSwap(), 36 CmdTxMsgSwapAll(), 37 CmdMsgSetSwap(), 38 ) 39 40 return cmd 41 } 42 43 func CmdTxMsgSwap() *cobra.Command { 44 cmd := &cobra.Command{ 45 Use: "swap [from] [from_coin_amount] [to_denom]", 46 Short: "swap amount of from-coin to to-coin", 47 Args: cobra.ExactArgs(3), 48 RunE: func(cmd *cobra.Command, args []string) error { 49 from := args[0] 50 if err := cmd.Flags().Set(flags.FlagFrom, from); err != nil { 51 return err 52 } 53 54 clientCtx, err := client.GetClientTxContext(cmd) 55 if err != nil { 56 return err 57 } 58 59 amount, err := sdk.ParseCoinNormalized(args[1]) 60 if err != nil { 61 return err 62 } 63 64 toDenom := args[2] 65 66 msg := &types.MsgSwap{ 67 FromAddress: from, 68 FromCoinAmount: amount, 69 ToDenom: toDenom, 70 } 71 if err := msg.ValidateBasic(); err != nil { 72 return err 73 } 74 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 75 }, 76 } 77 78 flags.AddTxFlagsToCmd(cmd) 79 return cmd 80 } 81 82 func CmdTxMsgSwapAll() *cobra.Command { 83 cmd := &cobra.Command{ 84 Use: "swap-all [from_address] [from_denom] [to_denom]", 85 Short: "swap all the from-coin to to-coin", 86 Args: cobra.ExactArgs(3), 87 RunE: func(cmd *cobra.Command, args []string) error { 88 from := args[0] 89 if err := cmd.Flags().Set(flags.FlagFrom, from); err != nil { 90 return err 91 } 92 93 clientCtx, err := client.GetClientTxContext(cmd) 94 if err != nil { 95 return err 96 } 97 98 fromDenom := args[1] 99 toDenom := args[2] 100 msg := &types.MsgSwapAll{ 101 FromAddress: clientCtx.GetFromAddress().String(), 102 FromDenom: fromDenom, 103 ToDenom: toDenom, 104 } 105 if err := msg.ValidateBasic(); err != nil { 106 return err 107 } 108 109 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 110 }, 111 } 112 113 flags.AddTxFlagsToCmd(cmd) 114 return cmd 115 } 116 117 // CmdMsgSetSwap implements a command handler for submitting a swap init proposal transaction. 118 func CmdMsgSetSwap() *cobra.Command { 119 cmd := &cobra.Command{ 120 Use: "set-swap [authority] [metadata-json]", 121 Args: cobra.ExactArgs(2), 122 Short: "Set a swap", 123 Long: ` 124 Parameters: 125 metadata-json: messages in json format that will be executed if the proposal is accepted. 126 127 Example of the content of metadata-json: 128 129 { 130 "metadata": { 131 "description": "example of to-denom is finschia cony", 132 "denom_units": [ 133 { 134 "denom": "cony", 135 "exponent": 0, 136 "aliases": [ 137 "microfinschia" 138 ] 139 }, 140 { 141 "denom": "finschia", 142 "exponent": 6, 143 "aliases": [] 144 } 145 ], 146 "base": "cony", 147 "display": "finschia", 148 "name": "FINSCHIA", 149 "symbol": "FNSA" 150 } 151 } 152 `, 153 RunE: func(cmd *cobra.Command, args []string) error { 154 if err := validateGenerateOnly(cmd); err != nil { 155 return err 156 } 157 158 clientCtx, err := client.GetClientTxContext(cmd) 159 if err != nil { 160 return err 161 } 162 163 fromDenom, err := cmd.Flags().GetString(FlagFromDenom) 164 if err != nil { 165 return err 166 } 167 168 toDenom, err := cmd.Flags().GetString(FlagToDenom) 169 if err != nil { 170 return err 171 } 172 173 amountCapStr, err := cmd.Flags().GetString(FlagAmountCapForToDenom) 174 if err != nil { 175 return err 176 } 177 178 amountCap, ok := sdk.NewIntFromString(amountCapStr) 179 if !ok { 180 return sdkerrors.ErrInvalidRequest.Wrapf("failed to parse %s %s", FlagAmountCapForToDenom, amountCap.String()) 181 } 182 183 swapRate, err := cmd.Flags().GetString(FlagSwapRate) 184 if err != nil { 185 return err 186 } 187 swapRateDec, err := sdk.NewDecFromStr(swapRate) 188 if err != nil { 189 return err 190 } 191 swap := types.Swap{ 192 FromDenom: fromDenom, 193 ToDenom: toDenom, 194 AmountCapForToDenom: amountCap, 195 SwapRate: swapRateDec, 196 } 197 198 authority := args[0] 199 toDenomMetadata, err := parseToDenomMetadata(args[1]) 200 if err != nil { 201 return err 202 } 203 204 msg := types.MsgSetSwap{ 205 Authority: authority, 206 Swap: swap, 207 ToDenomMetadata: toDenomMetadata, 208 } 209 210 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg) 211 }, 212 } 213 214 cmd.Flags().String(FlagFromDenom, "", "set fromDenom string, ex) cony") 215 cmd.Flags().String(FlagToDenom, "", "set toDenom string, ex) peb") 216 cmd.Flags().String(FlagAmountCapForToDenom, "0", "set integer value for limit cap for the amount to swap to to-denom, ex 1000000000") 217 cmd.Flags().String(FlagSwapRate, "0", "set swap rate for swap from fromDenom to toDenom, ex(rate for cony to peb) 148079656000000") 218 219 flags.AddTxFlagsToCmd(cmd) 220 return cmd 221 } 222 223 func validateGenerateOnly(cmd *cobra.Command) error { 224 generateOnly, err := cmd.Flags().GetBool(flags.FlagGenerateOnly) 225 if err != nil { 226 return err 227 } 228 if !generateOnly { 229 return fmt.Errorf("you must use it with the flag --%s", flags.FlagGenerateOnly) 230 } 231 return nil 232 } 233 234 func parseToDenomMetadata(jsonDenomMetadata string) (bank.Metadata, error) { 235 type toDenomMeta struct { 236 Metadata bank.Metadata `json:"metadata"` 237 } 238 denomMeta := toDenomMeta{} 239 if err := json.Unmarshal([]byte(jsonDenomMetadata), &denomMeta); err != nil { 240 return bank.Metadata{}, err 241 } 242 243 if err := denomMeta.Metadata.Validate(); err != nil { 244 return bank.Metadata{}, err 245 } 246 247 return denomMeta.Metadata, nil 248 }