From 87794892bf0e5c9c729f709777bb01e383d192de Mon Sep 17 00:00:00 2001 From: terminaldweller Date: Tue, 28 May 2024 19:02:34 -0400 Subject: added cmc as a provider --- docker-compose-test.yaml | 8 ++-- hived/CMCTickerResponseType.go | 46 ++++++++++++++++++++ hived/hived.go | 88 ++++++++++++++++++++++++++++---------- hived/polygonTicerResponseType.go | 54 ----------------------- hived/polygonTickerResponseType.go | 54 +++++++++++++++++++++++ 5 files changed, 171 insertions(+), 79 deletions(-) create mode 100644 hived/CMCTickerResponseType.go delete mode 100644 hived/polygonTicerResponseType.go create mode 100644 hived/polygonTickerResponseType.go diff --git a/docker-compose-test.yaml b/docker-compose-test.yaml index 965bef9..8d8481f 100644 --- a/docker-compose-test.yaml +++ b/docker-compose-test.yaml @@ -11,7 +11,7 @@ services: ports: - "10008:8008" depends_on: - - redis + - keydb - telebot entrypoint: ["/hived/docker-entrypoint.sh"] cap_drop: @@ -19,6 +19,8 @@ services: environment: - SERVER_DEPLOYMENT_TYPE=test - POLYGON_API_KEY= + - HIVED_PRICE_SOURCE=cmc + - CMC_API_KEY=d941be62-d4da-426c-8dc3-7311b04dfa5f telebot: image: telebot build: @@ -56,7 +58,7 @@ services: environment: - ALLOW_EMPTY_PASSWORD=yes # volumes: - # - redis-data:/data/ + # - keydb-data:/data/ networks: mainnet: driver: bridge @@ -66,4 +68,4 @@ secrets: tg_bot_token: file: ./tgtoken volumes: - redis-data: + keydb-data: diff --git a/hived/CMCTickerResponseType.go b/hived/CMCTickerResponseType.go new file mode 100644 index 0000000..c7fcf84 --- /dev/null +++ b/hived/CMCTickerResponseType.go @@ -0,0 +1,46 @@ +package main + +type CMCTickerStatus struct { + Timestamp string `json:"timestamp"` + ErrorCode int `json:"error_code"` + ErrorMessage string `json:"error_message"` + Elapsed int `json:"elapsed"` + CreditCount int `json:"credit_count"` + Notice string `json:"notice"` +} + +type CMCTickerQuoteData struct { + Price float64 `json:"price"` + Volume24H float64 `json:"volume_24h"` + VolumeChnage24H float64 `json:"volume_change_24h"` + PercentChange1H float64 `json:"percent_change_1h"` + PercentChange24h float64 `json:"percent_change_24h"` + PercentChange7d float64 `json:"percent_change_7d"` + PercentChange30d float64 `json:"percent_change_30d"` + MarketCap float64 `json:"market_cap"` + MarketCapDominance float64 `json:"market_cap_dominance"` + FullyDilutedMarketCap float64 `json:"fully_diluted_market_cap"` + LastUpdated string `json:"last_updated"` +} + +type CMCTickerData struct { + ID int `json:"id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Slug string `json:"slug"` + IsActive int `json:"is_active"` + IsFiat int `json:"is_fiat"` + CirculatingSupply float64 `json:"circulating_supply"` + TotalSupply float64 `json:"total_supply"` + MaxSupply float64 `json:"max_supply"` + DateAdded string `json:"date_added"` + NumMarketPairs int `json:"num_market_pairs"` + CMCRank int `json:"cmc_rank"` + LastUpdated string `json:"last_updated"` + Quote map[string]CMCTickerQuoteData `json:"quote"` +} + +type CMCTickerResponseType struct { + Data map[string]CMCTickerData `json:"data"` + Status CMCTickerStatus `json:"status"` +} diff --git a/hived/hived.go b/hived/hived.go index 4ed81cf..6d3cdfb 100644 --- a/hived/hived.go +++ b/hived/hived.go @@ -28,6 +28,7 @@ import ( const ( cryptocomparePriceURL = "https://min-api.cryptocompare.com/data/price?" polygonCryptoTickerURL = "https://api.polygon.io/v2/snapshot/locale/global/markets/crypto/tickers" + cmcCryptoTickerURL = "https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest" telegramBotTokenEnvVar = "TELEGRAM_BOT_TOKEN" //nolint: gosec serverDeploymentType = "SERVER_DEPLOYMENT_TYPE" httpClientTimeout = 5 @@ -121,21 +122,6 @@ type errorChanStruct struct { err error } -// type APISource int - -const ( - CryptoCompareSource = iota - PolygonSource - // CoinGeckoSource - // CoinCapSource -) - -// TODO-add more sources. -// TODO-do a round robin. -func chooseGetPriceSource() int { - return PolygonSource -} - func getPrice(ctx context.Context, name, unit string, waitGroup *sync.WaitGroup, @@ -145,21 +131,20 @@ func getPrice(ctx context.Context, val, err := rdb.Get(ctx, name+"_price").Float64() if err != nil { - source := chooseGetPriceSource() + source := os.Getenv("HIVED_PRICE_SOURCE") switch source { - case CryptoCompareSource: - fmt.Println("one") + case "cryptocompare": getPriceFromCryptoCompare(ctx, name, unit, waitGroup, priceChan, errChan) - case PolygonSource: - fmt.Println("two") + case "polygon": getPriceFromPolygon(ctx, name, unit, waitGroup, priceChan, errChan) - default: - + case "cmc": + getPriceFromCMC(ctx, name, unit, waitGroup, priceChan, errChan) } } else { priceChan <- priceChanStruct{name: name, price: val} errChan <- errorChanStruct{hasError: false, err: nil} + waitGroup.Done() } } @@ -280,6 +265,65 @@ func getPriceFromPolygon( errChan <- errorChanStruct{hasError: false, err: nil} } +func getPriceFromCMC( + ctx context.Context, + name, unit string, + wg *sync.WaitGroup, + priceChan chan<- priceChanStruct, + errChan chan<- errorChanStruct, +) { + defer wg.Done() + + apiKey := os.Getenv("CMC_API_KEY") + + params := "?slug=" + name + path := cmcCryptoTickerURL + params + + log.Print(path) + + client := GetProxiedClient() + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, path, nil) + if err != nil { + getPriceFromCryptoCompareErrorHandler(err, name, priceChan, errChan) + + return + } + + req.Header.Set("X-CMC_PRO_API_KEY", apiKey) + + resp, err := client.Do(req) + if err != nil { + getPriceFromCryptoCompareErrorHandler(err, name, priceChan, errChan) + + return + } + defer resp.Body.Close() + + var jsonBody CMCTickerResponseType + + err = json.NewDecoder(resp.Body).Decode(&jsonBody) + if err != nil { + getPriceFromCryptoCompareErrorHandler(err, name, priceChan, errChan) + } + + log.Print(jsonBody) + + var price float64 + for _, v := range jsonBody.Data { + price = v.Quote["USD"].Price + } + + err = rdb.Set(ctx, name+"_price", price, time.Duration(*cacheDuration*redisCacheDurationMultiplier)).Err() + + if err != nil { + log.Error().Err(err) + } + + priceChan <- priceChanStruct{name: name, price: price} + errChan <- errorChanStruct{hasError: false, err: nil} +} + func PriceHandler(writer http.ResponseWriter, request *http.Request) { writer.Header().Add("Content-Type", "application/json") diff --git a/hived/polygonTicerResponseType.go b/hived/polygonTicerResponseType.go deleted file mode 100644 index 6d8b323..0000000 --- a/hived/polygonTicerResponseType.go +++ /dev/null @@ -1,54 +0,0 @@ -package main - -type PolygonTickerDataLastTrade struct { - C []int `json:"c"` - I string `json:"i"` - P float64 `json:"p"` - S int `json:"s"` - T int64 `json:"t"` - X int `json:"x"` -} - -type PolygonTickerDataDay struct { - C float64 `json:"c"` - H float64 `json:"h"` - L float64 `json:"l"` - O float64 `json:"o"` - V float64 `json:"v"` - VW float64 `json:"vw"` -} - -type PolygonTickerDataPrevDay struct { - C float64 `json:"c"` - H float64 `json:"h"` - L float64 `json:"l"` - O float64 `json:"o"` - V float64 `json:"v"` - VW float64 `json:"vw"` -} - -type PolygonTickerDataMin struct { - C float64 `json:"c"` - H float64 `json:"h"` - L float64 `json:"l"` - N float64 `json:"n"` - O float64 `json:"o"` - T float64 `json:"t"` - V float64 `json:"v"` - VW float64 `json:"vw"` -} - -type PolygonTickerData struct { - Min PolygonTickerDataMin `json:"min"` - Day PolygonTickerDataDay `json:"day"` - PrevDay PolygonTickerDataPrevDay `json:"prevDay"` -} - -type PolygonTickerResponse struct { - RequestID string `json:"request_id"` - Status string `json:"status"` - TodaysChange float64 `json:"todaysChange"` - TodaysChangePerc float64 `json:"todaysChangePerc"` - Updated float64 `json:"updated"` - Ticker PolygonTickerData `json:"ticker"` -} diff --git a/hived/polygonTickerResponseType.go b/hived/polygonTickerResponseType.go new file mode 100644 index 0000000..6d8b323 --- /dev/null +++ b/hived/polygonTickerResponseType.go @@ -0,0 +1,54 @@ +package main + +type PolygonTickerDataLastTrade struct { + C []int `json:"c"` + I string `json:"i"` + P float64 `json:"p"` + S int `json:"s"` + T int64 `json:"t"` + X int `json:"x"` +} + +type PolygonTickerDataDay struct { + C float64 `json:"c"` + H float64 `json:"h"` + L float64 `json:"l"` + O float64 `json:"o"` + V float64 `json:"v"` + VW float64 `json:"vw"` +} + +type PolygonTickerDataPrevDay struct { + C float64 `json:"c"` + H float64 `json:"h"` + L float64 `json:"l"` + O float64 `json:"o"` + V float64 `json:"v"` + VW float64 `json:"vw"` +} + +type PolygonTickerDataMin struct { + C float64 `json:"c"` + H float64 `json:"h"` + L float64 `json:"l"` + N float64 `json:"n"` + O float64 `json:"o"` + T float64 `json:"t"` + V float64 `json:"v"` + VW float64 `json:"vw"` +} + +type PolygonTickerData struct { + Min PolygonTickerDataMin `json:"min"` + Day PolygonTickerDataDay `json:"day"` + PrevDay PolygonTickerDataPrevDay `json:"prevDay"` +} + +type PolygonTickerResponse struct { + RequestID string `json:"request_id"` + Status string `json:"status"` + TodaysChange float64 `json:"todaysChange"` + TodaysChangePerc float64 `json:"todaysChangePerc"` + Updated float64 `json:"updated"` + Ticker PolygonTickerData `json:"ticker"` +} -- cgit v1.2.3