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  }