treasury.gno

3.41 Kb ยท 131 lines
  1package treasury
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/nt/avl"
  7	"gno.land/p/nt/avl/pager"
  8	"gno.land/p/nt/ufmt"
  9)
 10
 11var (
 12	ErrNoBankerProvided  = errors.New("no banker provided")
 13	ErrDuplicateBanker   = errors.New("duplicate banker")
 14	ErrBankerNotFound    = errors.New("banker not found")
 15	ErrSendPaymentFailed = errors.New("failed to send payment")
 16)
 17
 18// New creates a new Treasury instance with the given bankers.
 19func New(bankers []Banker) (*Treasury, error) {
 20	if len(bankers) == 0 {
 21		return nil, ErrNoBankerProvided
 22	}
 23
 24	// Create a new Treasury instance.
 25	treasury := &Treasury{bankers: avl.NewTree()}
 26
 27	// Register the bankers.
 28	for _, banker := range bankers {
 29		if treasury.bankers.Has(banker.ID()) {
 30			return nil, ufmt.Errorf("%v: %s", ErrDuplicateBanker, banker.ID())
 31		}
 32
 33		treasury.bankers.Set(
 34			banker.ID(),
 35			&bankerRecord{banker: banker},
 36		)
 37	}
 38
 39	// Register the Render routes.
 40	treasury.initRenderRouter()
 41
 42	return treasury, nil
 43}
 44
 45// Send sends a payment using the corresponding banker.
 46func (t *Treasury) Send(p Payment) error {
 47	// Get the banker record corresponding to this Payment.
 48	br, ok := t.bankers.Get(p.BankerID())
 49	if !ok {
 50		return ufmt.Errorf("%v: %s", ErrBankerNotFound, p.BankerID())
 51	}
 52	record := br.(*bankerRecord)
 53
 54	// Send the payment using the corresponding banker.
 55	if err := record.banker.Send(p); err != nil {
 56		return ufmt.Errorf("%v: %s", ErrSendPaymentFailed, err)
 57	}
 58
 59	// Add the payment to the history of the banker.
 60	record.history.Append(p)
 61
 62	return nil
 63}
 64
 65// History returns the payment history sent by the banker with the given ID.
 66// Payments are paginated, with the most recent payments first.
 67func (t *Treasury) History(
 68	bankerID string,
 69	pageNumber int,
 70	pageSize int,
 71) ([]Payment, error) {
 72	// Get the banker record corresponding to this ID.
 73	br, ok := t.bankers.Get(bankerID)
 74	if !ok {
 75		return nil, ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
 76	}
 77	history := br.(*bankerRecord).history
 78
 79	// Get the page of payments from the history.
 80	p := pager.NewPager(history.Tree(), pageSize, true)
 81	page := p.GetPage(pageNumber)
 82
 83	// Convert the items in the page to a slice of Payments.
 84	payments := make([]Payment, len(page.Items))
 85	for i := range page.Items {
 86		payments[i] = page.Items[i].Value.(Payment)
 87	}
 88
 89	return payments, nil
 90}
 91
 92// Balances returns the balances of the banker with the given ID.
 93func (t *Treasury) Balances(bankerID string) ([]Balance, error) {
 94	// Get the banker record corresponding to this ID.
 95	br, ok := t.bankers.Get(bankerID)
 96	if !ok {
 97		return nil, ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
 98	}
 99
100	// Get the balances from the banker.
101	return br.(*bankerRecord).banker.Balances(), nil
102}
103
104// Address returns the address of the banker with the given ID.
105func (t *Treasury) Address(bankerID string) (string, error) {
106	// Get the banker record corresponding to this ID.
107	br, ok := t.bankers.Get(bankerID)
108	if !ok {
109		return "", ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
110	}
111
112	// Get the address from the banker.
113	return br.(*bankerRecord).banker.Address(), nil
114}
115
116// HasBanker checks if a banker with the given ID is registered.
117func (t *Treasury) HasBanker(bankerID string) bool {
118	return t.bankers.Has(bankerID)
119}
120
121// ListBankerIDs returns a list of all registered banker IDs.
122func (t *Treasury) ListBankerIDs() []string {
123	var bankerIDs []string
124
125	t.bankers.Iterate("", "", func(bankerID string, _ any) bool {
126		bankerIDs = append(bankerIDs, bankerID)
127		return false
128	})
129
130	return bankerIDs
131}