119 lines
3.4 KiB
Go
119 lines
3.4 KiB
Go
package grpcserver
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strconv"
|
|
|
|
walletpb "game-admin/gen"
|
|
"game-admin/internal/wallet"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
type WalletServer struct {
|
|
walletpb.UnimplementedWalletServiceServer
|
|
|
|
service *wallet.Service
|
|
}
|
|
|
|
func NewWalletServer(service *wallet.Service) *WalletServer {
|
|
return &WalletServer{service: service}
|
|
}
|
|
|
|
func (s *WalletServer) Reserve(ctx context.Context, req *walletpb.ReserveRequest) (*walletpb.ReserveResponse, error) {
|
|
transaction, responseStatus, balances, err := s.service.Reserve(
|
|
ctx,
|
|
req.GetRequestId(),
|
|
req.GetUserId(),
|
|
req.GetGameId(),
|
|
req.GetRoundId(),
|
|
req.GetAmount(),
|
|
req.GetCurrency(),
|
|
)
|
|
if err != nil {
|
|
return nil, mapWalletError(err)
|
|
}
|
|
|
|
return &walletpb.ReserveResponse{
|
|
TransactionId: transaction.ID,
|
|
Status: responseStatus,
|
|
AvailableBalance: balances.Available,
|
|
ReservedBalance: balances.Reserved,
|
|
}, nil
|
|
}
|
|
|
|
func (s *WalletServer) Confirm(ctx context.Context, req *walletpb.ConfirmRequest) (*walletpb.ConfirmResponse, error) {
|
|
transaction, responseStatus, balances, err := s.service.Confirm(
|
|
ctx,
|
|
req.GetTransactionId(),
|
|
req.GetRoundId(),
|
|
req.GetWinAmount(),
|
|
)
|
|
if err != nil {
|
|
return nil, mapWalletError(err)
|
|
}
|
|
|
|
return &walletpb.ConfirmResponse{
|
|
TransactionId: transaction.ID,
|
|
Status: responseStatus,
|
|
AvailableBalance: balances.Available,
|
|
ReservedBalance: balances.Reserved,
|
|
}, nil
|
|
}
|
|
|
|
func (s *WalletServer) Cancel(ctx context.Context, req *walletpb.CancelRequest) (*walletpb.CancelResponse, error) {
|
|
transaction, responseStatus, balances, err := s.service.Cancel(ctx, req.GetTransactionId())
|
|
if err != nil {
|
|
return nil, mapWalletError(err)
|
|
}
|
|
|
|
return &walletpb.CancelResponse{
|
|
TransactionId: transaction.ID,
|
|
Status: responseStatus,
|
|
AvailableBalance: balances.Available,
|
|
ReservedBalance: balances.Reserved,
|
|
}, nil
|
|
}
|
|
|
|
func (s *WalletServer) GetTransaction(ctx context.Context, req *walletpb.GetTransactionRequest) (*walletpb.GetTransactionResponse, error) {
|
|
transaction, err := s.service.GetTransaction(ctx, req.GetTransactionId())
|
|
if err != nil {
|
|
return nil, mapWalletError(err)
|
|
}
|
|
|
|
return &walletpb.GetTransactionResponse{
|
|
TransactionId: transaction.ID,
|
|
UserId: strconv.FormatInt(transaction.UserID, 10),
|
|
RoundId: transaction.RoundID,
|
|
Amount: transaction.Amount,
|
|
WinAmount: transaction.WinAmount,
|
|
Status: transaction.Status,
|
|
}, nil
|
|
}
|
|
|
|
func mapWalletError(err error) error {
|
|
switch {
|
|
case errors.Is(err, wallet.ErrInvalidAmount),
|
|
errors.Is(err, wallet.ErrMissingRequiredFields),
|
|
errors.Is(err, wallet.ErrInvalidUserID),
|
|
errors.Is(err, wallet.ErrInvalidGameID),
|
|
errors.Is(err, wallet.ErrMissingTransactionID),
|
|
errors.Is(err, wallet.ErrMissingRoundID),
|
|
errors.Is(err, wallet.ErrInvalidWinAmount),
|
|
errors.Is(err, wallet.ErrRoundMismatch):
|
|
return status.Error(codes.InvalidArgument, err.Error())
|
|
case errors.Is(err, wallet.ErrAccountNotFound),
|
|
errors.Is(err, wallet.ErrTransactionNotFound):
|
|
return status.Error(codes.NotFound, err.Error())
|
|
case errors.Is(err, wallet.ErrInsufficientFunds),
|
|
errors.Is(err, wallet.ErrAlreadyCanceled),
|
|
errors.Is(err, wallet.ErrAlreadyConfirmed),
|
|
errors.Is(err, wallet.ErrInvalidTransactionState):
|
|
return status.Error(codes.FailedPrecondition, err.Error())
|
|
default:
|
|
return status.Error(codes.Internal, err.Error())
|
|
}
|
|
}
|