github.com/0chain/gosdk@v1.17.11/core/tokenrate/coinmarketcap.go (about) 1 package tokenrate 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "fmt" 8 "net/http" 9 "os" 10 "strconv" 11 "strings" 12 13 "github.com/0chain/gosdk/core/resty" 14 ) 15 16 type coinmarketcapQuoteQuery struct { 17 APIKey string 18 } 19 20 // js call is unsupported for coinmarketcap api due to core issue 21 // https://coinmarketcap.com/api/documentation/v1/#section/Quick-Start-Guide 22 // Note: Making HTTP requests on the client side with Javascript is currently prohibited through CORS configuration. This is to protect your API Key which should not be visible to users of your application so your API Key is not stolen. Secure your API Key by routing calls through your own backend service. 23 func createCoinmarketcapQuoteQuery() quoteQuery { 24 25 coinmarketcapAPIKEY, ok := os.LookupEnv("COINMARKETCAP_API_KEY") 26 if !ok { 27 coinmarketcapAPIKEY = "7e386213-56ef-4a7e-af17-806496c20d3b" 28 } 29 30 return &coinmarketcapQuoteQuery{ 31 APIKey: coinmarketcapAPIKEY, 32 } 33 } 34 35 func (qq *coinmarketcapQuoteQuery) getUSD(ctx context.Context, symbol string) (float64, error) { 36 37 var result coinmarketcapResponse 38 39 r := resty.New(resty.WithHeader(map[string]string{ 40 "X-CMC_PRO_API_KEY": qq.APIKey, 41 })) 42 43 s := strings.ToUpper(symbol) 44 45 r.DoGet(ctx, "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest?symbol="+s). 46 Then(func(req *http.Request, resp *http.Response, respBody []byte, cf context.CancelFunc, err error) error { 47 if err != nil { 48 return err 49 } 50 if resp.StatusCode != http.StatusOK { 51 return errors.New("coinmarketcap: " + strconv.Itoa(resp.StatusCode) + resp.Status) 52 } 53 54 err = json.Unmarshal(respBody, &result) 55 if err != nil { 56 return err 57 } 58 59 result.Raw = string(respBody) 60 61 return nil 62 63 }) 64 65 errs := r.Wait() 66 if len(errs) > 0 { 67 return 0, errs[0] 68 } 69 70 zcn, ok := result.Data[s] 71 72 if !ok || len(zcn) == 0 { 73 return 0, errors.New("coinmarketcap: " + symbol + " is not provided on coinmarketcap apis") 74 } 75 76 rate, ok := zcn[0].Quote["USD"] 77 if ok { 78 if rate.Price > 0 { 79 return rate.Price, nil 80 } 81 82 return 0, fmt.Errorf("coinmarketcap: invalid response %s", result.Raw) 83 } 84 85 return 0, errors.New("coinmarketcap: " + symbol + " to USD quote is not provided on coinmarketcap apis") 86 } 87 88 // { 89 // "status": { 90 // "timestamp": "2022-06-03T02:18:34.093Z", 91 // "error_code": 0, 92 // "error_message": null, 93 // "elapsed": 50, 94 // "credit_count": 1, 95 // "notice": null 96 // }, 97 // "data": { 98 // "ZCN": [ 99 // { 100 // "id": 2882, 101 // "name": "0Chain", 102 // "symbol": "ZCN", 103 // "slug": "0chain", 104 // "num_market_pairs": 8, 105 // "date_added": "2018-07-02T00:00:00.000Z", 106 // "tags": [ 107 // { 108 // "slug": "platform", 109 // "name": "Platform", 110 // "category": "PROPERTY" 111 // }, 112 // { 113 // "slug": "ai-big-data", 114 // "name": "AI & Big Data", 115 // "category": "PROPERTY" 116 // }, 117 // { 118 // "slug": "distributed-computing", 119 // "name": "Distributed Computing", 120 // "category": "PROPERTY" 121 // }, 122 // { 123 // "slug": "filesharing", 124 // "name": "Filesharing", 125 // "category": "PROPERTY" 126 // }, 127 // { 128 // "slug": "iot", 129 // "name": "IoT", 130 // "category": "PROPERTY" 131 // }, 132 // { 133 // "slug": "storage", 134 // "name": "Storage", 135 // "category": "PROPERTY" 136 // } 137 // ], 138 // "max_supply": 400000000, 139 // "circulating_supply": 48400982, 140 // "total_supply": 200000000, 141 // "platform": { 142 // "id": 1027, 143 // "name": "Ethereum", 144 // "symbol": "ETH", 145 // "slug": "ethereum", 146 // "token_address": "0xb9ef770b6a5e12e45983c5d80545258aa38f3b78" 147 // }, 148 // "is_active": 1, 149 // "cmc_rank": 782, 150 // "is_fiat": 0, 151 // "self_reported_circulating_supply": 115000000, 152 // "self_reported_market_cap": 25409234.858036295, 153 // "last_updated": "2022-06-03T02:17:00.000Z", 154 // "quote": { 155 // "USD": { 156 // "price": 0.2209498683307504, 157 // "volume_24h": 28807.79174117, 158 // "volume_change_24h": -78.341, 159 // "percent_change_1h": 0.09600341, 160 // "percent_change_24h": 0.1834049, 161 // "percent_change_7d": 24.08736297, 162 // "percent_change_30d": -43.56084388, 163 // "percent_change_60d": -63.69787917, 164 // "percent_change_90d": -27.17695342, 165 // "market_cap": 10694190.59997902, 166 // "market_cap_dominance": 0.0008, 167 // "fully_diluted_market_cap": 88379947.33, 168 // "last_updated": "2022-06-03T02:17:00.000Z" 169 // } 170 // } 171 // } 172 // ] 173 // } 174 // } 175 type coinmarketcapResponse struct { 176 Data map[string][]coinmarketcapCurrency `json:"data"` 177 Raw string `json:"-"` 178 } 179 180 type coinmarketcapCurrency struct { 181 Quote map[string]coinmarketcapQuote `json:"quote"` 182 } 183 184 type coinmarketcapQuote struct { 185 Price float64 `json:"price"` 186 }