Skip to content

Commit

Permalink
Add cli commands for the coinswap module. (#4719)
Browse files Browse the repository at this point in the history
* Added query.go that includes the cli commands for querying.

* Added transaction subcommands such as add and remove liquidity.

* Added tx command for swap order message type.

* Added REST API commands for transaction sub commands specific to the coinswap module.

* Added REST API commands for the query sub commands. Also added a struct type for query params in querier.go. Incorporated review comment of querying liquidity with a param. Fixed some code problems in tx.go..

* Removed some lines of code that were commented.

* Update x/coinswap/client/cli/tx.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Update x/coinswap/client/cli/tx.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Update x/coinswap/internal/types/querier.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Incorporating Colin's and Fede's review comments.

* Update x/coinswap/client/rest/query.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Update x/coinswap/client/rest/query.go

Co-Authored-By: colin axner <colinaxner@berkeley.edu>

* Incorporating Fede and Colin's review comments.

* Address Colin's comments.

* Addressing comments on handling time.parse errors.

* Addressed review comments about flags and splitting swap order into buy and sell order.

* Addressed Colin's comments.

* Addressing comment of removing req.Sender.
  • Loading branch information
aayushijain23 authored and fedekunze committed Sep 9, 2019
1 parent cf88b4f commit 265f431
Show file tree
Hide file tree
Showing 7 changed files with 630 additions and 0 deletions.
111 changes: 111 additions & 0 deletions x/coinswap/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package cli

import (
"fmt"
"strings"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/coinswap/internal/types"
)

const (
nativeDenom = "atom"
)

// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
coinswapQueryCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the coinswap module",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}
coinswapQueryCmd.AddCommand(client.GetCommands(
GetCmdQueryLiquidity(queryRoute, cdc),
GetCmdQueryParams(queryRoute, cdc))...)

return coinswapQueryCmd
}

// GetCmdQueryLiquidity implements the liquidity query command
func GetCmdQueryLiquidity(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "liquidity [denom]",
Short: "Query the current liquidity values",
Long: strings.TrimSpace(
fmt.Sprintf(`Query the liquidity of a specific trading pair stored in the reserve pool.
Example:
$ %s query coinswap liquidity btc
`,
version.ClientName,
),
),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)

// Added a check to ensure that input provided is not a native denom
if strings.Compare(strings.TrimSpace(args[0]), nativeDenom) == 0 {
return fmt.Errorf("%s is not a valid denom, please input a valid denom", args[0])
}

bz, err := cdc.MarshalJSON(types.NewQueryLiquidityParams(args[0]))
if err != nil {
return err
}

route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryLiquidity)
res, _, err := cliCtx.QueryWithData(route, bz)
if err != nil {
return err
}

var liquidity sdk.Coins
if err := cdc.UnmarshalJSON(res, &liquidity); err != nil {
return err
}
return cliCtx.PrintOutput(liquidity)
},
}
}

// GetCmdQueryParams implements the params query command
func GetCmdQueryParams(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "params",
Short: "Query the parameters involved in the coinswap process",
Long: strings.TrimSpace(
fmt.Sprintf(`Query all the parameters for the coinswap process.
Example:
$ %s query coinswap params
`,
version.ClientName,
),
),
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)

route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryParameters)
bz, _, err := cliCtx.QueryWithData(route, nil)
if err != nil {
return err
}

var params types.Params
if err := cdc.UnmarshalJSON(bz, &params); err != nil {
return err
}
return cliCtx.PrintOutput(params)
},
}
}
278 changes: 278 additions & 0 deletions x/coinswap/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package cli

import (
"fmt"
"strings"
"time"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/client/utils"
"github.com/cosmos/cosmos-sdk/x/coinswap/internal/types"
)

// Liquidity flags
const (
MinReward = "min-reward"
MinNative = "min-native"
Deadline = "deadline"
Recipient = "recipient"
)

// GetTxCmd returns the transaction commands for this module
func GetTxCmd(storeKey string, cdc *codec.Codec) *cobra.Command {
coinswapTxCmd := &cobra.Command{
Use: types.ModuleName,
Short: "Coinswap transaction subcommands",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

coinswapTxCmd.AddCommand(client.PostCommands(
GetCmdAddLiquidity(cdc),
GetCmdRemoveLiquidity(cdc),
GetCmdBuyOrder(cdc),
GetCmdSellOrder(cdc))...)

return coinswapTxCmd
}

// GetCmdAddLiquidity implements the add liquidity command handler
func GetCmdAddLiquidity(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "add-liquidity [deposit-coin] [deposit]",
Args: cobra.ExactArgs(2),
Short: "Add liquidity to the reserve pool",
Long: strings.TrimSpace(
fmt.Sprintf(`Add liquidity to the reserve pool for a trading pair.
Example:
$ %s tx coinswap add-liquidity dai 1000atom --min-reward 100 --deadline 2h --from mykey
`,
version.ClientName,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)

depositCoin, err := sdk.ParseCoin(args[0])
if err != nil {
return err
}

deposit, err := sdk.ParseCoin(args[1])
if err != nil {
return err
}

minRewardArg := viper.GetString(MinReward)
minReward, err := sdk.ParseCoin(minRewardArg)
if err != nil {
return err
}

durationArg := viper.GetString(Deadline)
duration, err := time.ParseDuration(durationArg)
if err != nil {
return fmt.Errorf("failed to parse the duration : %s", err)
}
deadline := time.Now().Add(duration).UTC()

senderAddr := cliCtx.GetFromAddress()

msg := types.NewMsgAddLiquidity(depositCoin, deposit.Amount, minReward.Amount, deadline, senderAddr)
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cmd.Flags().String(MinReward, "", "minimum amount of vouchers the sender is willing to accept for deposited coins (required)")
cmd.Flags().String(Deadline, "1h", "duration for which the transaction is valid (required)")

cmd.MarkFlagRequired(MinReward)
cmd.MarkFlagRequired(Deadline)

return cmd
}

// GetCmdRemoveLiquidity implements the remove liquidity command handler
func GetCmdRemoveLiquidity(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "remove-liquidity [withdraw-coin] [pool-tokens]",
Args: cobra.ExactArgs(2),
Short: "Remove liquidity from the reserve pool",
Long: strings.TrimSpace(
fmt.Sprintf(`Remove liquidity from the reserve pool for a trading pair.
Example:
$ %s tx coinswap remove-liquidity dai 1000atom --min-native 100atom --deadline 2h --from mykey
`,
version.ClientName,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)

withdrawCoin, err := sdk.ParseCoin(args[0])
if err != nil {
return err
}

poolTokens, ok := sdk.NewIntFromString(args[1])
if !ok {
return fmt.Errorf("pool-tokens %s is not a valid int, please input valid pool-tokens", args[1])
}

minNativeArg := viper.GetString(MinNative)
minNative, err := sdk.ParseCoin(minNativeArg)
if err != nil {
return err
}

durationArg := viper.GetString(Deadline)
duration, err := time.ParseDuration(durationArg)
if err != nil {
return fmt.Errorf("failed to parse the duration : %s", err)
}
deadline := time.Now().Add(duration).UTC()

senderAddr := cliCtx.GetFromAddress()

msg := types.NewMsgRemoveLiquidity(withdrawCoin, poolTokens, minNative.Amount, deadline, senderAddr)
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cmd.Flags().String(MinNative, "", "minimum amount of the native asset the sender is willing to accept (required)")
cmd.Flags().String(Deadline, "1h", "duration for which the transaction is valid (required)")

cmd.MarkFlagRequired(MinNative)
cmd.MarkFlagRequired(Deadline)

return cmd
}

// GetCmdBuyOrder implements the buy order command handler
func GetCmdBuyOrder(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "buy-order [input] [output]",
Args: cobra.ExactArgs(2),
Short: "Buy order",
Long: strings.TrimSpace(
fmt.Sprintf(`Buy order for a trading pair.
Example:
$ %s tx coinswap buy-order 5atom 2eth --deadline 2h --recipient recipientAddr --from mykey
`,
version.ClientName,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)

input, err := sdk.ParseCoin(args[0])
if err != nil {
return err
}

output, err := sdk.ParseCoin(args[1])
if err != nil {
return err
}

durationArg := viper.GetString(Deadline)
duration, err := time.ParseDuration(durationArg)
if err != nil {
return fmt.Errorf("failed to parse the duration : %s", err)
}
deadline := time.Now().Add(duration).UTC()

senderAddr := cliCtx.GetFromAddress()

recipientAddrArg := viper.GetString(Recipient)
recipientAddr, err := sdk.AccAddressFromBech32(recipientAddrArg)
if err != nil {
return err
}

msg := types.NewMsgSwapOrder(input, output, deadline, senderAddr, recipientAddr, true)
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cmd.Flags().String(Recipient, "", "recipient's address (required)")
cmd.Flags().String(Deadline, "1h", "duration for which the transaction is valid (required)")

cmd.MarkFlagRequired(Recipient)
cmd.MarkFlagRequired(Deadline)

return cmd
}

// GetCmdSellOrder implements the sell order command handler
func GetCmdSellOrder(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "sell-order [input] [output]",
Args: cobra.ExactArgs(2),
Short: "Sell order",
Long: strings.TrimSpace(
fmt.Sprintf(`Sell order for a trading pair.
Example:
$ %s tx coinswap sell-order 2eth 5atom --deadline 2h --recipient recipientAddr --from mykey
`,
version.ClientName,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(auth.DefaultTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)

input, err := sdk.ParseCoin(args[0])
if err != nil {
return err
}

output, err := sdk.ParseCoin(args[1])
if err != nil {
return err
}

durationArg := viper.GetString(Deadline)
duration, err := time.ParseDuration(durationArg)
if err != nil {
return fmt.Errorf("failed to parse the duration : %s", err)
}
deadline := time.Now().Add(duration).UTC()

senderAddr := cliCtx.GetFromAddress()

recipientAddrArg := viper.GetString(Recipient)
recipientAddr, err := sdk.AccAddressFromBech32(recipientAddrArg)
if err != nil {
return err
}

msg := types.NewMsgSwapOrder(input, output, deadline, senderAddr, recipientAddr, false)
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}

cmd.Flags().String(Recipient, "", "recipient's address (required)")
cmd.Flags().String(Deadline, "1h", "duration for which the transaction is valid (required)")

cmd.MarkFlagRequired(Recipient)
cmd.MarkFlagRequired(Deadline)

return cmd
}
Loading

0 comments on commit 265f431

Please sign in to comment.