2022-10-05 22:56:39 +00:00
|
|
|
package keeper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
|
2023-04-05 23:21:59 +00:00
|
|
|
sdkmath "cosmossdk.io/math"
|
2022-10-05 22:56:39 +00:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
vestingexported "github.com/cosmos/cosmos-sdk/x/auth/vesting/exported"
|
|
|
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
|
|
|
"github.com/kava-labs/kava/x/liquid/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type queryServer struct {
|
|
|
|
keeper Keeper
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewQueryServerImpl creates a new server for handling gRPC queries.
|
|
|
|
func NewQueryServerImpl(k Keeper) types.QueryServer {
|
|
|
|
return &queryServer{keeper: k}
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ types.QueryServer = queryServer{}
|
|
|
|
|
|
|
|
func (s queryServer) DelegatedBalance(
|
|
|
|
goCtx context.Context,
|
|
|
|
req *types.QueryDelegatedBalanceRequest,
|
|
|
|
) (*types.QueryDelegatedBalanceResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
|
|
|
|
delegator, err := sdk.AccAddressFromBech32(req.Delegator)
|
|
|
|
if err != nil {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "invalid delegator address: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
delegated := s.getDelegatedBalance(ctx, delegator)
|
|
|
|
|
|
|
|
bondDenom := s.keeper.stakingKeeper.BondDenom(ctx)
|
|
|
|
vesting := s.getVesting(ctx, delegator).AmountOf(bondDenom)
|
|
|
|
|
|
|
|
vestingDelegated := sdk.MinInt(vesting, delegated)
|
|
|
|
vestedDelegated := delegated.Sub(vestingDelegated)
|
|
|
|
|
|
|
|
res := types.QueryDelegatedBalanceResponse{
|
|
|
|
Vested: sdk.NewCoin(bondDenom, vestedDelegated),
|
|
|
|
Vesting: sdk.NewCoin(bondDenom, vestingDelegated),
|
|
|
|
}
|
|
|
|
return &res, nil
|
2022-11-08 17:43:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s queryServer) TotalSupply(
|
|
|
|
goCtx context.Context,
|
|
|
|
req *types.QueryTotalSupplyRequest,
|
|
|
|
) (*types.QueryTotalSupplyResponse, error) {
|
|
|
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
|
|
|
|
|
|
|
totalValue, err := s.keeper.GetTotalDerivativeValue(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &types.QueryTotalSupplyResponse{
|
|
|
|
Height: ctx.BlockHeight(),
|
|
|
|
Result: []sdk.Coin{totalValue},
|
|
|
|
}, nil
|
2022-10-05 22:56:39 +00:00
|
|
|
}
|
|
|
|
|
2023-04-05 23:21:59 +00:00
|
|
|
func (s queryServer) getDelegatedBalance(ctx sdk.Context, delegator sdk.AccAddress) sdkmath.Int {
|
2022-10-05 22:56:39 +00:00
|
|
|
balance := sdk.ZeroDec()
|
|
|
|
|
|
|
|
s.keeper.stakingKeeper.IterateDelegatorDelegations(ctx, delegator, func(delegation stakingtypes.Delegation) bool {
|
|
|
|
validator, found := s.keeper.stakingKeeper.GetValidator(ctx, delegation.GetValidatorAddr())
|
|
|
|
if !found {
|
|
|
|
panic(fmt.Sprintf("validator %s for delegation not found", delegation.GetValidatorAddr()))
|
|
|
|
}
|
|
|
|
tokens := validator.TokensFromSharesTruncated(delegation.GetShares())
|
|
|
|
balance = balance.Add(tokens)
|
|
|
|
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
return balance.TruncateInt()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s queryServer) getVesting(ctx sdk.Context, delegator sdk.AccAddress) sdk.Coins {
|
|
|
|
acc := s.keeper.accountKeeper.GetAccount(ctx, delegator)
|
|
|
|
if acc == nil {
|
|
|
|
// account doesn't exist so amount vesting is 0
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
vestAcc, ok := acc.(vestingexported.VestingAccount)
|
|
|
|
if !ok {
|
|
|
|
// account is not vesting type, so amount vesting is 0
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return vestAcc.GetVestingCoins(ctx.BlockTime())
|
|
|
|
}
|