github.com/cosmos/cosmos-sdk@v0.50.10/x/auth/keeper/grpc_query.go (about) 1 package keeper 2 3 import ( 4 "context" 5 "errors" 6 "sort" 7 "strings" 8 9 "google.golang.org/grpc/codes" 10 "google.golang.org/grpc/status" 11 12 codectypes "github.com/cosmos/cosmos-sdk/codec/types" 13 sdk "github.com/cosmos/cosmos-sdk/types" 14 "github.com/cosmos/cosmos-sdk/types/query" 15 "github.com/cosmos/cosmos-sdk/x/auth/types" 16 ) 17 18 var _ types.QueryServer = queryServer{} 19 20 func NewQueryServer(k AccountKeeper) types.QueryServer { 21 return queryServer{k: k} 22 } 23 24 type queryServer struct{ k AccountKeeper } 25 26 func (s queryServer) AccountAddressByID(ctx context.Context, req *types.QueryAccountAddressByIDRequest) (*types.QueryAccountAddressByIDResponse, error) { 27 if req == nil { 28 return nil, status.Errorf(codes.InvalidArgument, "empty request") 29 } 30 31 if req.Id != 0 { // ignoring `0` case since it is default value. 32 return nil, status.Error(codes.InvalidArgument, "requesting with id isn't supported, try to request using account-id") 33 } 34 35 accID := req.AccountId 36 37 address, err := s.k.Accounts.Indexes.Number.MatchExact(ctx, accID) 38 if err != nil { 39 return nil, status.Errorf(codes.NotFound, "account address not found with account number %d", accID) 40 } 41 42 return &types.QueryAccountAddressByIDResponse{AccountAddress: address.String()}, nil 43 } 44 45 func (s queryServer) Accounts(ctx context.Context, req *types.QueryAccountsRequest) (*types.QueryAccountsResponse, error) { 46 if req == nil { 47 return nil, status.Error(codes.InvalidArgument, "empty request") 48 } 49 50 accounts, pageRes, err := query.CollectionPaginate( 51 ctx, 52 s.k.Accounts, 53 req.Pagination, 54 func(_ sdk.AccAddress, value sdk.AccountI) (*codectypes.Any, error) { 55 return codectypes.NewAnyWithValue(value) 56 }, 57 ) 58 59 return &types.QueryAccountsResponse{Accounts: accounts, Pagination: pageRes}, err 60 } 61 62 // Account returns account details based on address 63 func (s queryServer) Account(ctx context.Context, req *types.QueryAccountRequest) (*types.QueryAccountResponse, error) { 64 if req == nil { 65 return nil, status.Errorf(codes.InvalidArgument, "empty request") 66 } 67 68 if req.Address == "" { 69 return nil, status.Error(codes.InvalidArgument, "Address cannot be empty") 70 } 71 72 addr, err := s.k.addressCodec.StringToBytes(req.Address) 73 if err != nil { 74 return nil, err 75 } 76 account := s.k.GetAccount(ctx, addr) 77 if account == nil { 78 return nil, status.Errorf(codes.NotFound, "account %s not found", req.Address) 79 } 80 81 any, err := codectypes.NewAnyWithValue(account) 82 if err != nil { 83 return nil, status.Errorf(codes.Internal, err.Error()) 84 } 85 86 return &types.QueryAccountResponse{Account: any}, nil 87 } 88 89 // Params returns parameters of auth module 90 func (s queryServer) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { 91 if req == nil { 92 return nil, status.Error(codes.InvalidArgument, "empty request") 93 } 94 ctx := sdk.UnwrapSDKContext(c) 95 params := s.k.GetParams(ctx) 96 97 return &types.QueryParamsResponse{Params: params}, nil 98 } 99 100 // ModuleAccounts returns all the existing Module Accounts 101 func (s queryServer) ModuleAccounts(c context.Context, req *types.QueryModuleAccountsRequest) (*types.QueryModuleAccountsResponse, error) { 102 if req == nil { 103 return nil, status.Error(codes.InvalidArgument, "empty request") 104 } 105 106 ctx := sdk.UnwrapSDKContext(c) 107 108 // For deterministic output, sort the permAddrs by module name. 109 sortedPermAddrs := make([]string, 0, len(s.k.permAddrs)) 110 for moduleName := range s.k.permAddrs { 111 sortedPermAddrs = append(sortedPermAddrs, moduleName) 112 } 113 sort.Strings(sortedPermAddrs) 114 115 modAccounts := make([]*codectypes.Any, 0, len(s.k.permAddrs)) 116 117 for _, moduleName := range sortedPermAddrs { 118 account := s.k.GetModuleAccount(ctx, moduleName) 119 if account == nil { 120 return nil, status.Errorf(codes.NotFound, "account %s not found", moduleName) 121 } 122 any, err := codectypes.NewAnyWithValue(account) 123 if err != nil { 124 return nil, status.Errorf(codes.Internal, err.Error()) 125 } 126 modAccounts = append(modAccounts, any) 127 } 128 129 return &types.QueryModuleAccountsResponse{Accounts: modAccounts}, nil 130 } 131 132 // ModuleAccountByName returns module account by module name 133 func (s queryServer) ModuleAccountByName(c context.Context, req *types.QueryModuleAccountByNameRequest) (*types.QueryModuleAccountByNameResponse, error) { 134 if req == nil { 135 return nil, status.Errorf(codes.InvalidArgument, "empty request") 136 } 137 138 if len(req.Name) == 0 { 139 return nil, status.Error(codes.InvalidArgument, "module name is empty") 140 } 141 142 ctx := sdk.UnwrapSDKContext(c) 143 moduleName := req.Name 144 145 account := s.k.GetModuleAccount(ctx, moduleName) 146 if account == nil { 147 return nil, status.Errorf(codes.NotFound, "account %s not found", moduleName) 148 } 149 any, err := codectypes.NewAnyWithValue(account) 150 if err != nil { 151 return nil, status.Errorf(codes.Internal, err.Error()) 152 } 153 154 return &types.QueryModuleAccountByNameResponse{Account: any}, nil 155 } 156 157 // Bech32Prefix returns the keeper internally stored bech32 prefix. 158 func (s queryServer) Bech32Prefix(ctx context.Context, req *types.Bech32PrefixRequest) (*types.Bech32PrefixResponse, error) { 159 bech32Prefix, err := s.k.getBech32Prefix() 160 if err != nil { 161 return nil, err 162 } 163 164 if bech32Prefix == "" { 165 return &types.Bech32PrefixResponse{Bech32Prefix: "bech32 is not used on this chain"}, nil 166 } 167 168 return &types.Bech32PrefixResponse{Bech32Prefix: bech32Prefix}, nil 169 } 170 171 // AddressBytesToString converts an address from bytes to string, using the 172 // keeper's bech32 prefix. 173 func (s queryServer) AddressBytesToString(ctx context.Context, req *types.AddressBytesToStringRequest) (*types.AddressBytesToStringResponse, error) { 174 if req == nil { 175 return nil, status.Error(codes.InvalidArgument, "empty request") 176 } 177 178 if len(req.AddressBytes) == 0 { 179 return nil, errors.New("empty address bytes is not allowed") 180 } 181 182 text, err := s.k.addressCodec.BytesToString(req.AddressBytes) 183 if err != nil { 184 return nil, err 185 } 186 187 return &types.AddressBytesToStringResponse{AddressString: text}, nil 188 } 189 190 // AddressStringToBytes converts an address from string to bytes, using the 191 // keeper's bech32 prefix. 192 func (s queryServer) AddressStringToBytes(ctx context.Context, req *types.AddressStringToBytesRequest) (*types.AddressStringToBytesResponse, error) { 193 if req == nil { 194 return nil, status.Error(codes.InvalidArgument, "empty request") 195 } 196 197 if len(strings.TrimSpace(req.AddressString)) == 0 { 198 return nil, errors.New("empty address string is not allowed") 199 } 200 201 bz, err := s.k.addressCodec.StringToBytes(req.AddressString) 202 if err != nil { 203 return nil, err 204 } 205 206 return &types.AddressStringToBytesResponse{AddressBytes: bz}, nil 207 } 208 209 // AccountInfo implements the AccountInfo query. 210 func (s queryServer) AccountInfo(ctx context.Context, req *types.QueryAccountInfoRequest) (*types.QueryAccountInfoResponse, error) { 211 if req == nil { 212 return nil, status.Errorf(codes.InvalidArgument, "empty request") 213 } 214 215 if req.Address == "" { 216 return nil, status.Error(codes.InvalidArgument, "address cannot be empty") 217 } 218 219 addr, err := s.k.addressCodec.StringToBytes(req.Address) 220 if err != nil { 221 return nil, err 222 } 223 224 account := s.k.GetAccount(ctx, addr) 225 if account == nil { 226 return nil, status.Errorf(codes.NotFound, "account %s not found", req.Address) 227 } 228 229 // if there is no public key, avoid serializing the nil value 230 pubKey := account.GetPubKey() 231 var pkAny *codectypes.Any 232 if pubKey != nil { 233 pkAny, err = codectypes.NewAnyWithValue(account.GetPubKey()) 234 if err != nil { 235 return nil, status.Errorf(codes.Internal, err.Error()) 236 } 237 } 238 239 return &types.QueryAccountInfoResponse{ 240 Info: &types.BaseAccount{ 241 Address: req.Address, 242 PubKey: pkAny, 243 AccountNumber: account.GetAccountNumber(), 244 Sequence: account.GetSequence(), 245 }, 246 }, nil 247 }