-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
190 lines (162 loc) · 5.62 KB
/
main.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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package main
import (
"sync"
"github.com/commoddity/bank-informer/client"
"github.com/commoddity/bank-informer/cmc"
"github.com/commoddity/bank-informer/csv"
"github.com/commoddity/bank-informer/env"
"github.com/commoddity/bank-informer/eth"
"github.com/commoddity/bank-informer/log"
"github.com/commoddity/bank-informer/persistence"
"github.com/commoddity/bank-informer/pokt"
"github.com/commoddity/bank-informer/setup"
"github.com/joho/godotenv"
)
const (
// Required env vars
grovePortalAppID = "GROVE_PORTAL_APP_ID"
groveSecretKey = "GROVE_SECRET_KEY"
ethWalletAddressEnv = "ETH_WALLET_ADDRESS"
poktWalletAddressEnv = "POKT_WALLET_ADDRESS"
cmcAPIKeyEnv = "CMC_API_KEY"
// Optional env vars
cryptoFiatConversionEnv = "CRYPTO_FIAT_CONVERSION"
convertCurrenciesEnv = "CONVERT_CURRENCIES"
cryptoValuesEnv = "CRYPTO_VALUES"
// Default currency values
defaultConvertCurrencies = "USD"
defaultCryptoFiatConversion = "USD"
defaultCryptoValues = "USDC,ETH,POKT"
)
type options struct {
ethConfig eth.Config
poktConfig pokt.Config
cmcConfig cmc.Config
cryptoFiatConversion string
convertCurrencies []string
cryptoValues []string
}
func gatherOptions() options {
// Validate that all converted currencies are valid
convertCurrencies := env.GetStringSlice(convertCurrenciesEnv, defaultConvertCurrencies)
for _, currency := range convertCurrencies {
if err := log.ValidateCurrencySymbol(currency, convertCurrenciesEnv); err != nil {
panic(err)
}
}
// Validate that cryptoFiatConversion is valid
cryptoFiatConversion := env.GetString(cryptoFiatConversionEnv, defaultCryptoFiatConversion)
if err := log.ValidateCurrencySymbol(cryptoFiatConversion, cryptoFiatConversionEnv); err != nil {
panic(err)
}
// Validate that Grove Portal App ID is valid
grovePortalAppID := env.MustGetString(grovePortalAppID)
if err := pokt.ValidatePortalAppID(grovePortalAppID); err != nil {
panic(err)
}
// Validate that Grove Secret Key is valid
groveSecretKey := env.GetString(groveSecretKey, "")
if groveSecretKey != "" {
if err := pokt.ValidateSecretKey(groveSecretKey); err != nil {
panic(err)
}
}
// Validate that ETH wallet address is valid
ethWalletAddress := env.MustGetString(ethWalletAddressEnv)
if err := eth.ValidateETHWalletAddress(ethWalletAddress); err != nil {
panic(err)
}
return options{
ethConfig: eth.Config{
PortalAppID: grovePortalAppID,
SecretKey: groveSecretKey,
ETHWalletAddress: ethWalletAddress,
},
poktConfig: pokt.Config{
PortalAppID: grovePortalAppID,
SecretKey: groveSecretKey,
POKTWalletAddress: env.MustGetString(poktWalletAddressEnv),
},
cmcConfig: cmc.Config{
CmcAPIKey: env.MustGetString(cmcAPIKeyEnv),
ConvertCurrencies: convertCurrencies,
},
cryptoFiatConversion: cryptoFiatConversion,
convertCurrencies: convertCurrencies,
cryptoValues: env.GetStringSlice(cryptoValuesEnv, defaultCryptoValues),
}
}
func init() {
// Load .env file from the bank-informer dir in the user's home directory
_ = godotenv.Load(env.EnvPath)
}
// This program retrieves and logs the balances of ETH and POKT wallets.
// It also fetches the exchange rates for a list of currencies and calculates
// the fiat values for each balance. The balances, fiat values, and exchange rates
// are then logged for further use.
func main() {
// Setup .env file if it doesn't exist
setup.Start()
// Gather options from env vars
opts := gatherOptions()
// Initialize persistence module
persistence := persistence.NewPersistence()
defer persistence.Close()
// Add 1 to chanLength to account for the call to get exchange rates
chanLength := len(opts.cryptoValues) + len(opts.convertCurrencies)
progressChan := make(chan string, chanLength)
// Initialize logger
logger := log.New(log.Config{
CryptoFiatConversion: opts.cryptoFiatConversion,
ConvertCurrencies: opts.convertCurrencies,
CryptoValues: opts.cryptoValues,
}, persistence, progressChan, chanLength)
// Start the progress bar in a goroutine
go logger.RunProgressBar()
// Create a map to store balances
balances := make(map[string]float64)
for _, crypto := range opts.cryptoValues {
balances[crypto] = 0
}
// Create mutex and wait group
var mu sync.Mutex
var wg sync.WaitGroup
// Create clients
httpClient := client.New()
ethClient := eth.NewClient(opts.ethConfig, httpClient, progressChan, &mu, &wg)
poktClient := pokt.NewClient(opts.poktConfig, httpClient, progressChan, &mu, &wg)
cmcClient := cmc.NewClient(opts.cmcConfig, httpClient, progressChan, &mu, &wg)
// Retrieve and store ERC20 wallet balances through Grove Portal
err := ethClient.GetETHWalletBalances(balances)
if err != nil {
panic(err)
}
// Retrieve and store POKT wallet balance through Grove Portal
err = poktClient.GetWalletBalance(balances)
if err != nil {
panic(err)
}
// Retrieve and store the exchange rates for the current currency
exchangeRates, err := cmcClient.GetAllExchangeRates(balances)
if err != nil {
panic(err)
}
// Wait for all goroutines to finish
wg.Wait()
// Close the progress bar channel
close(progressChan)
// Calculate the fiat values for each balance
fiatValues := cmcClient.GetFiatValues(balances, exchangeRates)
// Log the balances, fiat values, and exchange rates
logger.LogBalances(balances, fiatValues, exchangeRates)
// Write the balances, fiat values, and exchange rates to a CSV file
err = csv.WriteCryptoValuesToCSV(persistence, opts.cryptoValues)
if err != nil {
panic(err)
}
// Clear BadgerDB of old entries (older than 72 hours)
err = persistence.ClearOldEntries()
if err != nil {
panic(err)
}
}