-
Notifications
You must be signed in to change notification settings - Fork 608
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## What is the purpose of the change Add CLI query support for TWAP. I've eye ball-tested the values for correctness against imperator API. Ideally we add this logic to our querygen, or use proto-reflect from SDK to automate CLI boilerplate going for. ## Testing and Verifying Manually tested ## Documentation and Release Note - Does this pull request introduce a new feature or user-facing behavior changes? yes - Is a relevant changelog entry added to the `Unreleased` section in `CHANGELOG.md`? yes - How is the feature or change documented? CLI help
- Loading branch information
1 parent
d80e025
commit e3e8e27
Showing
3 changed files
with
143 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package twapcli | ||
|
||
import ( | ||
"fmt" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/client/flags" | ||
"github.com/cosmos/cosmos-sdk/version" | ||
"github.com/spf13/cobra" | ||
|
||
gammtypes "github.com/osmosis-labs/osmosis/v12/x/gamm/types" | ||
"github.com/osmosis-labs/osmosis/v12/x/twap/client/queryproto" | ||
"github.com/osmosis-labs/osmosis/v12/x/twap/types" | ||
) | ||
|
||
// GetQueryCmd returns the cli query commands for this module. | ||
func GetQueryCmd() *cobra.Command { | ||
// Group superfluid queries under a subcommand | ||
cmd := &cobra.Command{ | ||
Use: types.ModuleName, | ||
Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), | ||
DisableFlagParsing: true, | ||
SuggestionsMinimumDistance: 2, | ||
RunE: client.ValidateCmd, | ||
} | ||
|
||
cmd.AddCommand(GetQueryTwapCommand()) | ||
|
||
return cmd | ||
} | ||
|
||
// GetCmdAssetMultiplier returns multiplier of an asset by denom. | ||
func GetQueryTwapCommand() *cobra.Command { | ||
cmd := &cobra.Command{ | ||
Use: "twap [poolid] [base denom] [start time] [end time]", | ||
Short: "Query twap", | ||
Long: strings.TrimSpace( | ||
fmt.Sprintf(`Query twap for pull. Start time must be unix time. End time can be unix time or duration. | ||
Example: | ||
$ %s q twap 1 uosmo 1667088000 24h | ||
$ %s q twap 1 uosmo 1667088000 1667174400 | ||
`, | ||
version.AppName, version.AppName, | ||
), | ||
), | ||
Args: cobra.ExactArgs(4), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
// boilerplate parse fields | ||
// <UINT PARSE> | ||
poolId, err := parseUint(args[0], "poolId") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// <DENOM PARSE> | ||
baseDenom := strings.TrimSpace(args[1]) | ||
|
||
// <UNIX TIME PARSE> | ||
startTime, err := parseUnixTime(args[2], "start time") | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// END TIME PARSE: ONEOF {<UNIX TIME PARSE>, <DURATION>} | ||
// try parsing in unix time, if failed try parsing in duration | ||
endTime, err := parseUnixTime(args[3], "end time") | ||
if err != nil { | ||
// TODO if we don't use protoreflect: | ||
// make better error combiner, rather than just returning last error | ||
duration, err := time.ParseDuration(args[3]) | ||
if err != nil { | ||
return err | ||
} | ||
endTime = startTime.Add(duration) | ||
} | ||
|
||
clientCtx, err := client.GetClientQueryContext(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
queryClient := queryproto.NewQueryClient(clientCtx) | ||
gammClient := gammtypes.NewQueryClient(clientCtx) | ||
liquidity, err := gammClient.TotalPoolLiquidity(cmd.Context(), &gammtypes.QueryTotalPoolLiquidityRequest{PoolId: poolId}) | ||
if err != nil { | ||
return err | ||
} | ||
if len(liquidity.Liquidity) != 2 { | ||
return fmt.Errorf("pool %d has %d assets of liquidity, CLI support only exists for 2 assets right now.", poolId, len(liquidity.Liquidity)) | ||
} | ||
quoteDenom := "" | ||
if liquidity.Liquidity[0].Denom == baseDenom { | ||
quoteDenom = liquidity.Liquidity[1].Denom | ||
} else if liquidity.Liquidity[1].Denom == baseDenom { | ||
quoteDenom = liquidity.Liquidity[0].Denom | ||
} else { | ||
return fmt.Errorf("pool %d doesn't have provided baseDenom %s, has %s and %s", | ||
poolId, baseDenom, liquidity.Liquidity[0], liquidity.Liquidity[1]) | ||
} | ||
|
||
res, err := queryClient.ArithmeticTwap(cmd.Context(), &queryproto.ArithmeticTwapRequest{ | ||
PoolId: poolId, | ||
BaseAsset: baseDenom, | ||
QuoteAsset: quoteDenom, | ||
StartTime: startTime, | ||
EndTime: &endTime, | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return clientCtx.PrintProto(res) | ||
}, | ||
} | ||
|
||
flags.AddQueryFlagsToCmd(cmd) | ||
|
||
return cmd | ||
} | ||
|
||
func parseUint(arg string, fieldName string) (uint64, error) { | ||
v, err := strconv.ParseUint(arg, 10, 64) | ||
if err != nil { | ||
return 0, fmt.Errorf("could not parse %s as uint for field %s: %w", arg, fieldName, err) | ||
} | ||
return v, nil | ||
} | ||
|
||
func parseUnixTime(arg string, fieldName string) (time.Time, error) { | ||
timeUnix, err := strconv.ParseInt(arg, 10, 64) | ||
if err != nil { | ||
return time.Time{}, fmt.Errorf("could not parse %s as unix time for field %s: %w", arg, fieldName, err) | ||
} | ||
startTime := time.Unix(timeUnix, 0) | ||
return startTime, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters