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 }