github.com/s7techlab/cckit@v0.10.5/examples/token/service/allowance/store.go (about)

     1  package allowance
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/s7techlab/cckit/examples/token/service/balance"
     8  	"github.com/s7techlab/cckit/router"
     9  	"github.com/s7techlab/cckit/state"
    10  )
    11  
    12  type Store struct {
    13  	state state.GetSettable
    14  	path  []string // token path
    15  }
    16  
    17  func NewStore(ctx router.Context) *Store {
    18  	return &Store{
    19  		state: State(ctx),
    20  	}
    21  }
    22  
    23  func (s *Store) Get(ownerAddress, spenderAddress string, token []string) (*Allowance, error) {
    24  	allowance, err := s.state.Get(&AllowanceId{
    25  		OwnerAddress:   ownerAddress,
    26  		SpenderAddress: spenderAddress,
    27  		Token:          token}, &Allowance{})
    28  	if err != nil {
    29  		if errors.Is(err, state.ErrKeyNotFound) {
    30  			return &Allowance{
    31  				OwnerAddress:   ownerAddress,
    32  				SpenderAddress: spenderAddress,
    33  				Token:          token,
    34  				Amount:         0,
    35  			}, nil
    36  		}
    37  		return nil, fmt.Errorf(`get allowance: %w`, err)
    38  	}
    39  
    40  	return allowance.(*Allowance), nil
    41  }
    42  
    43  func (s *Store) Set(ownerAddress, spenderAddress string, token []string, amount uint64) (*Allowance, error) {
    44  	allowance := &Allowance{
    45  		OwnerAddress:   ownerAddress,
    46  		SpenderAddress: spenderAddress,
    47  		Token:          token,
    48  		Amount:         amount,
    49  	}
    50  
    51  	if err := s.state.Put(allowance); err != nil {
    52  		return nil, fmt.Errorf(`set allowance: %w`, err)
    53  	}
    54  
    55  	return allowance, nil
    56  }
    57  
    58  func (s *Store) Sub(ownerAddress, spenderAddress string, token []string, amount uint64) (*Allowance, error) {
    59  	allowance, err := s.Get(ownerAddress, spenderAddress, token)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	if allowance.Amount < amount {
    65  		return nil, balance.ErrAmountInsuficcient
    66  	}
    67  
    68  	return s.Set(ownerAddress, spenderAddress, token, allowance.Amount-amount)
    69  }