func (s *Service) TotalReceived(peer swarm.Address) (totalReceived *big.Int, err error) {
	chequebookAddress, known, err := s.addressbook.Chequebook(peer)
	if err != nil {
		return nil, err
	}
	if !known {
		return nil, settlement.ErrPeerNoSettlements
	}
	cheque, err := s.chequeStore.LastCheque(chequebookAddress)
	if err != nil {
		if err == chequebook.ErrNoCheque {
			return nil, settlement.ErrPeerNoSettlements
		}
		return nil, err
	}
	return cheque.CumulativePayout, nil
}
TotalReceived returns the total amount received from a peer
package swap
import (
	"context"
	"errors"
	"fmt"
	"math/big"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethsana/sana/pkg/logging"
	"github.com/ethsana/sana/pkg/settlement"
	"github.com/ethsana/sana/pkg/settlement/swap/chequebook"
	"github.com/ethsana/sana/pkg/settlement/swap/swapprotocol"
	"github.com/ethsana/sana/pkg/storage"
	"github.com/ethsana/sana/pkg/swarm"
)
var (
	ErrWrongChequebook = errors.New("wrong chequebook")
	ErrUnknownBeneficary = errors.New("unknown beneficiary for peer")
	ErrChequeValueTooLow = errors.New("cheque value too low")
)
type Interface interface {
	settlement.Interface
	LastSentCheque(peer swarm.Address) (*chequebook.SignedCheque, error)
	LastSentCheques() (map[string]*chequebook.SignedCheque, error)
	LastReceivedCheque(peer swarm.Address) (*chequebook.SignedCheque, error)
	LastReceivedCheques() (map[string]*chequebook.SignedCheque, error)
	CashCheque(ctx context.Context, peer swarm.Address) (common.Hash, error)
	CashoutStatus(ctx context.Context, peer swarm.Address) (*chequebook.CashoutStatus, error)
}
type Service struct {
	proto       swapprotocol.Interface
	logger      logging.Logger
	store       storage.StateStorer
	accounting  settlement.Accounting
	metrics     metrics
	chequebook  chequebook.Service
	chequeStore chequebook.ChequeStore
	cashout     chequebook.CashoutService
	addressbook Addressbook
	networkID   uint64
}
func New(proto swapprotocol.Interface, logger logging.Logger, store storage.StateStorer, chequebook chequebook.Service, chequeStore chequebook.ChequeStore, addressbook Addressbook, networkID uint64, cashout chequebook.CashoutService, accounting settlement.Accounting) *Service {
	return &Service{
		proto:       proto,
		logger:      logger,
		store:       store,
		metrics:     newMetrics(),
		chequebook:  chequebook,
		chequeStore: chequeStore,
		addressbook: addressbook,
		networkID:   networkID,
		cashout:     cashout,
		accounting:  accounting,
	}
}
func (s *Service) ReceiveCheque(ctx context.Context, peer swarm.Address, cheque *chequebook.SignedCheque, exchangeRate, deduction *big.Int) (err error) {
	expectedChequebook, known, err := s.addressbook.Chequebook(peer)
	if err != nil {
		return err
	}
	if known && expectedChequebook != cheque.Chequebook {
		return ErrWrongChequebook
	}
	receivedAmount, err := s.chequeStore.ReceiveCheque(ctx, cheque, exchangeRate, deduction)
	if err != nil {
		s.metrics.ChequesRejected.Inc()
		return fmt.Errorf("rejecting cheque: %w", err)
	}
	if deduction.Cmp(big.NewInt(0)) > 0 {
		err = s.addressbook.AddDeductionFor(peer)
		if err != nil {
			return err
		}
	}
	decreasedAmount := new(big.Int).Sub(receivedAmount, deduction)
	amount := new(big.Int).Div(decreasedAmount, exchangeRate)
	if !known {
		err = s.addressbook.PutChequebook(peer, cheque.Chequebook)
		if err != nil {
			return err
		}
	}
	tot, _ := big.NewFloat(0).SetInt(receivedAmount).Float64()
	s.metrics.TotalReceived.Add(tot)
	s.metrics.ChequesReceived.Inc()
	return s.accounting.NotifyPaymentReceived(peer, amount)
}
func (s *Service) Pay(ctx context.Context, peer swarm.Address, amount *big.Int) {
	var err error
	defer func() {
		if err != nil {
			s.accounting.NotifyPaymentSent(peer, amount, err)
		}
	}()
	beneficiary, known, err := s.addressbook.Beneficiary(peer)
	if err != nil {
		return
	}
	if !known {
		err = ErrUnknownBeneficary
		return
	}
	balance, err := s.proto.EmitCheque(ctx, peer, beneficiary, amount, s.chequebook.Issue)
	if err != nil {
		return
	}
	bal, _ := big.NewFloat(0).SetInt(balance).Float64()
	s.metrics.AvailableBalance.Set(bal)
	s.accounting.NotifyPaymentSent(peer, amount, nil)
	amountFloat, _ := big.NewFloat(0).SetInt(amount).Float64()
	s.metrics.TotalSent.Add(amountFloat)
	s.metrics.ChequesSent.Inc()
}
func (s *Service) SetAccounting(accounting settlement.Accounting) {
	s.accounting = accounting
}
func (s *Service) TotalSent(peer swarm.Address) (totalSent *big.Int, err error) {
	beneficiary, known, err := s.addressbook.Beneficiary(peer)
	if err != nil {
		return nil, err
	}
	if !known {
		return nil, settlement.ErrPeerNoSettlements
	}
	cheque, err := s.chequebook.LastCheque(beneficiary)
	if err != nil {
		if err == chequebook.ErrNoCheque {
			return nil, settlement.ErrPeerNoSettlements
		}
		return nil, err
	}
	return cheque.CumulativePayout, nil
}