-
Notifications
You must be signed in to change notification settings - Fork 0
/
handle_periodic_operations.go
96 lines (81 loc) · 2.5 KB
/
handle_periodic_operations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package pricefeed
import (
"fmt"
"math"
"github.com/go-co-op/gocron"
"github.com/rs/zerolog/log"
"github.com/forbole/soljuno/apis/coingecko"
dbtypes "github.com/forbole/soljuno/db/types"
"github.com/forbole/soljuno/modules/utils"
)
// RegisterPeriodicOperations implements modules.PeriodicOperationsModule
func (m *Module) RegisterPeriodicOperations(scheduler *gocron.Scheduler) error {
log.Debug().Str("module", "pricefeed").Msg("setting up periodic tasks")
// Fetch prices of tokens in 30 seconds each
if _, err := scheduler.Every(30).Second().Do(func() {
utils.WatchMethod(m, m.RunPeriodicOperations)
}); err != nil {
return fmt.Errorf("error while setting up pricefeed period operations: %s", err)
}
return nil
}
func (m *Module) RunPeriodicOperations() error {
return m.updatePrice()
}
// getTokenPrices gets the token prices in the database from coingecko
func (m *Module) getTokenPrices() ([]dbtypes.TokenPriceRow, error) {
units, err := m.db.GetTokenUnits()
if err != nil {
return nil, fmt.Errorf("error while getting token units: %s", err)
}
// Find the id of the coins
var ids []string
for _, unit := range units {
// Skip the token if the price id is empty
if unit.PriceID == "" {
continue
}
ids = append(ids, unit.PriceID)
}
if len(ids) == 0 {
return nil, fmt.Errorf("no traded tokens found")
}
// Get the tokens prices
prices, err := m.client.GetTokensPrices(ids)
if err != nil {
return nil, fmt.Errorf("error while getting tokens prices: %s", err)
}
return convertCoingeckoPrices(prices), err
}
// updatePrice fetch total amount of coins in the system from RPC and store it into database
func (m *Module) updatePrice() error {
log.Debug().
Str("module", "pricefeed").
Str("operation", "pricefeed").
Msg("getting token price and market cap")
prices, err := m.getTokenPrices()
if err != nil {
return fmt.Errorf("error while getting token prices")
}
// Save the token prices
err = m.db.SaveTokenPrices(prices)
if err != nil {
return fmt.Errorf("error while saving token prices: %s", err)
}
return nil
}
// convertCoingeckoPrices converts the MarketTicker list into TokenPriceRow list
func convertCoingeckoPrices(prices []coingecko.MarketTicker) []dbtypes.TokenPriceRow {
tokenPrices := make([]dbtypes.TokenPriceRow, len(prices))
for i, price := range prices {
tokenPrices[i] = dbtypes.NewTokenPriceRow(
price.ID,
price.CurrentPrice,
int64(math.Trunc(price.MarketCap)),
price.Symbol,
price.LastUpdated,
price.Volume,
)
}
return tokenPrices
}