-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathccapi.go
157 lines (133 loc) · 3.83 KB
/
ccapi.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
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
)
//URL_API main api url
const URL_API = "https://min-api.cryptocompare.com/data/"
//COINLIST url api
const COINLIST = "https://www.cryptocompare.com/api/data/coinlist/"
type coinListResp struct {
Response string `json:"Response"`
Message string `json:"Message"`
BaseImageURL string `json:"BaseImageUrl"`
BaseLinkURL string `json:"BaseLinkUrl"`
Data map[string]CoinInfo `json:"Data"`
Type int `json:"Type"`
}
//Coins Coins map used to receive json resp from the api
type Coins map[string]CoinInfo
//CoinInfo is struct for CryptoCompare Api
type CoinInfo struct {
ID string `json:"Id"`
URL string `json:"Url"`
ImageURL string `json:"ImageUrl"`
Name string `json:"Name"`
CoinName string `json:"CoinName"`
FullName string `json:"FullName"`
Algorithm string `json:"Algorithm"`
ProofType string `json:"ProofType"`
FullyPremined string `json:"FullyPremined"`
TotalCoinsFreeFloat string `json:"TotalCoinsFreeFloat"`
TotalCoinSupply string `json:"TotalCoinSupply"`
PreMinedValue string `json:"PreMinedValue"`
SortOrder string `json:"SortOrder"`
}
//PriceResult is used for fetching price data from the api
type PriceResult map[string]map[string]float64
//GetCoinList fetches data for all coins from the API
func GetCoinList() (Coins, error) {
resp, err := makeReq(COINLIST)
if err != nil {
log.Println(err)
}
var data coinListResp
err = json.Unmarshal(resp, &data)
if err != nil {
log.Println(err)
}
return data.Data, err
}
//SyncPortfolio fetch prices from api and calculate total portfolio value
func SyncPortfolio(assets Assets, coins Coins) (portfolio Assets, err error) {
//Check portfolio for invalid coins/entries
portfolio = checkPortfolio(assets, coins)
//storing coin's ticker in an array
var a []string
for _, asset := range portfolio {
a = append(a, asset.Ticker)
}
//join into a string
from := strings.Join(a, ",")
to := "BTC," + Config.BaseCurrency
url := URL_API + "pricemulti?fsyms=" + from + "&tsyms=" + to
//get latest prices
currentPrices, err := getCurrentPrice(url)
if err != nil {
log.Println("SyncPortfolio(): ", err)
return
}
for i, v := range portfolio {
portfolio[i].BTCPrice = currentPrices[v.Ticker]["BTC"]
portfolio[i].FiatPrice = currentPrices[v.Ticker][Config.BaseCurrency]
}
return
}
//CheckCoins protfolio input
func checkPortfolio(assets Assets, coins Coins) (newList Assets) {
for i, asset := range assets {
//check if asset is in the coinlist
if coins[asset.Ticker].Name != "" {
//if its in the list fetch the full Name
assets[i].Name = coins[assets[i].Ticker].CoinName
newList = append(newList, assets[i])
} else {
log.Println("Asset not found in Coinlist: ", asset.Ticker)
}
}
log.Println("Checking coinlist completed.")
return
}
func getCurrentPrice(url string) (map[string]map[string]float64, error) {
resp, err := makeReq(url)
if err != nil {
log.Println("getCurrentPrice(): ", err)
}
var data PriceResult
err = json.Unmarshal(resp, &data)
if err != nil {
log.Println("getCurrentPrice(): ", err)
}
return data, err
}
func doReq(req *http.Request) ([]byte, error) {
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Println(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
}
if 200 != resp.StatusCode {
return nil, fmt.Errorf("%s", body)
}
return body, nil
}
func makeReq(url string) ([]byte, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Println(err)
}
resp, err := doReq(req)
if err != nil {
log.Println(err)
}
return resp, err
}