github.com/diadata-org/diadata@v1.4.593/pkg/dia/ApiClient.go (about) 1 package dia 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "os/user" 10 "time" 11 12 "github.com/diadata-org/diadata/pkg/utils" 13 log "github.com/sirupsen/logrus" 14 "github.com/tkanos/gonfig" 15 ) 16 17 type Client struct { 18 config *ConfigApi 19 token string 20 lastSupplyUpdateTime time.Time 21 lastSupplyUpdateValue float64 22 url string 23 } 24 25 type Symbols struct { 26 Symbols []string 27 } 28 29 const BaseUrl string = "https://api.diadata.org/" 30 31 type response struct { 32 Token string 33 } 34 35 func (c *Client) refresh() error { 36 37 url := c.url + "auth/refresh_token" 38 39 req, err := http.NewRequest("GET", url, nil) //nolint:noctx 40 if err != nil { 41 return err 42 } 43 44 bytes, err := c.DoRequest(req, false) 45 if err != nil { 46 return err 47 } 48 var r response 49 err = json.Unmarshal(bytes, &r) 50 if err != nil { 51 fmt.Println("error:", err) 52 return err 53 } 54 c.token = r.Token 55 return nil 56 } 57 58 func (c *Client) login() error { 59 60 client := &http.Client{} 61 62 type login struct { 63 Username string 64 Password string 65 } 66 url := c.url + "login" 67 68 jsonStr, err := json.Marshal(&login{ 69 Username: c.config.ApiKey, 70 Password: c.config.SecretKey, 71 }) 72 73 if err != nil { 74 log.Println(err) 75 return err 76 } 77 78 req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) //nolint:noctx 79 if err != nil { 80 return err 81 } 82 83 req.Header.Set("Content-Type", "application/json") 84 85 resp, err := client.Do(req) 86 if err != nil { 87 log.Println(err) 88 return err 89 } 90 defer func() { 91 err = resp.Body.Close() 92 if err != nil { 93 log.Error(err) 94 } 95 }() 96 97 body, _ := ioutil.ReadAll(resp.Body) 98 99 var r response 100 err = json.Unmarshal(body, &r) 101 if err != nil { 102 log.Println(err) 103 return err 104 } 105 106 c.token = r.Token 107 108 return nil 109 } 110 111 func GetSupply(symbol string) (*Supply, error) { 112 url := BaseUrl + "/v1/supply/" + symbol 113 log.Println("Checking supply for", symbol, "on", url) 114 115 contents, _, err := utils.GetRequest(url) 116 if err != nil { 117 return nil, err 118 } 119 120 log.Debugf("%s\n", string(contents)) 121 var b Supply 122 err = b.UnmarshalBinary(contents) 123 if err != nil { 124 return nil, err 125 } 126 127 log.Debug("got", b) 128 return &b, nil 129 130 } 131 132 // TODO remove URL 133 func GetSymbolsList(url string) ([]string, error) { 134 log.Println("getSymbolList") 135 136 contents, _, err := utils.GetRequest(url + "/v1/symbols") 137 if err != nil { 138 return nil, err 139 } 140 141 log.Debugf("%s\n", string(contents)) 142 var b Symbols 143 144 err = json.Unmarshal(contents, &b) 145 146 if err != nil { 147 return nil, err 148 } 149 150 return b.Symbols, nil 151 } 152 153 func GetConfigApi() *ConfigApi { 154 var c ConfigApi 155 if utils.Getenv("USE_ENV","false") == "true" { 156 c = ConfigApi{ 157 ApiKey: utils.Getenv("DIADATA_API_KEY", ""), 158 SecretKey: utils.Getenv("DIADATA_SECRET_KEY", ""), 159 } 160 } else { 161 configFile := "/run/secrets/api_diadata" 162 err := gonfig.GetConf(configFile, &c) 163 if err != nil { 164 log.Errorln("GetConfigApi", err) 165 usr, _ := user.Current() 166 dir := usr.HomeDir 167 configFile = dir + "/secrets/api_diadata.json" 168 err = gonfig.GetConf(configFile, &c) 169 } 170 if err != nil { 171 log.Println(err) 172 return nil 173 } else { 174 log.Println("Loaded secret in", configFile) 175 } 176 } 177 return &c 178 } 179 180 func NewClientWithUrl(config *ConfigApi, url string) *Client { 181 c := &Client{ 182 config: config, 183 token: "", 184 url: url, 185 } 186 err := c.login() 187 if err != nil { 188 log.Println(err) 189 return nil 190 } 191 return c 192 } 193 194 func NewClient(config *ConfigApi) *Client { 195 c := &Client{ 196 config: config, 197 token: "", 198 url: BaseUrl, 199 } 200 err := c.login() 201 if err != nil { 202 log.Println(err) 203 return nil 204 } 205 return c 206 } 207 208 func (c *Client) DoRequest(req *http.Request, refresh bool) ([]byte, error) { 209 210 req.Header.Set("Content-Type", "application/json") 211 req.Header.Set("Authorization", "Bearer "+c.token) 212 213 client := &http.Client{} 214 resp, err := client.Do(req) 215 if err != nil { 216 return nil, err 217 } 218 defer func() { 219 err = resp.Body.Close() 220 if err != nil { 221 log.Error(err) 222 } 223 }() 224 225 body, err := ioutil.ReadAll(resp.Body) 226 if err != nil { 227 return nil, err 228 } 229 230 log.Debug("StatusCode", resp.StatusCode) 231 232 if resp.StatusCode != 200 { 233 234 if refresh { 235 if resp.StatusCode == 401 { 236 err = c.refresh() 237 if err != nil { 238 err = c.login() 239 if err == nil { 240 return c.DoRequest(req, true) 241 } 242 } 243 } 244 } 245 return nil, fmt.Errorf("%s", body) 246 } 247 return body, nil 248 } 249 250 func (c *Client) SendSupplyWithForceOption(s *Supply, force bool) error { 251 lastUpdate := time.Since(c.lastSupplyUpdateTime) 252 if lastUpdate.Hours() >= 1.0 || c.lastSupplyUpdateValue != s.CirculatingSupply || force { 253 c.lastSupplyUpdateTime = s.Time 254 c.lastSupplyUpdateValue = s.CirculatingSupply 255 return c.sendSupply(s) 256 } else { 257 log.Println("Skipping sending to API", s, "last update:", lastUpdate) 258 return nil 259 } 260 } 261 262 func (c *Client) SendSupply(s *Supply) error { 263 return c.SendSupplyWithForceOption(s, false) 264 } 265 266 func (c *Client) sendSupply(s *Supply) error { 267 268 jsonStr, err := json.Marshal(s) 269 if err != nil { 270 return err 271 } 272 273 url := c.url + "v1/supply" 274 275 req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr)) //nolint:noctx 276 if err != nil { 277 return err 278 } 279 280 _, err = c.DoRequest(req, true) 281 if err != nil { 282 log.Println("Error: SendSupply", err) 283 return err 284 } 285 286 return nil 287 }