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 }