-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathexternal.go
109 lines (88 loc) · 3.04 KB
/
external.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
package data
import (
"context"
"errors"
"time"
"github.com/code-payments/code-server/pkg/code/data/currency"
currency_lib "github.com/code-payments/code-server/pkg/currency"
"github.com/code-payments/code-server/pkg/currency/coingecko"
"github.com/code-payments/code-server/pkg/currency/fixer"
"github.com/code-payments/code-server/pkg/metrics"
)
const (
webProviderMetricsName = "data.web_provider"
)
type WebData interface {
// Currency
// --------------------------------------------------------------------------------
GetCurrentExchangeRatesFromExternalProviders(ctx context.Context) (*currency.MultiRateRecord, error)
GetPastExchangeRatesFromExternalProviders(ctx context.Context, t time.Time) (*currency.MultiRateRecord, error)
}
type WebProvider struct {
coinGecko currency_lib.Client
fixer currency_lib.Client
}
func NewWebProvider(configProvider ConfigProvider) (WebData, error) {
conf := configProvider()
return &WebProvider{
coinGecko: coingecko.NewClient(),
fixer: fixer.NewClient(conf.fixerApiKey.Get(context.Background())),
}, nil
}
// Currency
// --------------------------------------------------------------------------------
func (dp *WebProvider) GetCurrentExchangeRatesFromExternalProviders(ctx context.Context) (*currency.MultiRateRecord, error) {
tracer := metrics.TraceMethodCall(ctx, webProviderMetricsName, "GetCurrentExchangeRatesFromExternalProviders")
defer tracer.End()
coinGeckoData, err := dp.coinGecko.GetCurrentRates(ctx, string(currency_lib.KIN))
if err != nil {
return nil, err
}
fixerData, err := dp.fixer.GetCurrentRates(ctx, string(currency_lib.USD))
if err != nil {
return nil, err
}
rates, err := computeAllKinExchangeRates(coinGeckoData.Rates, fixerData.Rates)
if err != nil {
return nil, err
}
return ¤cy.MultiRateRecord{
Time: time.Now(),
Rates: rates,
}, nil
}
func (dp *WebProvider) GetPastExchangeRatesFromExternalProviders(ctx context.Context, t time.Time) (*currency.MultiRateRecord, error) {
tracer := metrics.TraceMethodCall(ctx, webProviderMetricsName, "GetPastExchangeRatesFromExternalProviders")
defer tracer.End()
coinGeckoData, err := dp.coinGecko.GetHistoricalRates(ctx, string(currency_lib.KIN), t.UTC())
if err != nil {
return nil, err
}
fixerData, err := dp.fixer.GetHistoricalRates(ctx, string(currency_lib.USD), t.UTC())
if err != nil {
return nil, err
}
rates, err := computeAllKinExchangeRates(coinGeckoData.Rates, fixerData.Rates)
if err != nil {
return nil, err
}
return ¤cy.MultiRateRecord{
Time: coinGeckoData.Timestamp,
Rates: rates,
}, nil
}
func computeAllKinExchangeRates(kinRates map[string]float64, usdRates map[string]float64) (map[string]float64, error) {
kinToUsd, ok := kinRates[string(currency_lib.USD)]
if !ok {
return nil, errors.New("kin to usd rate missing")
}
for symbol, usdRate := range usdRates {
// Trust the source of the crypto rate when available
if _, ok := kinRates[symbol]; ok {
continue
}
kinExchangeRate := usdRate * kinToUsd
kinRates[symbol] = kinExchangeRate
}
return kinRates, nil
}