/
datasource.go
91 lines (66 loc) · 2.2 KB
/
datasource.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
package utils
import (
"context"
"fmt"
"io"
"net/http"
"net/url"
"github.com/tidwall/gjson"
)
type ExternalDataSoure interface {
Price(string) (float64, error)
}
type Coingecko struct {
apiKey string
assetsMapping map[string]string // key blockchain+address value coingecko name
}
func NewCoinGeckoProvider(apiKey string, assetsMapping map[string]string) *Coingecko {
return &Coingecko{apiKey: apiKey, assetsMapping: assetsMapping}
}
func (cg *Coingecko) Price(assetName string) (float64, error) {
cgName := cg.assetsMapping[assetName]
url := "https://pro-api.coingecko.com/api/v3/simple/price?ids=" + cgName + "&vs_currencies=usd&x_cg_pro_api_key=" + cg.apiKey
response, err := http.Get(url)
if err != nil {
return 0.0, err
}
defer response.Body.Close()
if 200 != response.StatusCode {
return 0.0, fmt.Errorf("Error on coingecko API call with return code %d", response.StatusCode)
}
contents, err := io.ReadAll(response.Body)
if err != nil {
return 0.0, err
}
price := gjson.Get(string(contents), cgName+".usd").Float()
return price, nil
}
// 5655df14-0213-429e-b375-51d338e8c79f
type CoinMarketCap struct {
apiKey string
assetsMapping map[string]string // key blockchain+address value CoinMarketCap name
}
func NewCoinMarketCapProvider(apiKey string, assetsMapping map[string]string) *CoinMarketCap {
return &CoinMarketCap{apiKey: apiKey, assetsMapping: assetsMapping}
}
func (cg *CoinMarketCap) Price(assetName string) (float64, error) {
cmcName := cg.assetsMapping[assetName]
urls := "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest"
req, err := http.NewRequestWithContext(context.Background(), "GET", urls, nil)
if err != nil {
return 0.0, err
}
req.Header.Add("X-CMC_PRO_API_KEY", cg.apiKey)
q := url.Values{}
q.Add("symbol", cmcName)
req.URL.RawQuery = q.Encode()
response, statusCode, err := HTTPRequest(req)
if err != nil {
return 0.0, fmt.Errorf("Error on coinmarketcap API call with return code %d", statusCode)
}
if 200 != statusCode {
return 0.0, fmt.Errorf("Error on coinmarketcap API call with return code %d", statusCode)
}
price := gjson.Get(string(response), "data."+cmcName+".0.quote.USD.price").Float()
return price, nil
}