github.com/Finschia/finschia-sdk@v0.49.1/x/bank/keeper/grpc_query.go (about)

     1  package keeper
     2  
     3  import (
     4  	"context"
     5  
     6  	"google.golang.org/grpc/codes"
     7  	"google.golang.org/grpc/status"
     8  
     9  	"github.com/Finschia/finschia-sdk/store/prefix"
    10  	sdk "github.com/Finschia/finschia-sdk/types"
    11  	"github.com/Finschia/finschia-sdk/types/query"
    12  	"github.com/Finschia/finschia-sdk/x/bank/types"
    13  )
    14  
    15  var _ types.QueryServer = BaseKeeper{}
    16  
    17  // Balance implements the Query/Balance gRPC method
    18  func (k BaseKeeper) Balance(ctx context.Context, req *types.QueryBalanceRequest) (*types.QueryBalanceResponse, error) {
    19  	if req == nil {
    20  		return nil, status.Error(codes.InvalidArgument, "empty request")
    21  	}
    22  
    23  	if req.Address == "" {
    24  		return nil, status.Error(codes.InvalidArgument, "address cannot be empty")
    25  	}
    26  
    27  	if req.Denom == "" {
    28  		return nil, status.Error(codes.InvalidArgument, "invalid denom")
    29  	}
    30  
    31  	sdkCtx := sdk.UnwrapSDKContext(ctx)
    32  	address, err := sdk.AccAddressFromBech32(req.Address)
    33  	if err != nil {
    34  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
    35  	}
    36  
    37  	balance := k.GetBalance(sdkCtx, address, req.Denom)
    38  
    39  	return &types.QueryBalanceResponse{Balance: &balance}, nil
    40  }
    41  
    42  // AllBalances implements the Query/AllBalances gRPC method
    43  func (k BaseKeeper) AllBalances(ctx context.Context, req *types.QueryAllBalancesRequest) (*types.QueryAllBalancesResponse, error) {
    44  	if req == nil {
    45  		return nil, status.Error(codes.InvalidArgument, "empty request")
    46  	}
    47  
    48  	if req.Address == "" {
    49  		return nil, status.Error(codes.InvalidArgument, "address cannot be empty")
    50  	}
    51  
    52  	addr, err := sdk.AccAddressFromBech32(req.Address)
    53  	if err != nil {
    54  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
    55  	}
    56  
    57  	sdkCtx := sdk.UnwrapSDKContext(ctx)
    58  
    59  	balances := sdk.NewCoins()
    60  	accountStore := k.getAccountStore(sdkCtx, addr)
    61  
    62  	pageRes, err := query.Paginate(accountStore, req.Pagination, func(_, value []byte) error {
    63  		var result sdk.Coin
    64  		err := k.cdc.Unmarshal(value, &result)
    65  		if err != nil {
    66  			return err
    67  		}
    68  		balances = append(balances, result)
    69  		return nil
    70  	})
    71  	if err != nil {
    72  		return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
    73  	}
    74  
    75  	return &types.QueryAllBalancesResponse{Balances: balances, Pagination: pageRes}, nil
    76  }
    77  
    78  // SpendableBalances implements a gRPC query handler for retrieving an account's
    79  // spendable balances.
    80  func (k BaseKeeper) SpendableBalances(ctx context.Context, req *types.QuerySpendableBalancesRequest) (*types.QuerySpendableBalancesResponse, error) {
    81  	if req == nil {
    82  		return nil, status.Error(codes.InvalidArgument, "empty request")
    83  	}
    84  
    85  	addr, err := sdk.AccAddressFromBech32(req.Address)
    86  	if err != nil {
    87  		return nil, status.Errorf(codes.InvalidArgument, "invalid address: %s", err.Error())
    88  	}
    89  
    90  	sdkCtx := sdk.UnwrapSDKContext(ctx)
    91  
    92  	balances := sdk.NewCoins()
    93  	accountStore := k.getAccountStore(sdkCtx, addr)
    94  	zeroAmt := sdk.ZeroInt()
    95  
    96  	pageRes, err := query.Paginate(accountStore, req.Pagination, func(key, value []byte) error {
    97  		balances = append(balances, sdk.NewCoin(string(key), zeroAmt))
    98  		return nil
    99  	})
   100  	if err != nil {
   101  		return nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
   102  	}
   103  
   104  	result := sdk.NewCoins()
   105  	spendable := k.SpendableCoins(sdkCtx, addr)
   106  
   107  	for _, c := range balances {
   108  		result = append(result, sdk.NewCoin(c.Denom, spendable.AmountOf(c.Denom)))
   109  	}
   110  
   111  	return &types.QuerySpendableBalancesResponse{Balances: result, Pagination: pageRes}, nil
   112  }
   113  
   114  // TotalSupply implements the Query/TotalSupply gRPC method
   115  func (k BaseKeeper) TotalSupply(ctx context.Context, req *types.QueryTotalSupplyRequest) (*types.QueryTotalSupplyResponse, error) {
   116  	sdkCtx := sdk.UnwrapSDKContext(ctx)
   117  	totalSupply, pageRes, err := k.GetPaginatedTotalSupply(sdkCtx, req.Pagination)
   118  	if err != nil {
   119  		return nil, status.Error(codes.Internal, err.Error())
   120  	}
   121  
   122  	return &types.QueryTotalSupplyResponse{Supply: totalSupply, Pagination: pageRes}, nil
   123  }
   124  
   125  // SupplyOf implements the Query/SupplyOf gRPC method
   126  func (k BaseKeeper) SupplyOf(c context.Context, req *types.QuerySupplyOfRequest) (*types.QuerySupplyOfResponse, error) {
   127  	if req == nil {
   128  		return nil, status.Error(codes.InvalidArgument, "empty request")
   129  	}
   130  
   131  	if req.Denom == "" {
   132  		return nil, status.Error(codes.InvalidArgument, "invalid denom")
   133  	}
   134  
   135  	ctx := sdk.UnwrapSDKContext(c)
   136  	supply := k.GetSupply(ctx, req.Denom)
   137  
   138  	return &types.QuerySupplyOfResponse{Amount: sdk.NewCoin(req.Denom, supply.Amount)}, nil
   139  }
   140  
   141  // Params implements the gRPC service handler for querying x/bank parameters.
   142  func (k BaseKeeper) Params(ctx context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
   143  	if req == nil {
   144  		return nil, status.Errorf(codes.InvalidArgument, "empty request")
   145  	}
   146  
   147  	sdkCtx := sdk.UnwrapSDKContext(ctx)
   148  	params := k.GetParams(sdkCtx)
   149  
   150  	return &types.QueryParamsResponse{Params: params}, nil
   151  }
   152  
   153  // DenomsMetadata implements Query/DenomsMetadata gRPC method.
   154  func (k BaseKeeper) DenomsMetadata(c context.Context, req *types.QueryDenomsMetadataRequest) (*types.QueryDenomsMetadataResponse, error) {
   155  	if req == nil {
   156  		return nil, status.Errorf(codes.InvalidArgument, "empty request")
   157  	}
   158  
   159  	ctx := sdk.UnwrapSDKContext(c)
   160  	store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomMetadataPrefix)
   161  
   162  	metadatas := []types.Metadata{}
   163  	pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error {
   164  		var metadata types.Metadata
   165  		k.cdc.MustUnmarshal(value, &metadata)
   166  
   167  		metadatas = append(metadatas, metadata)
   168  		return nil
   169  	})
   170  	if err != nil {
   171  		return nil, status.Error(codes.Internal, err.Error())
   172  	}
   173  
   174  	return &types.QueryDenomsMetadataResponse{
   175  		Metadatas:  metadatas,
   176  		Pagination: pageRes,
   177  	}, nil
   178  }
   179  
   180  // DenomMetadata implements Query/DenomMetadata gRPC method.
   181  func (k BaseKeeper) DenomMetadata(c context.Context, req *types.QueryDenomMetadataRequest) (*types.QueryDenomMetadataResponse, error) {
   182  	if req == nil {
   183  		return nil, status.Errorf(codes.InvalidArgument, "empty request")
   184  	}
   185  
   186  	if req.Denom == "" {
   187  		return nil, status.Error(codes.InvalidArgument, "invalid denom")
   188  	}
   189  
   190  	ctx := sdk.UnwrapSDKContext(c)
   191  
   192  	metadata, found := k.GetDenomMetaData(ctx, req.Denom)
   193  	if !found {
   194  		return nil, status.Errorf(codes.NotFound, "client metadata for denom %s", req.Denom)
   195  	}
   196  
   197  	return &types.QueryDenomMetadataResponse{
   198  		Metadata: metadata,
   199  	}, nil
   200  }