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

     1  package balance
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/s7techlab/cckit/router"
     8  	"github.com/s7techlab/cckit/state"
     9  )
    10  
    11  type Store struct {
    12  	state state.GetSettable
    13  }
    14  
    15  func NewStore(ctx router.Context) *Store {
    16  	return &Store{
    17  		state: State(ctx),
    18  	}
    19  }
    20  
    21  func (s *Store) Get(address string, token []string) (*Balance, error) {
    22  	balance, err := s.state.Get(&BalanceId{Address: address, Token: token}, &Balance{})
    23  	if err != nil {
    24  
    25  		if strings.Contains(err.Error(), state.ErrKeyNotFound.Error()) {
    26  			// default zero balance even if no Balance state entry for account exists
    27  			return &Balance{
    28  				Address: address,
    29  				Amount:  0,
    30  			}, nil
    31  		}
    32  		return nil, err
    33  	}
    34  
    35  	return balance.(*Balance), nil
    36  }
    37  
    38  func (s *Store) set(address string, token []string, amount uint64) error {
    39  	balance := &Balance{
    40  		Address: address,
    41  		Token:   token,
    42  		Amount:  amount,
    43  	}
    44  
    45  	return s.state.Put(balance)
    46  }
    47  
    48  func (s *Store) Add(address string, token []string, amount uint64) error {
    49  	balance, err := s.Get(address, token)
    50  	if err != nil {
    51  		return nil
    52  	}
    53  
    54  	err = s.set(address, token, balance.Amount+amount)
    55  	if err != nil {
    56  		return fmt.Errorf(`add to=%s: %w`, address, err)
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  func (s *Store) Sub(address string, token []string, amount uint64) error {
    63  	balance, err := s.Get(address, token)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	if balance.Amount < amount {
    69  		return fmt.Errorf(`subtract from=%s: %w`, address, ErrAmountInsuficcient)
    70  	}
    71  
    72  	err = s.set(address, token, balance.Amount-amount)
    73  	if err != nil {
    74  		return fmt.Errorf(`subtract from=%s: %w`, address, err)
    75  	}
    76  
    77  	return nil
    78  }
    79  
    80  func (s *Store) Transfer(senderAddress, recipientAddress string, tokenId []string, amount uint64) error {
    81  	// subtract from sender balance
    82  	if err := s.Sub(senderAddress, tokenId, amount); err != nil {
    83  		return fmt.Errorf(`transfer: %w`, err)
    84  	}
    85  	// add to recipient balance
    86  	if err := s.Add(recipientAddress, tokenId, amount); err != nil {
    87  		return fmt.Errorf(`transfer: %w`, err)
    88  	}
    89  	return nil
    90  }