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  }