github.com/NpoolPlatform/chain-middleware@v0.0.0-20240228100535-eb1bcf896eb9/pkg/mw/tx/handler.go (about)

     1  package tx
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	constant "github.com/NpoolPlatform/chain-middleware/pkg/const"
     8  	txcrud "github.com/NpoolPlatform/chain-middleware/pkg/crud/tx"
     9  	basetypes "github.com/NpoolPlatform/message/npool/basetypes/v1"
    10  	npool "github.com/NpoolPlatform/message/npool/chain/mw/v1/tx"
    11  
    12  	"github.com/NpoolPlatform/libent-cruder/pkg/cruder"
    13  
    14  	"github.com/google/uuid"
    15  	"github.com/shopspring/decimal"
    16  )
    17  
    18  type Handler struct {
    19  	ID            *uint32
    20  	EntID         *uuid.UUID
    21  	CoinTypeID    *uuid.UUID
    22  	FromAccountID *uuid.UUID
    23  	ToAccountID   *uuid.UUID
    24  	Amount        *decimal.Decimal
    25  	FeeAmount     *decimal.Decimal
    26  	ChainTxID     *string
    27  	State         *basetypes.TxState
    28  	Extra         *string
    29  	Type          *basetypes.TxType
    30  	Reqs          []*txcrud.Req
    31  	Conds         *txcrud.Conds
    32  	Offset        int32
    33  	Limit         int32
    34  }
    35  
    36  func NewHandler(ctx context.Context, options ...func(context.Context, *Handler) error) (*Handler, error) {
    37  	handler := &Handler{}
    38  	for _, opt := range options {
    39  		if err := opt(ctx, handler); err != nil {
    40  			return nil, err
    41  		}
    42  	}
    43  	return handler, nil
    44  }
    45  
    46  func WithID(u *uint32, must bool) func(context.Context, *Handler) error {
    47  	return func(ctx context.Context, h *Handler) error {
    48  		if u == nil {
    49  			if must {
    50  				return fmt.Errorf("invalid id")
    51  			}
    52  			return nil
    53  		}
    54  		h.ID = u
    55  		return nil
    56  	}
    57  }
    58  
    59  func WithEntID(id *string, must bool) func(context.Context, *Handler) error {
    60  	return func(ctx context.Context, h *Handler) error {
    61  		if id == nil {
    62  			if must {
    63  				return fmt.Errorf("invalid entid")
    64  			}
    65  			return nil
    66  		}
    67  		_id, err := uuid.Parse(*id)
    68  		if err != nil {
    69  			return err
    70  		}
    71  		h.EntID = &_id
    72  		return nil
    73  	}
    74  }
    75  
    76  func WithCoinTypeID(id *string, must bool) func(context.Context, *Handler) error {
    77  	return func(ctx context.Context, h *Handler) error {
    78  		if id == nil {
    79  			if must {
    80  				return fmt.Errorf("invalid cointypeid")
    81  			}
    82  			return nil
    83  		}
    84  		_id, err := uuid.Parse(*id)
    85  		if err != nil {
    86  			return err
    87  		}
    88  		h.CoinTypeID = &_id
    89  		return nil
    90  	}
    91  }
    92  
    93  func WithFromAccountID(id *string, must bool) func(context.Context, *Handler) error {
    94  	return func(ctx context.Context, h *Handler) error {
    95  		if id == nil {
    96  			if must {
    97  				return fmt.Errorf("invalid fromaccountid")
    98  			}
    99  			return nil
   100  		}
   101  		_id, err := uuid.Parse(*id)
   102  		if err != nil {
   103  			return err
   104  		}
   105  		h.FromAccountID = &_id
   106  		return nil
   107  	}
   108  }
   109  
   110  func WithToAccountID(id *string, must bool) func(context.Context, *Handler) error {
   111  	return func(ctx context.Context, h *Handler) error {
   112  		if id == nil {
   113  			if must {
   114  				return fmt.Errorf("invalid toaccountid")
   115  			}
   116  			return nil
   117  		}
   118  		_id, err := uuid.Parse(*id)
   119  		if err != nil {
   120  			return err
   121  		}
   122  		h.ToAccountID = &_id
   123  		return nil
   124  	}
   125  }
   126  
   127  func WithAmount(amount *string, must bool) func(context.Context, *Handler) error {
   128  	return func(ctx context.Context, h *Handler) error {
   129  		if amount == nil {
   130  			if must {
   131  				return fmt.Errorf("invalid amount")
   132  			}
   133  			return nil
   134  		}
   135  		_amount, err := decimal.NewFromString(*amount)
   136  		if err != nil {
   137  			return err
   138  		}
   139  		h.Amount = &_amount
   140  		return nil
   141  	}
   142  }
   143  
   144  func WithFeeAmount(amount *string, must bool) func(context.Context, *Handler) error {
   145  	return func(ctx context.Context, h *Handler) error {
   146  		if amount == nil {
   147  			if must {
   148  				return fmt.Errorf("invalid feeamount")
   149  			}
   150  			return nil
   151  		}
   152  		_amount, err := decimal.NewFromString(*amount)
   153  		if err != nil {
   154  			return err
   155  		}
   156  		h.FeeAmount = &_amount
   157  		return nil
   158  	}
   159  }
   160  
   161  func WithChainTxID(txID *string, must bool) func(context.Context, *Handler) error {
   162  	return func(ctx context.Context, h *Handler) error {
   163  		if txID == nil {
   164  			if must {
   165  				return fmt.Errorf("invalid chaintxid")
   166  			}
   167  			return nil
   168  		}
   169  		if *txID == "" {
   170  			return fmt.Errorf("invalid txid")
   171  		}
   172  		h.ChainTxID = txID
   173  		return nil
   174  	}
   175  }
   176  
   177  //nolint:dupl
   178  func WithState(state *basetypes.TxState, must bool) func(context.Context, *Handler) error {
   179  	return func(ctx context.Context, h *Handler) error {
   180  		if state == nil {
   181  			if must {
   182  				return fmt.Errorf("invalid state")
   183  			}
   184  			return nil
   185  		}
   186  		switch *state {
   187  		case basetypes.TxState_TxStateCreated:
   188  		case basetypes.TxState_TxStateCreatedCheck:
   189  		case basetypes.TxState_TxStateWait:
   190  		case basetypes.TxState_TxStateWaitCheck:
   191  		case basetypes.TxState_TxStateTransferring:
   192  		case basetypes.TxState_TxStateSuccessful:
   193  		case basetypes.TxState_TxStateFail:
   194  		default:
   195  			return fmt.Errorf("invalid txstate")
   196  		}
   197  		h.State = state
   198  		return nil
   199  	}
   200  }
   201  
   202  func WithExtra(extra *string, must bool) func(context.Context, *Handler) error {
   203  	return func(ctx context.Context, h *Handler) error {
   204  		h.Extra = extra
   205  		return nil
   206  	}
   207  }
   208  
   209  //nolint:dupl
   210  func WithType(_type *basetypes.TxType, must bool) func(context.Context, *Handler) error {
   211  	return func(ctx context.Context, h *Handler) error {
   212  		if _type == nil {
   213  			if must {
   214  				return fmt.Errorf("invalid type")
   215  			}
   216  			return nil
   217  		}
   218  		switch *_type {
   219  		case basetypes.TxType_TxWithdraw:
   220  		case basetypes.TxType_TxFeedGas:
   221  		case basetypes.TxType_TxPaymentCollect:
   222  		case basetypes.TxType_TxBenefit:
   223  		case basetypes.TxType_TxLimitation:
   224  		case basetypes.TxType_TxPlatformBenefit:
   225  		case basetypes.TxType_TxUserBenefit:
   226  		default:
   227  			return fmt.Errorf("invalid txtype")
   228  		}
   229  		h.Type = _type
   230  		return nil
   231  	}
   232  }
   233  
   234  // nolint:gocyclo
   235  func WithReqs(reqs []*npool.TxReq, must bool) func(context.Context, *Handler) error {
   236  	return func(ctx context.Context, h *Handler) error {
   237  		_reqs := []*txcrud.Req{}
   238  		for _, req := range reqs {
   239  			_req := &txcrud.Req{
   240  				Extra: req.Extra,
   241  			}
   242  			if req.EntID != nil {
   243  				id, err := uuid.Parse(req.GetEntID())
   244  				if err != nil {
   245  					return err
   246  				}
   247  				_req.EntID = &id
   248  			}
   249  			if req.CoinTypeID != nil {
   250  				id, err := uuid.Parse(req.GetCoinTypeID())
   251  				if err != nil {
   252  					return err
   253  				}
   254  				_req.CoinTypeID = &id
   255  			}
   256  			if req.FromAccountID != nil {
   257  				id, err := uuid.Parse(req.GetFromAccountID())
   258  				if err != nil {
   259  					return err
   260  				}
   261  				_req.FromAccountID = &id
   262  			}
   263  			if req.ToAccountID != nil {
   264  				id, err := uuid.Parse(req.GetToAccountID())
   265  				if err != nil {
   266  					return err
   267  				}
   268  				_req.ToAccountID = &id
   269  			}
   270  			if req.Amount != nil {
   271  				amount, err := decimal.NewFromString(req.GetAmount())
   272  				if err != nil {
   273  					return err
   274  				}
   275  				_req.Amount = &amount
   276  			}
   277  			if req.FeeAmount != nil {
   278  				amount, err := decimal.NewFromString(req.GetFeeAmount())
   279  				if err != nil {
   280  					return err
   281  				}
   282  				_req.FeeAmount = &amount
   283  			}
   284  			if req.State != nil {
   285  				switch req.GetState() {
   286  				case basetypes.TxState_TxStateCreated:
   287  				case basetypes.TxState_TxStateWait:
   288  				case basetypes.TxState_TxStateTransferring:
   289  				case basetypes.TxState_TxStateSuccessful:
   290  				case basetypes.TxState_TxStateFail:
   291  				default:
   292  					return fmt.Errorf("invalid txstate")
   293  				}
   294  				_req.State = req.State
   295  			}
   296  			if req.Type != nil {
   297  				switch req.GetType() {
   298  				case basetypes.TxType_TxWithdraw:
   299  				case basetypes.TxType_TxFeedGas:
   300  				case basetypes.TxType_TxPaymentCollect:
   301  				case basetypes.TxType_TxBenefit:
   302  				case basetypes.TxType_TxLimitation:
   303  				case basetypes.TxType_TxPlatformBenefit:
   304  				case basetypes.TxType_TxUserBenefit:
   305  				default:
   306  					return fmt.Errorf("invalid txtype")
   307  				}
   308  				_req.Type = req.Type
   309  			}
   310  			_reqs = append(_reqs, _req)
   311  		}
   312  		h.Reqs = _reqs
   313  		return nil
   314  	}
   315  }
   316  
   317  //nolint:gocyclo
   318  func WithConds(conds *npool.Conds) func(context.Context, *Handler) error {
   319  	return func(ctx context.Context, h *Handler) error {
   320  		h.Conds = &txcrud.Conds{}
   321  		if conds == nil {
   322  			return nil
   323  		}
   324  		if conds.EntID != nil {
   325  			id, err := uuid.Parse(conds.GetEntID().GetValue())
   326  			if err != nil {
   327  				return err
   328  			}
   329  			h.Conds.EntID = &cruder.Cond{
   330  				Op:  conds.GetEntID().GetOp(),
   331  				Val: id,
   332  			}
   333  		}
   334  		if conds.EntIDs != nil {
   335  			ids := []uuid.UUID{}
   336  			for _, id := range conds.GetEntIDs().GetValue() {
   337  				_id, err := uuid.Parse(id)
   338  				if err != nil {
   339  					return err
   340  				}
   341  				ids = append(ids, _id)
   342  			}
   343  			h.Conds.EntIDs = &cruder.Cond{
   344  				Op:  conds.GetEntIDs().GetOp(),
   345  				Val: ids,
   346  			}
   347  		}
   348  		if conds.CoinTypeID != nil {
   349  			id, err := uuid.Parse(conds.GetCoinTypeID().GetValue())
   350  			if err != nil {
   351  				return err
   352  			}
   353  			h.Conds.CoinTypeID = &cruder.Cond{
   354  				Op:  conds.GetCoinTypeID().GetOp(),
   355  				Val: id,
   356  			}
   357  		}
   358  		if conds.AccountID != nil {
   359  			id, err := uuid.Parse(conds.GetAccountID().GetValue())
   360  			if err != nil {
   361  				return err
   362  			}
   363  			h.Conds.AccountID = &cruder.Cond{
   364  				Op:  conds.GetAccountID().GetOp(),
   365  				Val: id,
   366  			}
   367  		}
   368  		if conds.AccountIDs != nil {
   369  			ids := []uuid.UUID{}
   370  			for _, id := range conds.GetAccountIDs().GetValue() {
   371  				_id, err := uuid.Parse(id)
   372  				if err != nil {
   373  					return err
   374  				}
   375  				ids = append(ids, _id)
   376  			}
   377  			h.Conds.AccountIDs = &cruder.Cond{
   378  				Op:  conds.GetAccountIDs().GetOp(),
   379  				Val: ids,
   380  			}
   381  		}
   382  		if conds.State != nil {
   383  			h.Conds.State = &cruder.Cond{
   384  				Op:  conds.GetState().GetOp(),
   385  				Val: basetypes.TxState(conds.GetState().GetValue()),
   386  			}
   387  		}
   388  		if conds.Type != nil {
   389  			h.Conds.Type = &cruder.Cond{
   390  				Op:  conds.GetType().GetOp(),
   391  				Val: basetypes.TxType(conds.GetType().GetValue()),
   392  			}
   393  		}
   394  		if conds.States != nil {
   395  			states := []basetypes.TxState{}
   396  			for _, state := range conds.GetStates().GetValue() {
   397  				states = append(states, basetypes.TxState(state))
   398  			}
   399  			h.Conds.States = &cruder.Cond{
   400  				Op:  conds.GetStates().GetOp(),
   401  				Val: states,
   402  			}
   403  		}
   404  		return nil
   405  	}
   406  }
   407  
   408  func WithOffset(offset int32) func(context.Context, *Handler) error {
   409  	return func(ctx context.Context, h *Handler) error {
   410  		h.Offset = offset
   411  		return nil
   412  	}
   413  }
   414  
   415  func WithLimit(limit int32) func(context.Context, *Handler) error {
   416  	return func(ctx context.Context, h *Handler) error {
   417  		if limit == 0 {
   418  			limit = constant.DefaultRowLimit
   419  		}
   420  		h.Limit = limit
   421  		return nil
   422  	}
   423  }