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

Support Estimate Swap queries via grpc gateway #5810

Merged
merged 4 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
40 changes: 40 additions & 0 deletions proto/osmosis/poolmanager/v1beta1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ service Query {
"/osmosis/poolmanager/v1beta1/{pool_id}/estimate/swap_exact_amount_in";
}

// EstimateSwapExactAmountInWithPrimitiveTypes is an alternative query for
// EstimateSwapExactAmountIn. Supports query via GRPC-Gateway by using
// primitive types instead of repeated structs. Each index in the
// routes_pool_id field corresponds to the respective routes_token_out_denom
// value, thus they are required to have the same length and are grouped
// together as pairs.
rpc EstimateSwapExactAmountInWithPrimitiveTypes(
EstimateSwapExactAmountInWithPrimitiveTypesRequest)
returns (EstimateSwapExactAmountInResponse) {
option (google.api.http).get =
"/osmosis/poolmanager/v1beta1/{pool_id}/estimate/"
"swap_exact_amount_in_with_primitive_types";
}

rpc EstimateSinglePoolSwapExactAmountIn(
EstimateSinglePoolSwapExactAmountInRequest)
returns (EstimateSwapExactAmountInResponse) {
Expand All @@ -41,6 +55,15 @@ service Query {
"/osmosis/poolmanager/v1beta1/{pool_id}/estimate/swap_exact_amount_out";
}

// Estimates swap amount in given out.
rpc EstimateSwapExactAmountOutWithPrimitiveTypes(
EstimateSwapExactAmountOutWithPrimitiveTypesRequest)
returns (EstimateSwapExactAmountOutResponse) {
option (google.api.http).get =
"/osmosis/poolmanager/v1beta1/{pool_id}/estimate/"
"swap_exact_amount_out_with_primitive_types";
}

rpc EstimateSinglePoolSwapExactAmountOut(
EstimateSinglePoolSwapExactAmountOutRequest)
returns (EstimateSwapExactAmountOutResponse) {
Expand Down Expand Up @@ -101,6 +124,14 @@ message EstimateSwapExactAmountInRequest {
(gogoproto.nullable) = false
];
}
message EstimateSwapExactAmountInWithPrimitiveTypesRequest {
uint64 pool_id = 1 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ];
string token_in = 2 [ (gogoproto.moretags) = "yaml:\"token_in\"" ];
repeated uint64 routes_pool_id = 3
[ (gogoproto.moretags) = "yaml:\"routes_pool_id\"" ];
repeated string routes_token_out_denom = 4
[ (gogoproto.moretags) = "yaml:\"routes_token_out_denom\"" ];
}

message EstimateSinglePoolSwapExactAmountInRequest {
uint64 pool_id = 1 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ];
Expand Down Expand Up @@ -129,6 +160,15 @@ message EstimateSwapExactAmountOutRequest {
string token_out = 4 [ (gogoproto.moretags) = "yaml:\"token_out\"" ];
}

message EstimateSwapExactAmountOutWithPrimitiveTypesRequest {
uint64 pool_id = 1 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ];
repeated uint64 routes_pool_id = 2
[ (gogoproto.moretags) = "yaml:\"routes_pool_id\"" ];
repeated string routes_token_in_denom = 3
[ (gogoproto.moretags) = "yaml:\"routes_token_in_denom\"" ];
string token_out = 4 [ (gogoproto.moretags) = "yaml:\"token_out\"" ];
}

message EstimateSinglePoolSwapExactAmountOutRequest {
uint64 pool_id = 1 [ (gogoproto.moretags) = "yaml:\"pool_id\"" ];
string token_in_denom = 2
Expand Down
12 changes: 12 additions & 0 deletions proto/osmosis/poolmanager/v1beta1/query.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,23 @@ queries:
query_func: "k.EstimateSwapExactAmountIn"
cli:
cmd: "EstimateSwapExactAmountIn"
EstimateSwapExactAmountInWithPrimitiveTypes:
proto_wrapper:
query_func: "k.EstimateSwapExactAmountInWithPrimitiveTypes"
response: "*queryproto.EstimateSwapExactAmountInResponse"
cli:
cmd: "EstimateSwapExactAmountInWithPrimitiveTypes"
EstimateSwapExactAmountOut:
proto_wrapper:
query_func: "k.EstimateSwapExactAmountOut"
cli:
cmd: "EstimateSwapExactAmountOut"
EstimateSwapExactAmountOutWithPrimitiveTypes:
proto_wrapper:
query_func: "k.EstimateSwapExactAmountOutWithPrimitiveTypes"
response: "*queryproto.EstimateSwapExactAmountOutResponse"
cli:
cmd: "EstimateSwapExactAmountOutWithPrimitiveTypes"
EstimateSinglePoolSwapExactAmountIn:
proto_wrapper:
query_func: "k.EstimateSinglePoolSwapExactAmountIn"
Expand Down
20 changes: 20 additions & 0 deletions x/poolmanager/client/grpc/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ func (q Querier) NumPools(grpcCtx context.Context,
return q.Q.NumPools(ctx, *req)
}

func (q Querier) EstimateSwapExactAmountOutWithPrimitiveTypes(grpcCtx context.Context,
req *queryproto.EstimateSwapExactAmountOutWithPrimitiveTypesRequest,
) (*queryproto.EstimateSwapExactAmountOutResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(grpcCtx)
return q.Q.EstimateSwapExactAmountOutWithPrimitiveTypes(ctx, *req)
}

func (q Querier) EstimateSwapExactAmountOut(grpcCtx context.Context,
req *queryproto.EstimateSwapExactAmountOutRequest,
) (*queryproto.EstimateSwapExactAmountOutResponse, error) {
Expand All @@ -90,6 +100,16 @@ func (q Querier) EstimateSwapExactAmountOut(grpcCtx context.Context,
return q.Q.EstimateSwapExactAmountOut(ctx, *req)
}

func (q Querier) EstimateSwapExactAmountInWithPrimitiveTypes(grpcCtx context.Context,
req *queryproto.EstimateSwapExactAmountInWithPrimitiveTypesRequest,
) (*queryproto.EstimateSwapExactAmountInResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
ctx := sdk.UnwrapSDKContext(grpcCtx)
return q.Q.EstimateSwapExactAmountInWithPrimitiveTypes(ctx, *req)
}

func (q Querier) EstimateSwapExactAmountIn(grpcCtx context.Context,
req *queryproto.EstimateSwapExactAmountInRequest,
) (*queryproto.EstimateSwapExactAmountInResponse, error) {
Expand Down
63 changes: 63 additions & 0 deletions x/poolmanager/client/query_proto_wrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,36 @@ func (q Querier) EstimateSwapExactAmountIn(ctx sdk.Context, req queryproto.Estim
}, nil
}

// EstimateSwapExactAmountInWithPrimitiveTypes runs same logic with EstimateSwapExactAmountIn
// but instead takes array of primitive types in the request to support query through grpc-gateway.
func (q Querier) EstimateSwapExactAmountInWithPrimitiveTypes(ctx sdk.Context, req queryproto.EstimateSwapExactAmountInWithPrimitiveTypesRequest) (*queryproto.EstimateSwapExactAmountInResponse, error) {
if req.TokenIn == "" {
return nil, status.Error(codes.InvalidArgument, "invalid token")
}

tokenIn, err := sdk.ParseCoinNormalized(req.TokenIn)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid token: %s", err.Error())
}

var routes []types.SwapAmountInRoute

for idx, poolId := range req.RoutesPoolId {
var route types.SwapAmountInRoute
route.PoolId = poolId
route.TokenOutDenom = req.RoutesTokenOutDenom[idx]
}

tokenOutAmount, err := q.K.MultihopEstimateOutGivenExactAmountIn(ctx, routes, tokenIn)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

return &queryproto.EstimateSwapExactAmountInResponse{
TokenOutAmount: tokenOutAmount,
}, nil
}

// EstimateSwapExactAmountOut estimates token output amount for a swap.
func (q Querier) EstimateSwapExactAmountOut(ctx sdk.Context, req queryproto.EstimateSwapExactAmountOutRequest) (*queryproto.EstimateSwapExactAmountOutResponse, error) {
if req.TokenOut == "" {
Expand All @@ -75,6 +105,39 @@ func (q Querier) EstimateSwapExactAmountOut(ctx sdk.Context, req queryproto.Esti
}, nil
}

// EstimateSwapExactAmountOut estimates token output amount for a swap.
func (q Querier) EstimateSwapExactAmountOutWithPrimitiveTypes(ctx sdk.Context, req queryproto.EstimateSwapExactAmountOutWithPrimitiveTypesRequest) (*queryproto.EstimateSwapExactAmountOutResponse, error) {
if req.TokenOut == "" {
return nil, status.Error(codes.InvalidArgument, "invalid token")
}

var routes []types.SwapAmountOutRoute

for idx, poolId := range req.RoutesPoolId {
var route types.SwapAmountOutRoute
route.PoolId = poolId
route.TokenInDenom = req.RoutesTokenInDenom[idx]
}

if err := types.SwapAmountOutRoutes(routes).Validate(); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

tokenOut, err := sdk.ParseCoinNormalized(req.TokenOut)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "invalid token: %s", err.Error())
}

tokenInAmount, err := q.K.MultihopEstimateInGivenExactAmountOut(ctx, routes, tokenOut)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}

return &queryproto.EstimateSwapExactAmountOutResponse{
TokenInAmount: tokenInAmount,
}, nil
}

func (q Querier) EstimateSinglePoolSwapExactAmountOut(ctx sdk.Context, req queryproto.EstimateSinglePoolSwapExactAmountOutRequest) (*queryproto.EstimateSwapExactAmountOutResponse, error) {
routeReq := &queryproto.EstimateSwapExactAmountOutRequest{
PoolId: req.PoolId,
Expand Down
Loading