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}