Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cli commands for the coinswap module. #4719

Merged
merged 19 commits into from
Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a42b045
Added query.go that includes the cli commands for querying.
aayushijain23 Jul 12, 2019
6af249b
Added transaction subcommands such as add and remove liquidity.
aayushijain23 Jul 18, 2019
7aa6998
Added tx command for swap order message type.
aayushijain23 Jul 22, 2019
f9b248e
Added REST API commands for transaction sub commands specific to the …
aayushijain23 Jul 22, 2019
39306cb
Added REST API commands for the query sub commands. Also added a stru…
aayushijain23 Jul 23, 2019
7445656
Removed some lines of code that were commented.
aayushijain23 Jul 30, 2019
920166e
Update x/coinswap/client/cli/tx.go
aayushijain23 Jul 31, 2019
405f7d8
Update x/coinswap/client/cli/tx.go
aayushijain23 Jul 31, 2019
31038a7
Update x/coinswap/internal/types/querier.go
aayushijain23 Aug 1, 2019
0c9fef3
Incorporating Colin's and Fede's review comments.
aayushijain23 Aug 1, 2019
438d219
Update x/coinswap/client/rest/query.go
aayushijain23 Aug 2, 2019
f9f3b0b
Update x/coinswap/client/rest/query.go
aayushijain23 Aug 2, 2019
03d4687
Incorporating Fede and Colin's review comments.
aayushijain23 Aug 2, 2019
de2a089
Address Colin's comments.
aayushijain23 Aug 8, 2019
81856e8
Addressing comments on handling time.parse errors.
aayushijain23 Aug 8, 2019
5f2af25
Addressed review comments about flags and splitting swap order into b…
aayushijain23 Aug 8, 2019
f8532d0
Addressed Colin's comments.
aayushijain23 Aug 9, 2019
8f1ccfb
Merge branch 'colin/4443-coinswap' of github.com:cosmos/cosmos-sdk in…
aayushijain23 Aug 9, 2019
fb30336
Addressing comment of removing req.Sender.
aayushijain23 Aug 9, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be configurable

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is in the core code; its a parameter. The issue on the client is its useful to know what the native denom is but it is inefficient to do an extra query for it for every command especially since it doesn't change after genesis. One way of handling this is through a config file, which could be done at a later point

)

// 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 {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
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 {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
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)
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
},
}
}
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 {
colin-axner marked this conversation as resolved.
Show resolved Hide resolved
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