github.com/KiraCore/sekai@v0.3.43/x/basket/client/cli/tx.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/KiraCore/sekai/x/basket/types" 9 govcli "github.com/KiraCore/sekai/x/gov/client/cli" 10 govtypes "github.com/KiraCore/sekai/x/gov/types" 11 "github.com/cosmos/cosmos-sdk/client" 12 "github.com/cosmos/cosmos-sdk/client/flags" 13 "github.com/cosmos/cosmos-sdk/client/tx" 14 sdk "github.com/cosmos/cosmos-sdk/types" 15 "github.com/spf13/cobra" 16 ) 17 18 // flags for basket module txs 19 const ( 20 FlagBasketId = "basket-id" 21 FlagBasketSuffix = "basket-suffix" 22 FlagBasketDescription = "basket-description" 23 FlagSwapFee = "swap-fee" 24 FlagSlippageFeeMin = "slippage-fee-min" 25 FlagTokensCap = "tokens-cap" 26 FlagLimitsPeriod = "limits-period" 27 FlagMintsMin = "mints-min" 28 FlagMintsMax = "mints-max" 29 FlagMintsDisabled = "mints-disabled" 30 FlagBurnsMin = "burns-min" 31 FlagBurnsMax = "burns-max" 32 FlagBurnsDisabled = "burns-disabled" 33 FlagSwapsMin = "swaps-min" 34 FlagSwapsMax = "swaps-max" 35 FlagSwapsDisabled = "swaps-disabled" 36 FlagBasketTokens = "basket-tokens" 37 ) 38 39 // NewTxCmd returns a root CLI command handler for all x/bank transaction commands. 40 func NewTxCmd() *cobra.Command { 41 txCmd := &cobra.Command{ 42 Use: types.ModuleName, 43 Short: "Tokens sub commands", 44 DisableFlagParsing: true, 45 SuggestionsMinimumDistance: 2, 46 RunE: client.ValidateCmd, 47 } 48 49 txCmd.AddCommand( 50 GetTxDisableBasketDepositsCmd(), 51 GetTxDisableBasketWithdrawsCmd(), 52 GetTxDisableBasketSwapsCmd(), 53 GetTxBasketTokenMintCmd(), 54 GetTxBasketTokenBurnCmd(), 55 GetTxBasketTokenSwapCmd(), 56 GetTxBasketClaimRewardsCmd(), 57 GetTxProposalCreateBasketCmd(), 58 GetTxProposalEditBasketCmd(), 59 GetTxProposalBasketWithdrawSurplusCmd(), 60 ) 61 62 return txCmd 63 } 64 65 // GetTxDisableBasketDepositsCmd implement cli command for MsgDisableBasketDeposits 66 func GetTxDisableBasketDepositsCmd() *cobra.Command { 67 cmd := &cobra.Command{ 68 Use: "disable-basket-deposits [basket_id] [disabled]", 69 Short: "Emergency function & permission to disable one or all deposits of one or all token in the basket", 70 Args: cobra.MinimumNArgs(2), 71 RunE: func(cmd *cobra.Command, args []string) error { 72 clientCtx, err := client.GetClientTxContext(cmd) 73 if err != nil { 74 return err 75 } 76 77 basketId, err := strconv.Atoi(args[0]) 78 if err != nil { 79 return err 80 } 81 82 disabled, err := strconv.ParseBool(args[1]) 83 if err != nil { 84 return err 85 } 86 87 msg := types.NewMsgDisableBasketDeposits( 88 clientCtx.FromAddress, 89 uint64(basketId), 90 disabled, 91 ) 92 93 err = msg.ValidateBasic() 94 if err != nil { 95 return err 96 } 97 98 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 99 }, 100 } 101 102 flags.AddTxFlagsToCmd(cmd) 103 _ = cmd.MarkFlagRequired(flags.FlagFrom) 104 105 return cmd 106 } 107 108 // GetTxDisableBasketWithdrawsCmd implement cli command for MsgDisableBasketWithdraws 109 func GetTxDisableBasketWithdrawsCmd() *cobra.Command { 110 cmd := &cobra.Command{ 111 Use: "disable-basket-withdraws [basket_id] [disabled]", 112 Short: "Emergency function & permission to disable one or all withdraws of one or all token in the basket", 113 Args: cobra.MinimumNArgs(2), 114 RunE: func(cmd *cobra.Command, args []string) error { 115 clientCtx, err := client.GetClientTxContext(cmd) 116 if err != nil { 117 return err 118 } 119 120 basketId, err := strconv.Atoi(args[0]) 121 if err != nil { 122 return err 123 } 124 125 disabled, err := strconv.ParseBool(args[1]) 126 if err != nil { 127 return err 128 } 129 130 msg := types.NewMsgDisableBasketWithdraws( 131 clientCtx.FromAddress, 132 uint64(basketId), 133 disabled, 134 ) 135 136 err = msg.ValidateBasic() 137 if err != nil { 138 return err 139 } 140 141 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 142 }, 143 } 144 145 flags.AddTxFlagsToCmd(cmd) 146 _ = cmd.MarkFlagRequired(flags.FlagFrom) 147 148 return cmd 149 } 150 151 // GetTxDisableBasketSwapsCmd implement cli command for MsgDisableBasketSwaps 152 func GetTxDisableBasketSwapsCmd() *cobra.Command { 153 cmd := &cobra.Command{ 154 Use: "disable-basket-swaps [basket_id] [disabled]", 155 Short: "Emergency function & permission to disable one or all swaps of one or all token in the basket", 156 Args: cobra.MinimumNArgs(2), 157 RunE: func(cmd *cobra.Command, args []string) error { 158 clientCtx, err := client.GetClientTxContext(cmd) 159 if err != nil { 160 return err 161 } 162 163 basketId, err := strconv.Atoi(args[0]) 164 if err != nil { 165 return err 166 } 167 168 disabled, err := strconv.ParseBool(args[1]) 169 if err != nil { 170 return err 171 } 172 173 msg := types.NewMsgDisableBasketSwaps( 174 clientCtx.FromAddress, 175 uint64(basketId), 176 disabled, 177 ) 178 179 err = msg.ValidateBasic() 180 if err != nil { 181 return err 182 } 183 184 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 185 }, 186 } 187 188 flags.AddTxFlagsToCmd(cmd) 189 _ = cmd.MarkFlagRequired(flags.FlagFrom) 190 191 return cmd 192 } 193 194 // GetTxBasketTokenMintCmd implement cli command for MsgBasketTokenMint 195 func GetTxBasketTokenMintCmd() *cobra.Command { 196 cmd := &cobra.Command{ 197 Use: "mint-basket-tokens [basket_id] [deposit_coins]", 198 Short: "mint basket tokens", 199 Args: cobra.MinimumNArgs(2), 200 RunE: func(cmd *cobra.Command, args []string) error { 201 clientCtx, err := client.GetClientTxContext(cmd) 202 if err != nil { 203 return err 204 } 205 206 basketId, err := strconv.Atoi(args[0]) 207 if err != nil { 208 return err 209 } 210 211 coins, err := sdk.ParseCoinsNormalized(args[1]) 212 if err != nil { 213 return err 214 } 215 216 msg := types.NewMsgBasketTokenMint( 217 clientCtx.FromAddress, 218 uint64(basketId), 219 coins, 220 ) 221 222 err = msg.ValidateBasic() 223 if err != nil { 224 return err 225 } 226 227 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 228 }, 229 } 230 231 flags.AddTxFlagsToCmd(cmd) 232 _ = cmd.MarkFlagRequired(flags.FlagFrom) 233 234 return cmd 235 } 236 237 // GetTxBasketTokenBurnCmd implement cli command for MsgBasketTokenBurn 238 func GetTxBasketTokenBurnCmd() *cobra.Command { 239 cmd := &cobra.Command{ 240 Use: "burn-basket-tokens [basket_id] [burn_coin]", 241 Short: "burn basket tokens", 242 Args: cobra.MinimumNArgs(2), 243 RunE: func(cmd *cobra.Command, args []string) error { 244 clientCtx, err := client.GetClientTxContext(cmd) 245 if err != nil { 246 return err 247 } 248 249 basketId, err := strconv.Atoi(args[0]) 250 if err != nil { 251 return err 252 } 253 254 coin, err := sdk.ParseCoinNormalized(args[1]) 255 if err != nil { 256 return err 257 } 258 259 msg := types.NewMsgBasketTokenBurn( 260 clientCtx.FromAddress, 261 uint64(basketId), 262 coin, 263 ) 264 265 err = msg.ValidateBasic() 266 if err != nil { 267 return err 268 } 269 270 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 271 }, 272 } 273 274 flags.AddTxFlagsToCmd(cmd) 275 _ = cmd.MarkFlagRequired(flags.FlagFrom) 276 277 return cmd 278 } 279 280 // GetTxBasketTokenSwapCmd implement cli command for MsgBasketTokenSwap 281 func GetTxBasketTokenSwapCmd() *cobra.Command { 282 cmd := &cobra.Command{ 283 Use: "swap-basket-tokens [basket_id] [in_amount1] [out_token1] [in_amount2] [out_token2] ...", 284 Short: "swap one or many of the basket tokens for one or many others", 285 Args: cobra.MinimumNArgs(3), 286 RunE: func(cmd *cobra.Command, args []string) error { 287 clientCtx, err := client.GetClientTxContext(cmd) 288 289 basketId, err := strconv.Atoi(args[0]) 290 if err != nil { 291 return err 292 } 293 294 pairs := []types.SwapPair{} 295 for i := 1; i < len(args); i += 2 { 296 coin, err := sdk.ParseCoinNormalized(args[i]) 297 if err != nil { 298 return err 299 } 300 if i+1 == len(args) { 301 return fmt.Errorf("out token not set for %s", args[i]) 302 } 303 pairs = append(pairs, types.SwapPair{ 304 InAmount: coin, 305 OutToken: args[i+1], 306 }) 307 } 308 309 msg := types.NewMsgBasketTokenSwap( 310 clientCtx.FromAddress, 311 uint64(basketId), 312 pairs, 313 ) 314 err = msg.ValidateBasic() 315 if err != nil { 316 return err 317 } 318 319 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 320 }, 321 } 322 323 flags.AddTxFlagsToCmd(cmd) 324 _ = cmd.MarkFlagRequired(flags.FlagFrom) 325 326 return cmd 327 } 328 329 // GetTxBasketClaimRewardsCmd implement cli command for MsgBasketClaimRewards 330 func GetTxBasketClaimRewardsCmd() *cobra.Command { 331 cmd := &cobra.Command{ 332 Use: "basket-claim-rewards [basket_tokens]", 333 Short: "force staking derivative `SDB` basket to claim outstanding rewards of one all or many aggregate `V<ID>` tokens", 334 RunE: func(cmd *cobra.Command, args []string) error { 335 clientCtx, err := client.GetClientTxContext(cmd) 336 if err != nil { 337 return err 338 } 339 340 basketTokens, err := sdk.ParseCoinsNormalized(args[0]) 341 if err != nil { 342 return err 343 } 344 345 msg := types.NewMsgBasketClaimRewards( 346 clientCtx.FromAddress, 347 basketTokens, 348 ) 349 350 err = msg.ValidateBasic() 351 if err != nil { 352 return err 353 } 354 355 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 356 }, 357 } 358 359 flags.AddTxFlagsToCmd(cmd) 360 _ = cmd.MarkFlagRequired(flags.FlagFrom) 361 362 return cmd 363 } 364 365 // GetTxProposalCreateBasketCmd implement cli command for ProposalCreateBasket 366 func GetTxProposalCreateBasketCmd() *cobra.Command { 367 cmd := &cobra.Command{ 368 Use: "proposal-create-basket", 369 Short: "Create a proposal to create a basket", 370 Args: cobra.ExactArgs(0), 371 RunE: func(cmd *cobra.Command, args []string) error { 372 clientCtx, err := client.GetClientTxContext(cmd) 373 if err != nil { 374 return err 375 } 376 title, err := cmd.Flags().GetString(govcli.FlagTitle) 377 if err != nil { 378 return fmt.Errorf("invalid title: %w", err) 379 } 380 description, err := cmd.Flags().GetString(govcli.FlagDescription) 381 if err != nil { 382 return fmt.Errorf("invalid description: %w", err) 383 } 384 385 suffix, err := cmd.Flags().GetString(FlagBasketSuffix) 386 if err != nil { 387 return fmt.Errorf("invalid basket suffix: %w", err) 388 } 389 390 basketDescription, err := cmd.Flags().GetString(FlagBasketDescription) 391 if err != nil { 392 return fmt.Errorf("invalid basket description: %w", err) 393 } 394 395 swapFeeStr, err := cmd.Flags().GetString(FlagSwapFee) 396 if err != nil { 397 return fmt.Errorf("invalid basket swap fee: %w", err) 398 } 399 400 swapFee, err := sdk.NewDecFromStr(swapFeeStr) 401 if err != nil { 402 return fmt.Errorf("invalid basket swap fee: %w", err) 403 } 404 405 slippageFeeMinStr, err := cmd.Flags().GetString(FlagSlippageFeeMin) 406 if err != nil { 407 return fmt.Errorf("invalid basket slippage fee min: %w", err) 408 } 409 410 slipppageFeeMin, err := sdk.NewDecFromStr(slippageFeeMinStr) 411 if err != nil { 412 return fmt.Errorf("invalid basket slippage fee min: %w", err) 413 } 414 415 tokensCapStr, err := cmd.Flags().GetString(FlagTokensCap) 416 if err != nil { 417 return fmt.Errorf("invalid basket tokens cap: %w", err) 418 } 419 420 tokensCap, err := sdk.NewDecFromStr(tokensCapStr) 421 if err != nil { 422 return fmt.Errorf("invalid basket tokens cap: %w", err) 423 } 424 425 limitsPeriod, err := cmd.Flags().GetUint64(FlagLimitsPeriod) 426 if err != nil { 427 return fmt.Errorf("invalid basket limits cap: %w", err) 428 } 429 430 mintsMinStr, err := cmd.Flags().GetString(FlagMintsMin) 431 if err != nil { 432 return fmt.Errorf("invalid basket minimum mints: %w", err) 433 } 434 435 mintsMin, ok := sdk.NewIntFromString(mintsMinStr) 436 if !ok { 437 return fmt.Errorf("invalid basket minimum mints: %s", mintsMinStr) 438 } 439 440 mintsMaxStr, err := cmd.Flags().GetString(FlagMintsMax) 441 if err != nil { 442 return fmt.Errorf("invalid basket maximum mints: %w", err) 443 } 444 445 mintsMax, ok := sdk.NewIntFromString(mintsMaxStr) 446 if !ok { 447 return fmt.Errorf("invalid basket maximum mints: %s", mintsMaxStr) 448 } 449 450 mintsDisabled, err := cmd.Flags().GetBool(FlagMintsDisabled) 451 if err != nil { 452 return fmt.Errorf("invalid basket mints disabled flag: %w", err) 453 } 454 455 burnsMinStr, err := cmd.Flags().GetString(FlagBurnsMin) 456 if err != nil { 457 return fmt.Errorf("invalid basket minimum burns: %w", err) 458 } 459 460 burnsMin, ok := sdk.NewIntFromString(burnsMinStr) 461 if !ok { 462 return fmt.Errorf("invalid basket minimum burns: %s", burnsMinStr) 463 } 464 465 burnsMaxStr, err := cmd.Flags().GetString(FlagBurnsMax) 466 if err != nil { 467 return fmt.Errorf("invalid basket maximum burns: %w", err) 468 } 469 470 burnsMax, ok := sdk.NewIntFromString(burnsMaxStr) 471 if !ok { 472 return fmt.Errorf("invalid basket maximum burns: %s", burnsMaxStr) 473 } 474 475 burnsDisabled, err := cmd.Flags().GetBool(FlagBurnsDisabled) 476 if err != nil { 477 return fmt.Errorf("invalid basket burns disabled flag: %w", err) 478 } 479 480 swapsMinStr, err := cmd.Flags().GetString(FlagSwapsMin) 481 if err != nil { 482 return fmt.Errorf("invalid basket minimum swaps: %w", err) 483 } 484 485 swapsMin, ok := sdk.NewIntFromString(swapsMinStr) 486 if !ok { 487 return fmt.Errorf("invalid basket minimum mints: %s", swapsMinStr) 488 } 489 490 swapsMaxStr, err := cmd.Flags().GetString(FlagSwapsMax) 491 if err != nil { 492 return fmt.Errorf("invalid basket maximum swaps: %w", err) 493 } 494 495 swapsMax, ok := sdk.NewIntFromString(swapsMaxStr) 496 if !ok { 497 return fmt.Errorf("invalid basket maximum swaps: %s", swapsMaxStr) 498 } 499 500 swapsDisabled, err := cmd.Flags().GetBool(FlagSwapsDisabled) 501 if err != nil { 502 return fmt.Errorf("invalid basket swaps disabled flag: %w", err) 503 } 504 505 basketTokensStr, err := cmd.Flags().GetString(FlagBasketTokens) 506 if err != nil { 507 return fmt.Errorf("invalid basket tokens: %w", err) 508 } 509 510 basketTokens, err := parseBasketTokens(basketTokensStr) 511 if err != nil { 512 return err 513 } 514 515 msg, err := govtypes.NewMsgSubmitProposal( 516 clientCtx.FromAddress, 517 title, 518 description, 519 types.NewProposalCreateBasket(types.Basket{ 520 Suffix: suffix, 521 Description: basketDescription, 522 SwapFee: swapFee, 523 SlipppageFeeMin: slipppageFeeMin, 524 TokensCap: tokensCap, 525 LimitsPeriod: limitsPeriod, 526 MintsMin: mintsMin, 527 MintsMax: mintsMax, 528 MintsDisabled: mintsDisabled, 529 BurnsMin: burnsMin, 530 BurnsMax: burnsMax, 531 BurnsDisabled: burnsDisabled, 532 SwapsMin: swapsMin, 533 SwapsMax: swapsMax, 534 SwapsDisabled: swapsDisabled, 535 Tokens: basketTokens, 536 }), 537 ) 538 if err != nil { 539 return err 540 } 541 542 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 543 }, 544 } 545 546 cmd.Flags().String(govcli.FlagTitle, "", "The title of the proposal.") 547 cmd.MarkFlagRequired(govcli.FlagTitle) 548 cmd.Flags().String(govcli.FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.") 549 cmd.MarkFlagRequired(govcli.FlagDescription) 550 cmd.Flags().String(FlagBasketSuffix, "", "The suffix of the basket.") 551 cmd.Flags().String(FlagBasketDescription, "", "The description of the basket.") 552 cmd.Flags().String(FlagSwapFee, "", "Swap fee on the basket.") 553 cmd.Flags().String(FlagSlippageFeeMin, "", "Minimum slippage fee on the basket.") 554 cmd.Flags().String(FlagTokensCap, "", "Tokens cap on the basket.") 555 cmd.Flags().Uint64(FlagLimitsPeriod, 0, "Limits period on the basket.") 556 cmd.Flags().String(FlagMintsMin, "", "Min mint amount on the basket.") 557 cmd.Flags().String(FlagMintsMax, "", "Max mint amount on a day on the basket.") 558 cmd.Flags().Bool(FlagMintsDisabled, false, "Mints enabled flag on the basket.") 559 cmd.Flags().String(FlagBurnsMin, "", "Min burn amount on the basket.") 560 cmd.Flags().String(FlagBurnsMax, "", "Max burn amount on a day on the basket.") 561 cmd.Flags().Bool(FlagBurnsDisabled, false, "Burns enabled flag on the basket.") 562 cmd.Flags().String(FlagSwapsMin, "", "Min swap amount on the basket.") 563 cmd.Flags().String(FlagSwapsMax, "", "Max swap amount on a day on the basket.") 564 cmd.Flags().Bool(FlagSwapsDisabled, false, "Swap disabled flag on the basket.") 565 cmd.Flags().String(FlagBasketTokens, "", "Underlying tokens with rates on the basket.") 566 567 flags.AddTxFlagsToCmd(cmd) 568 _ = cmd.MarkFlagRequired(flags.FlagFrom) 569 570 return cmd 571 } 572 573 // GetTxProposalEditBasketCmd implement cli command for ProposalEditBasket 574 func GetTxProposalEditBasketCmd() *cobra.Command { 575 cmd := &cobra.Command{ 576 Use: "proposal-edit-basket", 577 Short: "Create a proposal to edit a basket", 578 Args: cobra.ExactArgs(0), 579 RunE: func(cmd *cobra.Command, args []string) error { 580 clientCtx, err := client.GetClientTxContext(cmd) 581 if err != nil { 582 return err 583 } 584 title, err := cmd.Flags().GetString(govcli.FlagTitle) 585 if err != nil { 586 return fmt.Errorf("invalid title: %w", err) 587 } 588 description, err := cmd.Flags().GetString(govcli.FlagDescription) 589 if err != nil { 590 return fmt.Errorf("invalid description: %w", err) 591 } 592 593 basketId, err := cmd.Flags().GetUint64(FlagBasketId) 594 if err != nil { 595 return fmt.Errorf("invalid basket id: %w", err) 596 } 597 598 suffix, err := cmd.Flags().GetString(FlagBasketSuffix) 599 if err != nil { 600 return fmt.Errorf("invalid basket suffix: %w", err) 601 } 602 603 basketDescription, err := cmd.Flags().GetString(FlagBasketDescription) 604 if err != nil { 605 return fmt.Errorf("invalid basket description: %w", err) 606 } 607 608 swapFeeStr, err := cmd.Flags().GetString(FlagSwapFee) 609 if err != nil { 610 return fmt.Errorf("invalid basket swap fee: %w", err) 611 } 612 613 swapFee, err := sdk.NewDecFromStr(swapFeeStr) 614 if err != nil { 615 return fmt.Errorf("invalid basket swap fee: %w", err) 616 } 617 618 slippageFeeMinStr, err := cmd.Flags().GetString(FlagSlippageFeeMin) 619 if err != nil { 620 return fmt.Errorf("invalid basket slippage fee min: %w", err) 621 } 622 623 slipppageFeeMin, err := sdk.NewDecFromStr(slippageFeeMinStr) 624 if err != nil { 625 return fmt.Errorf("invalid basket slippage fee min: %w", err) 626 } 627 628 tokensCapStr, err := cmd.Flags().GetString(FlagTokensCap) 629 if err != nil { 630 return fmt.Errorf("invalid basket tokens cap: %w", err) 631 } 632 633 tokensCap, err := sdk.NewDecFromStr(tokensCapStr) 634 if err != nil { 635 return fmt.Errorf("invalid basket tokens cap: %w", err) 636 } 637 638 limitsPeriod, err := cmd.Flags().GetUint64(FlagLimitsPeriod) 639 if err != nil { 640 return fmt.Errorf("invalid basket limits cap: %w", err) 641 } 642 643 mintsMinStr, err := cmd.Flags().GetString(FlagMintsMin) 644 if err != nil { 645 return fmt.Errorf("invalid basket minimum mints: %w", err) 646 } 647 648 mintsMin, ok := sdk.NewIntFromString(mintsMinStr) 649 if !ok { 650 return fmt.Errorf("invalid basket minimum mints: %s", mintsMinStr) 651 } 652 653 mintsMaxStr, err := cmd.Flags().GetString(FlagMintsMax) 654 if err != nil { 655 return fmt.Errorf("invalid basket maximum mints: %w", err) 656 } 657 658 mintsMax, ok := sdk.NewIntFromString(mintsMaxStr) 659 if !ok { 660 return fmt.Errorf("invalid basket maximum mints: %s", mintsMaxStr) 661 } 662 663 mintsDisabled, err := cmd.Flags().GetBool(FlagMintsDisabled) 664 if err != nil { 665 return fmt.Errorf("invalid basket mints disabled flag: %w", err) 666 } 667 668 burnsMinStr, err := cmd.Flags().GetString(FlagBurnsMin) 669 if err != nil { 670 return fmt.Errorf("invalid basket minimum burns: %w", err) 671 } 672 673 burnsMin, ok := sdk.NewIntFromString(burnsMinStr) 674 if !ok { 675 return fmt.Errorf("invalid basket minimum burns: %s", burnsMinStr) 676 } 677 678 burnsMaxStr, err := cmd.Flags().GetString(FlagBurnsMax) 679 if err != nil { 680 return fmt.Errorf("invalid basket maximum burns: %w", err) 681 } 682 683 burnsMax, ok := sdk.NewIntFromString(burnsMaxStr) 684 if !ok { 685 return fmt.Errorf("invalid basket maximum burns: %s", burnsMaxStr) 686 } 687 688 burnsDisabled, err := cmd.Flags().GetBool(FlagBurnsDisabled) 689 if err != nil { 690 return fmt.Errorf("invalid basket burns disabled flag: %w", err) 691 } 692 693 swapsMinStr, err := cmd.Flags().GetString(FlagSwapsMin) 694 if err != nil { 695 return fmt.Errorf("invalid basket minimum swaps: %w", err) 696 } 697 698 swapsMin, ok := sdk.NewIntFromString(swapsMinStr) 699 if !ok { 700 return fmt.Errorf("invalid basket minimum mints: %s", swapsMinStr) 701 } 702 703 swapsMaxStr, err := cmd.Flags().GetString(FlagSwapsMax) 704 if err != nil { 705 return fmt.Errorf("invalid basket maximum swaps: %w", err) 706 } 707 708 swapsMax, ok := sdk.NewIntFromString(swapsMaxStr) 709 if !ok { 710 return fmt.Errorf("invalid basket maximum swaps: %s", swapsMaxStr) 711 } 712 713 swapsDisabled, err := cmd.Flags().GetBool(FlagSwapsDisabled) 714 if err != nil { 715 return fmt.Errorf("invalid basket swaps disabled flag: %w", err) 716 } 717 718 basketTokensStr, err := cmd.Flags().GetString(FlagBasketTokens) 719 if err != nil { 720 return fmt.Errorf("invalid basket tokens: %w", err) 721 } 722 723 basketTokens, err := parseBasketTokens(basketTokensStr) 724 if err != nil { 725 return err 726 } 727 728 msg, err := govtypes.NewMsgSubmitProposal( 729 clientCtx.FromAddress, 730 title, 731 description, 732 types.NewProposalEditBasket(types.Basket{ 733 Id: basketId, 734 Suffix: suffix, 735 Description: basketDescription, 736 SwapFee: swapFee, 737 SlipppageFeeMin: slipppageFeeMin, 738 TokensCap: tokensCap, 739 LimitsPeriod: limitsPeriod, 740 MintsMin: mintsMin, 741 MintsMax: mintsMax, 742 MintsDisabled: mintsDisabled, 743 BurnsMin: burnsMin, 744 BurnsMax: burnsMax, 745 BurnsDisabled: burnsDisabled, 746 SwapsMin: swapsMin, 747 SwapsMax: swapsMax, 748 SwapsDisabled: swapsDisabled, 749 Tokens: basketTokens, 750 }), 751 ) 752 if err != nil { 753 return err 754 } 755 756 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 757 }, 758 } 759 760 cmd.Flags().String(govcli.FlagTitle, "", "The title of the proposal.") 761 cmd.MarkFlagRequired(govcli.FlagTitle) 762 cmd.Flags().String(govcli.FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.") 763 cmd.MarkFlagRequired(govcli.FlagDescription) 764 cmd.Flags().Uint64(FlagBasketId, 0, "The id of the basket.") 765 cmd.Flags().String(FlagBasketSuffix, "", "The suffix of the basket.") 766 cmd.Flags().String(FlagBasketDescription, "", "The description of the basket.") 767 cmd.Flags().String(FlagSwapFee, "", "Swap fee on the basket.") 768 cmd.Flags().String(FlagSlippageFeeMin, "", "Minimum slippage fee on the basket.") 769 cmd.Flags().String(FlagTokensCap, "", "Tokens cap on the basket.") 770 cmd.Flags().Uint64(FlagLimitsPeriod, 0, "Limits period on the basket.") 771 cmd.Flags().String(FlagMintsMin, "", "Min mint amount on the basket.") 772 cmd.Flags().String(FlagMintsMax, "", "Max mint amount on a day on the basket.") 773 cmd.Flags().Bool(FlagMintsDisabled, false, "Mints enabled flag on the basket.") 774 cmd.Flags().String(FlagBurnsMin, "", "Min burn amount on the basket.") 775 cmd.Flags().String(FlagBurnsMax, "", "Max burn amount on a day on the basket.") 776 cmd.Flags().Bool(FlagBurnsDisabled, false, "Burns enabled flag on the basket.") 777 cmd.Flags().String(FlagSwapsMin, "", "Min swap amount on the basket.") 778 cmd.Flags().String(FlagSwapsMax, "", "Max swap amount on a day on the basket.") 779 cmd.Flags().Bool(FlagSwapsDisabled, false, "Swap disabled flag on the basket.") 780 cmd.Flags().String(FlagBasketTokens, "", "Underlying tokens with rates on the basket.") 781 782 flags.AddTxFlagsToCmd(cmd) 783 _ = cmd.MarkFlagRequired(flags.FlagFrom) 784 785 return cmd 786 } 787 788 // GetTxProposalBasketWithdrawSurplusCmd implement cli command for ProposalBasketWithdrawSurplus 789 func GetTxProposalBasketWithdrawSurplusCmd() *cobra.Command { 790 cmd := &cobra.Command{ 791 Use: "proposal-basket-withdraw-surplus [basket_ids] [withdraw_target]", 792 Short: "Create a proposal to withdraw surplus from the basket", 793 Args: cobra.ExactArgs(2), 794 RunE: func(cmd *cobra.Command, args []string) error { 795 clientCtx, err := client.GetClientTxContext(cmd) 796 if err != nil { 797 return err 798 } 799 title, err := cmd.Flags().GetString(govcli.FlagTitle) 800 if err != nil { 801 return fmt.Errorf("invalid title: %w", err) 802 } 803 description, err := cmd.Flags().GetString(govcli.FlagDescription) 804 if err != nil { 805 return fmt.Errorf("invalid description: %w", err) 806 } 807 808 basketIdsArr := strings.Split(args[0], ",") 809 basketIds := []uint64{} 810 for _, basketIdStr := range basketIdsArr { 811 basketId, err := strconv.Atoi(basketIdStr) 812 if err != nil { 813 return err 814 } 815 basketIds = append(basketIds, uint64(basketId)) 816 } 817 818 msg, err := govtypes.NewMsgSubmitProposal( 819 clientCtx.FromAddress, 820 title, 821 description, 822 types.NewProposalBasketWithdrawSurplus(basketIds, args[1]), 823 ) 824 if err != nil { 825 return err 826 } 827 828 return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) 829 }, 830 } 831 832 cmd.Flags().String(govcli.FlagTitle, "", "The title of the proposal.") 833 cmd.MarkFlagRequired(govcli.FlagTitle) 834 cmd.Flags().String(govcli.FlagDescription, "", "The description of the proposal, it can be a url, some text, etc.") 835 cmd.MarkFlagRequired(govcli.FlagDescription) 836 837 flags.AddTxFlagsToCmd(cmd) 838 _ = cmd.MarkFlagRequired(flags.FlagFrom) 839 840 return cmd 841 } 842 843 func parseBasketTokens(basketTokensStr string) ([]types.BasketToken, error) { 844 basketTokens := []types.BasketToken{} 845 basketTokensArr := strings.Split(basketTokensStr, ",") 846 for _, basketTokenStr := range basketTokensArr { 847 split := strings.Split(basketTokenStr, "#") 848 if len(split) != 5 { 849 return basketTokens, fmt.Errorf("invalid basket token info: %s", basketTokenStr) 850 } 851 weight, err := sdk.NewDecFromStr(split[1]) 852 if err != nil { 853 return basketTokens, fmt.Errorf("invalid basket token weight: %w", err) 854 } 855 deposits, err := strconv.ParseBool(split[2]) 856 if err != nil { 857 return basketTokens, fmt.Errorf("invalid basket token deposits: %w", err) 858 } 859 withdraws, _ := strconv.ParseBool(split[3]) 860 if err != nil { 861 return basketTokens, fmt.Errorf("invalid basket token withdraws: %w", err) 862 } 863 swaps, _ := strconv.ParseBool(split[4]) 864 if err != nil { 865 return basketTokens, fmt.Errorf("invalid basket token swaps: %w", err) 866 } 867 basketTokens = append(basketTokens, types.BasketToken{ 868 Denom: split[0], 869 Weight: weight, 870 Deposits: deposits, 871 Withdraws: withdraws, 872 Swaps: swaps, 873 }) 874 } 875 return basketTokens, nil 876 }