From 40f0b3a3b3a3a8b3003283f23844838ccde22fe2 Mon Sep 17 00:00:00 2001 From: Miguel Mota Date: Sun, 6 May 2018 21:07:33 -0700 Subject: [PATCH] currencyconversion var --- Gopkg.lock | 12 - Gopkg.toml | 5 - README.md | 2 +- cointop/chart.go | 11 +- cointop/cointop.go | 8 +- cointop/list.go | 2 +- cointop/marketbar.go | 2 +- pkg/api/cmc/cmc.go | 73 ++-- pkg/api/interface.go | 4 +- pkg/cmc/cmc.go | 356 ++++++++++++++++++ pkg/cmc/types/types.go | 73 ++++ .../miguelmota/go-coinmarketcap/.gitignore | 26 -- .../miguelmota/go-coinmarketcap/.travis.yml | 9 - .../miguelmota/go-coinmarketcap/Gopkg.lock | 24 -- .../miguelmota/go-coinmarketcap/Gopkg.toml | 34 -- .../miguelmota/go-coinmarketcap/LICENSE.md | 21 -- .../miguelmota/go-coinmarketcap/Makefile | 5 - .../miguelmota/go-coinmarketcap/README.md | 47 --- .../go-coinmarketcap/coinmarketcap.go | 210 ----------- .../go-coinmarketcap/coinmarketcap_test.go | 219 ----------- .../go-coinmarketcap/example/all_coins.go | 20 - .../go-coinmarketcap/example/coin.go | 18 - .../go-coinmarketcap/example/coin_graph.go | 25 -- .../go-coinmarketcap/example/global_market.go | 18 - .../miguelmota/go-coinmarketcap/types.go | 66 ---- 25 files changed, 491 insertions(+), 799 deletions(-) create mode 100644 pkg/cmc/cmc.go create mode 100644 pkg/cmc/types/types.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/.gitignore delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/.travis.yml delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.lock delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.toml delete mode 100755 vendor/github.com/miguelmota/go-coinmarketcap/LICENSE.md delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/Makefile delete mode 100755 vendor/github.com/miguelmota/go-coinmarketcap/README.md delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap_test.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/example/all_coins.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/example/coin.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/example/coin_graph.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/example/global_market.go delete mode 100644 vendor/github.com/miguelmota/go-coinmarketcap/types.go diff --git a/Gopkg.lock b/Gopkg.lock index 11e681f..f0c162f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -37,18 +37,6 @@ revision = "9e777a8366cce605130a531d2cd6363d07ad7317" version = "v0.0.2" -[[projects]] - branch = "master" - name = "github.com/miguelmota/go-coinmarketcap" - packages = ["."] - revision = "42269f499a7031e0affa526258909fa73f2914cd" - -[[projects]] - branch = "master" - name = "github.com/nsf/termbox-go" - packages = ["."] - revision = "7cbfaac9e282b3ea0cefeddc67b2c3ed3aaf97bc" - [[projects]] branch = "master" name = "go4.org" diff --git a/Gopkg.toml b/Gopkg.toml index 8738f07..47d327c 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -29,8 +29,3 @@ [[constraint]] name = "github.com/fatih/color" version = "1.6.0" - -[[constraint]] - branch = "master" - name = "github.com/miguelmota/go-coinmarketcap" - diff --git a/README.md b/README.md index c3e2b76..5276e08 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ > Coin tracking for hackers -[![License](http://img.shields.io/badge/license-Apache-red.svg)](https://raw.githubusercontent.com/miguelmota/cointop/master/LICENSE.md) [![Build Status](https://travis-ci.org/miguelmota/cointop.svg?branch=master)](https://travis-ci.org/miguelmota/cointop) [![Go Report Card](https://goreportcard.com/badge/github.com/miguelmota/cointop?)](https://goreportcard.com/report/github.com/miguelmota/cointop) [![GoDoc](https://godoc.org/github.com/miguelmota/cointop?status.svg)](https://godoc.org/github.com/miguelmota/cointop) [![Mentioned in Awesome Terminals](https://awesome.re/mentioned-badge.svg)](https://github.com/k4m4/terminals-are-sexy) +[![License](http://img.shields.io/badge/license-Apache-blue.svg)](https://raw.githubusercontent.com/miguelmota/cointop/master/LICENSE.md) [![Build Status](https://travis-ci.org/miguelmota/cointop.svg?branch=master)](https://travis-ci.org/miguelmota/cointop) [![Go Report Card](https://goreportcard.com/badge/github.com/miguelmota/cointop?)](https://goreportcard.com/report/github.com/miguelmota/cointop) [![GoDoc](https://godoc.org/github.com/miguelmota/cointop?status.svg)](https://godoc.org/github.com/miguelmota/cointop) [![Mentioned in Awesome Terminals](https://awesome.re/mentioned-badge.svg)](https://github.com/k4m4/terminals-are-sexy) [`cointop`](https://github.com/miguelmota/cointop) is a fast and lightweight interactive terminal based UI application for tracking and monitoring cryptocurrency coin stats in real-time. diff --git a/cointop/chart.go b/cointop/chart.go index c223222..dd9476a 100644 --- a/cointop/chart.go +++ b/cointop/chart.go @@ -13,7 +13,7 @@ import ( func (ct *Cointop) updateChart() error { maxX := ct.maxtablewidth - 3 - coin := ct.selectedCoinName() + coin := ct.selectedCoinSymbol() ct.chartPoints(maxX, coin) if len(ct.chartpoints) != 0 { ct.chartview.Clear() @@ -185,6 +185,15 @@ func (ct *Cointop) selectedCoinName() string { return "" } +func (ct *Cointop) selectedCoinSymbol() string { + coin := ct.selectedcoin + if coin != nil { + return coin.Symbol + } + + return "" +} + func (ct *Cointop) toggleCoinChart() error { highlightedcoin := ct.highlightedRowCoin() if ct.selectedcoin == highlightedcoin { diff --git a/cointop/cointop.go b/cointop/cointop.go index c6b828a..2c37445 100644 --- a/cointop/cointop.go +++ b/cointop/cointop.go @@ -9,7 +9,7 @@ import ( "time" "github.com/miguelmota/cointop/pkg/api" - types "github.com/miguelmota/cointop/pkg/api/types" + apitypes "github.com/miguelmota/cointop/pkg/api/types" "github.com/miguelmota/cointop/pkg/cache" "github.com/miguelmota/cointop/pkg/fcache" "github.com/miguelmota/cointop/pkg/gocui" @@ -63,6 +63,7 @@ type Cointop struct { helpview *gocui.View helpviewname string helpvisible bool + currencyconversion string } // Instance running cointop instance @@ -135,6 +136,7 @@ func Run() { statusbarviewname: "statusbar", searchfieldviewname: "searchfield", helpviewname: "help", + currencyconversion: "USD", } Instance = &ct err := ct.setupConfig() @@ -142,7 +144,7 @@ func Run() { log.Fatal(err) } - allcoinsmap := map[string]types.Coin{} + allcoinsmap := map[string]apitypes.Coin{} coinscachekey := "allcoinsmap" fcache.Get(coinscachekey, &allcoinsmap) ct.cache.Set(coinscachekey, allcoinsmap, 10*time.Second) @@ -152,7 +154,7 @@ func Run() { fcache.Get(chartcachekey, &globaldata) ct.cache.Set(chartcachekey, globaldata, 10*time.Second) - var market types.GlobalMarketData + var market apitypes.GlobalMarketData marketcachekey := "market" fcache.Get(marketcachekey, &market) ct.cache.Set(marketcachekey, market, 10*time.Second) diff --git a/cointop/list.go b/cointop/list.go index 878f8cb..2366073 100644 --- a/cointop/list.go +++ b/cointop/list.go @@ -23,7 +23,7 @@ func (ct *Cointop) updateCoins() error { // cache miss if allcoinsmap == nil { ct.debuglog("cache miss") - allcoinsmap, err = ct.api.GetAllCoinData() + allcoinsmap, err = ct.api.GetAllCoinData(ct.currencyconversion) if err != nil { return err } diff --git a/cointop/marketbar.go b/cointop/marketbar.go index 43e7196..862a0a2 100644 --- a/cointop/marketbar.go +++ b/cointop/marketbar.go @@ -26,7 +26,7 @@ func (ct *Cointop) updateMarketbar() error { ct.debuglog("soft cache hit") } } else { - market, err = ct.api.GetGlobalMarketData() + market, err = ct.api.GetGlobalMarketData(ct.currencyconversion) if err != nil { return err } diff --git a/pkg/api/cmc/cmc.go b/pkg/api/cmc/cmc.go index 5f2c976..66b7574 100644 --- a/pkg/api/cmc/cmc.go +++ b/pkg/api/cmc/cmc.go @@ -1,10 +1,10 @@ package api import ( - "strings" + "strconv" - types "github.com/miguelmota/cointop/pkg/api/types" - cmc "github.com/miguelmota/go-coinmarketcap" + apitypes "github.com/miguelmota/cointop/pkg/api/types" + cmc "github.com/miguelmota/cointop/pkg/cmc" ) // Service service @@ -17,37 +17,43 @@ func New() *Service { } // GetAllCoinData gets all coin data -func (s *Service) GetAllCoinData() (map[string]types.Coin, error) { - ret := make(map[string]types.Coin) - coins, err := cmc.GetAllCoinData(0) +func (s *Service) GetAllCoinData(convert string) (map[string]apitypes.Coin, error) { + ret := make(map[string]apitypes.Coin) + coins, err := cmc.Tickers(&cmc.TickersOptions{ + Convert: convert, + }) if err != nil { return ret, err } for _, v := range coins { - ret[v.ID] = types.Coin{ - ID: v.ID, + ret[v.Symbol] = apitypes.Coin{ + ID: v.Slug, Name: v.Name, Symbol: v.Symbol, Rank: v.Rank, - PriceUSD: v.PriceUSD, - PriceBTC: v.PriceBTC, - USD24HVolume: v.USD24HVolume, - MarketCapUSD: v.MarketCapUSD, - AvailableSupply: v.AvailableSupply, + AvailableSupply: v.CirculatingSupply, TotalSupply: v.TotalSupply, - PercentChange1H: v.PercentChange1H, - PercentChange24H: v.PercentChange24H, - PercentChange7D: v.PercentChange7D, - LastUpdated: v.LastUpdated, + MarketCapUSD: v.Quotes[convert].MarketCap, + PriceUSD: v.Quotes[convert].Price, + PercentChange1H: v.Quotes[convert].PercentChange1H, + PercentChange24H: v.Quotes[convert].PercentChange24H, + PercentChange7D: v.Quotes[convert].PercentChange7D, + USD24HVolume: v.Quotes[convert].Volume24H, + PriceBTC: 0, + LastUpdated: strconv.Itoa(v.LastUpdated), } } return ret, nil } // GetCoinGraphData gets coin graph data -func (s *Service) GetCoinGraphData(coin string, start int64, end int64) (types.CoinGraph, error) { - ret := types.CoinGraph{} - graphData, err := cmc.GetCoinGraphData(strings.ToLower(coin), start, end) +func (s *Service) GetCoinGraphData(coin string, start int64, end int64) (apitypes.CoinGraph, error) { + ret := apitypes.CoinGraph{} + graphData, err := cmc.TickerGraph(&cmc.TickerGraphOptions{ + Symbol: coin, + Start: start, + End: end, + }) if err != nil { return ret, err } @@ -60,9 +66,12 @@ func (s *Service) GetCoinGraphData(coin string, start int64, end int64) (types.C } // GetGlobalMarketGraphData gets global market graph data -func (s *Service) GetGlobalMarketGraphData(start int64, end int64) (types.MarketGraph, error) { - ret := types.MarketGraph{} - graphData, err := cmc.GetGlobalMarketGraphData(start, end) +func (s *Service) GetGlobalMarketGraphData(start int64, end int64) (apitypes.MarketGraph, error) { + ret := apitypes.MarketGraph{} + graphData, err := cmc.GlobalMarketGraph(&cmc.GlobalMarketGraphOptions{ + Start: start, + End: end, + }) if err != nil { return ret, err } @@ -73,19 +82,21 @@ func (s *Service) GetGlobalMarketGraphData(start int64, end int64) (types.Market } // GetGlobalMarketData gets global market data -func (s *Service) GetGlobalMarketData() (types.GlobalMarketData, error) { - ret := types.GlobalMarketData{} - market, err := cmc.GetGlobalMarketData() +func (s *Service) GetGlobalMarketData(convert string) (apitypes.GlobalMarketData, error) { + ret := apitypes.GlobalMarketData{} + market, err := cmc.GlobalMarket(&cmc.GlobalMarketOptions{ + Convert: convert, + }) if err != nil { return ret, err } - ret = types.GlobalMarketData{ - TotalMarketCapUSD: market.TotalMarketCapUSD, - Total24HVolumeUSD: market.Total24HVolumeUSD, + ret = apitypes.GlobalMarketData{ + TotalMarketCapUSD: market.Quotes[convert].TotalMarketCap, + Total24HVolumeUSD: market.Quotes[convert].TotalVolume24H, BitcoinPercentageOfMarketCap: market.BitcoinPercentageOfMarketCap, ActiveCurrencies: market.ActiveCurrencies, - ActiveAssets: market.ActiveCurrencies, - ActiveMarkets: market.ActiveAssets, + ActiveAssets: 0, + ActiveMarkets: market.ActiveMarkets, } return ret, nil } diff --git a/pkg/api/interface.go b/pkg/api/interface.go index c9eea9f..6cd8fe6 100644 --- a/pkg/api/interface.go +++ b/pkg/api/interface.go @@ -6,10 +6,10 @@ import ( // Interface interface type Interface interface { - GetAllCoinData() (map[string]types.Coin, error) + GetAllCoinData(convert string) (map[string]types.Coin, error) GetCoinGraphData(coin string, start int64, end int64) (types.CoinGraph, error) GetGlobalMarketGraphData(start int64, end int64) (types.MarketGraph, error) - GetGlobalMarketData() (types.GlobalMarketData, error) + GetGlobalMarketData(convert string) (types.GlobalMarketData, error) //GetCoinData(coin string) (types.Coin, error) //GetAltcoinMarketGraphData(start int64, end int64) (types.MarketGraph, error) //GetCoinPriceUSD(coin string) (float64, error) diff --git a/pkg/cmc/cmc.go b/pkg/cmc/cmc.go new file mode 100644 index 0000000..522d091 --- /dev/null +++ b/pkg/cmc/cmc.go @@ -0,0 +1,356 @@ +// Package coinmarketcap Coin Market Cap API client for Go +package coinmarketcap + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + + "github.com/anaskhan96/soup" + "github.com/coincircle/go-coinmarketcap/types" +) + +var ( + siteURL = "https://coinmarketcap.com" + baseURL = "https://api.coinmarketcap.com/v2" + coinGraphURL = "https://graphs2.coinmarketcap.com/currencies" + globalMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-total" + altcoinMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-altcoin" +) + +// Interface interface +type Interface interface { + Listings() ([]*types.Listing, error) + Tickers(options *TickersOptions) (map[string]*types.Ticker, error) + Ticker(options *TickerOptions) (*types.Ticker, error) + TickerGraph(options *TickerGraphOptions) (*types.TickerGraph, error) + GlobalMarket(options *GlobalMarketOptions) (*types.GlobalMarket, error) + GlobalMarketGraph(options *GlobalMarketGraphOptions) (*types.MarketGraph, error) + GlobalAltcoinMarketGraph(options *GlobalAltcoinMarketGraphOptions) (*types.MarketGraph, error) + Markets(options *MarketsOptions) ([]*types.Market, error) + Price(options *PriceOptions) (float64, error) + CoinID(symbol string) (int, error) + CoinSlug(symbol string) (string, error) +} + +// listingsMedia listings response media +type listingsMedia struct { + Data []*types.Listing `json:"data"` +} + +// Listings gets all coin listings +func Listings() ([]*types.Listing, error) { + url := fmt.Sprintf("%s/listings", baseURL) + resp, err := makeReq(url) + var body listingsMedia + err = json.Unmarshal(resp, &body) + if err != nil { + return nil, err + } + return body.Data, nil +} + +// TickersOptions options for tickers method +type TickersOptions struct { + Start int + Limit int + Convert string +} + +// tickerMedia tickers response media +type tickersMedia struct { + Data map[string]*types.Ticker `json:"data"` +} + +// Tickers gets ticker information on coins +func Tickers(options *TickersOptions) (map[string]*types.Ticker, error) { + var params []string + if options.Start >= 0 { + params = append(params, fmt.Sprintf("start=%v", options.Start)) + } + if options.Limit >= 0 { + params = append(params, fmt.Sprintf("limit=%v", options.Limit)) + } + if options.Convert != "" { + params = append(params, fmt.Sprintf("convert=%v", options.Convert)) + } + url := fmt.Sprintf("%s/ticker?%s", baseURL, strings.Join(params, "&")) + resp, err := makeReq(url) + var body tickersMedia + err = json.Unmarshal(resp, &body) + if err != nil { + return nil, err + } + tickers := make(map[string]*types.Ticker) + data := body.Data + for _, v := range data { + tickers[strings.ToUpper(string(v.Symbol))] = v + } + return tickers, nil +} + +// TickerOptions options for ticker method +type TickerOptions struct { + Symbol string + Convert string +} + +type tickerMedia struct { + Data *types.Ticker `json:"data"` +} + +// Ticker gets ticker information about a cryptocurrency +func Ticker(options *TickerOptions) (*types.Ticker, error) { + var params []string + if options.Convert != "" { + params = append(params, fmt.Sprintf("convert=%v", options.Convert)) + } + id, err := CoinID(options.Symbol) + if err != nil { + return nil, err + } + url := fmt.Sprintf("%s/ticker/%v?%s", baseURL, id, strings.Join(params, "&")) + resp, err := makeReq(url) + if err != nil { + return nil, err + } + var body tickerMedia + err = json.Unmarshal(resp, &body) + if err != nil { + return nil, err + } + return body.Data, nil +} + +// TickerGraphOptions options for ticker graph +type TickerGraphOptions struct { + Symbol string + Start int64 + End int64 +} + +// TickerGraph gets graph data points for a cryptocurrency +func TickerGraph(options *TickerGraphOptions) (*types.TickerGraph, error) { + slug, err := CoinSlug(options.Symbol) + if err != nil { + return nil, err + } + url := fmt.Sprintf("%s/%s/%d/%d", coinGraphURL, slug, options.Start*1000, options.End*1000) + resp, err := makeReq(url) + if err != nil { + return nil, err + } + var data *types.TickerGraph + err = json.Unmarshal(resp, &data) + if err != nil { + return nil, err + } + return data, nil +} + +// GlobalMarketOptions options for global data method +type GlobalMarketOptions struct { + Convert string +} + +// globalMedia global data response media +type globalMarketMedia struct { + Data *types.GlobalMarket `json:"data"` +} + +// GlobalMarket gets information about the global market of the cryptocurrencies +func GlobalMarket(options *GlobalMarketOptions) (*types.GlobalMarket, error) { + var params []string + if options.Convert != "" { + params = append(params, fmt.Sprintf("convert=%v", options.Convert)) + } + url := fmt.Sprintf("%s/global?%s", baseURL, strings.Join(params, "&")) + resp, err := makeReq(url) + var body globalMarketMedia + err = json.Unmarshal(resp, &body) + if err != nil { + return nil, err + } + return body.Data, nil +} + +// GlobalMarketGraphOptions options for global market graph method +type GlobalMarketGraphOptions struct { + Start int64 + End int64 +} + +// GlobalMarketGraph get graph data points of global market +func GlobalMarketGraph(options *GlobalMarketGraphOptions) (*types.MarketGraph, error) { + url := fmt.Sprintf("%s/%d/%d", globalMarketGraphURL, options.Start*1000, options.End*1000) + resp, err := makeReq(url) + if err != nil { + return nil, err + } + var data *types.MarketGraph + err = json.Unmarshal(resp, &data) + if err != nil { + return nil, err + } + return data, nil +} + +// GlobalAltcoinMarketGraphOptions options for global altcoin market graph method +type GlobalAltcoinMarketGraphOptions struct { + Start int64 + End int64 +} + +// GlobalAltcoinMarketGraph gets graph data points of altcoin market +func GlobalAltcoinMarketGraph(options *GlobalAltcoinMarketGraphOptions) (*types.MarketGraph, error) { + url := fmt.Sprintf("%s/%d/%d", altcoinMarketGraphURL, options.Start*1000, options.End*1000) + resp, err := makeReq(url) + if err != nil { + return nil, err + } + var data *types.MarketGraph + err = json.Unmarshal(resp, &data) + if err != nil { + return nil, err + } + return data, nil +} + +// MarketsOptions options for markets method +type MarketsOptions struct { + Symbol string +} + +// Markets get market data for a cryptocurrency +func Markets(options *MarketsOptions) ([]*types.Market, error) { + slug, err := CoinSlug(options.Symbol) + if err != nil { + return nil, err + } + url := fmt.Sprintf("%s/currencies/%s/#markets", siteURL, slug) + var markets []*types.Market + response, err := soup.Get(url) + if err != nil { + return nil, err + } + rows := soup.HTMLParse(response).Find("table", "id", "markets-table").Find("tbody").FindAll("tr") + for _, row := range rows { + var data []string + for _, column := range row.FindAll("td") { + attrs := column.Attrs() + if attrs["data-sort"] != "" { + data = append(data, attrs["data-sort"]) + } else { + data = append(data, column.Text()) + } + } + markets = append(markets, &types.Market{ + Rank: toInt(data[0]), + Exchange: data[1], + Pair: data[2], + VolumeUSD: toFloat(data[3]), + Price: toFloat(data[4]), + VolumePercent: toFloat(data[5]), + Updated: data[6], + }) + } + return markets, nil +} + +// PriceOptions options for price method +type PriceOptions struct { + Symbol string + Convert string +} + +// Price gets price of a cryptocurrency +func Price(options *PriceOptions) (float64, error) { + coins, err := Tickers(&TickersOptions{ + Convert: options.Convert, + }) + if err != nil { + return 0, err + } + coin := coins[options.Symbol] + if coin == nil { + return 0, errors.New("coin not found") + } + return coin.Quotes[options.Convert].Price, nil +} + +// CoinID gets the ID for the cryptocurrency +func CoinID(symbol string) (int, error) { + symbol = strings.ToUpper(strings.TrimSpace(symbol)) + coins, err := Tickers(&TickersOptions{}) + if err != nil { + return 0, err + } + coin := coins[symbol] + if coin == nil { + return 0, errors.New("coin not found") + } + return coin.ID, nil +} + +// CoinSlug gets the slug for the cryptocurrency +func CoinSlug(symbol string) (string, error) { + symbol = strings.ToUpper(strings.TrimSpace(symbol)) + coins, err := Tickers(&TickersOptions{}) + if err != nil { + return "", err + } + coin := coins[symbol] + if coin == nil { + return "", errors.New("coin not found") + } + return coin.Slug, nil +} + +// toInt helper for parsing strings to int +func toInt(rawInt string) int { + parsed, _ := strconv.Atoi(strings.Replace(strings.Replace(rawInt, "$", "", -1), ",", "", -1)) + return parsed +} + +// toFloat helper for parsing strings to float +func toFloat(rawFloat string) float64 { + parsed, _ := strconv.ParseFloat(strings.Replace(strings.Replace(strings.Replace(rawFloat, "$", "", -1), ",", "", -1), "%", "", -1), 64) + return parsed +} + +// doReq HTTP client +func doReq(req *http.Request) ([]byte, error) { + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if 200 != resp.StatusCode { + return nil, fmt.Errorf("%s", body) + } + + return body, nil +} + +// makeReq HTTP request helper +func makeReq(url string) ([]byte, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + resp, err := doReq(req) + if err != nil { + return nil, err + } + + return resp, err +} diff --git a/pkg/cmc/types/types.go b/pkg/cmc/types/types.go new file mode 100644 index 0000000..67bbd34 --- /dev/null +++ b/pkg/cmc/types/types.go @@ -0,0 +1,73 @@ +package types + +// Listing struct +type Listing struct { + ID int `json:"id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Slug string `json:"website_slug"` +} + +// Ticker struct +type Ticker struct { + ID int `json:"id"` + Name string `json:"name"` + Symbol string `json:"symbol"` + Slug string `json:"website_slug"` + Rank int `json:"rank"` + CirculatingSupply float64 `json:"circulating_supply"` + TotalSupply float64 `json:"total_supply"` + MaxSupply float64 `json:"max_supply"` + Quotes map[string]*TickerQuote `json:"quotes"` + LastUpdated int `json:"last_updated"` +} + +// TickerQuote struct +type TickerQuote struct { + Price float64 `json:"price"` + Volume24H float64 `json:"volume_24h"` + MarketCap float64 `json:"market_cap"` + PercentChange1H float64 `json:"percent_change_1h"` + PercentChange24H float64 `json:"percent_change_24h"` + PercentChange7D float64 `json:"percent_change_7d"` +} + +// GlobalMarket struct +type GlobalMarket struct { + ActiveCurrencies int `json:"active_cryptocurrencies"` + ActiveMarkets int `json:"active_markets"` + BitcoinPercentageOfMarketCap float64 `json:"bitcoin_percentage_of_market_cap"` + LastUpdated int `json:"last_updated"` + Quotes map[string]*GlobalMarketQuote `json:"quotes"` +} + +// GlobalMarketQuote struct +type GlobalMarketQuote struct { + TotalMarketCap float64 `json:"total_market_cap"` + TotalVolume24H float64 `json:"total_volume_24h"` +} + +// TickerGraph struct +type TickerGraph struct { + MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"` + PriceBTC [][]float64 `json:"price_btc"` + PriceUSD [][]float64 `json:"price_usd"` + VolumeUSD [][]float64 `json:"volume_usd"` +} + +// Market struct +type Market struct { + Rank int + Exchange string + Pair string + VolumeUSD float64 + Price float64 + VolumePercent float64 + Updated string +} + +// MarketGraph struct +type MarketGraph struct { + MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"` + VolumeUSD [][]float64 `json:"volume_usd"` +} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/.gitignore b/vendor/github.com/miguelmota/go-coinmarketcap/.gitignore deleted file mode 100644 index bf2bb1d..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -.DS_Store diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/.travis.yml b/vendor/github.com/miguelmota/go-coinmarketcap/.travis.yml deleted file mode 100644 index 1a5f7a1..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go - -go: - - "1.9.x" - - "1.10.x" - - "master" - -script: - - make test diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.lock b/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.lock deleted file mode 100644 index b8f3d3b..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.lock +++ /dev/null @@ -1,24 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/anaskhan96/soup" - packages = ["."] - revision = "7a8d31f81bad1a5abeed0d0219c35e5e295a5a76" - version = "v1.0.1" - -[[projects]] - branch = "master" - name = "golang.org/x/net" - packages = [ - "html", - "html/atom" - ] - revision = "dc948dff8834a7fe1ca525f8d04e261c2b56e70d" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "ef92c4a55490132c4b677cba28dd5f0ee0bb397d0b3581ea46df6c3f4f169646" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.toml b/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.toml deleted file mode 100644 index f0a6218..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/Gopkg.toml +++ /dev/null @@ -1,34 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/anaskhan96/soup" - version = "1.0.1" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/LICENSE.md b/vendor/github.com/miguelmota/go-coinmarketcap/LICENSE.md deleted file mode 100755 index eb0736f..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT license - -Copyright (C) 2015 Miguel Mota - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/Makefile b/vendor/github.com/miguelmota/go-coinmarketcap/Makefile deleted file mode 100644 index 10b2bf7..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: - @echo "no default" - -test: - go test -v diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/README.md b/vendor/github.com/miguelmota/go-coinmarketcap/README.md deleted file mode 100755 index c55fe49..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# go-coinmarketcap - -> The Unofficial [CoinMarketCap](https://coinmarketcap.com/) API client for Go. - -[![License](http://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/miguelmota/go-coinmarketcap/master/LICENSE.md) [![Build Status](https://travis-ci.org/miguelmota/go-coinmarketcap.svg?branch=master)](https://travis-ci.org/miguelmota/go-coinmarketcap) [![Go Report Card](https://goreportcard.com/badge/github.com/miguelmota/go-coinmarketcap?)](https://goreportcard.com/report/github.com/miguelmota/go-coinmarketcap) [![GoDoc](https://godoc.org/github.com/miguelmota/go-coinmarketcap?status.svg)](https://godoc.org/github.com/miguelmota/go-coinmarketcap) - -## Documentation - -[https://godoc.org/github.com/miguelmota/go-coinmarketcap](https://godoc.org/github.com/miguelmota/go-coinmarketcap) - -## Install - -```bash -go get -u github.com/miguelmota/go-coinmarketcap -``` - -## Getting started - -```go -package main - -import ( - "fmt" - "log" - - cmc "github.com/miguelmota/go-coinmarketcap" -) - -func main() { - coins, err := cmc.GetAllCoinData(0) - if err != nil { - log.Fatal(err) - } - - for _, coin := range coins { - fmt.Println(coin.Symbol, coin.PriceUSD) - } -} -``` - -## Examples - -Check out the [`./example`](./example) directory and documentation. - -## License - -MIT diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap.go b/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap.go deleted file mode 100644 index 899ff3d..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap.go +++ /dev/null @@ -1,210 +0,0 @@ -// Package coinmarketcap Coin Market Cap API client for Go -package coinmarketcap - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "net/http" - "strconv" - "strings" - - "github.com/anaskhan96/soup" -) - -var ( - baseURL = "https://api.coinmarketcap.com/v1" - coinGraphURL = "https://graphs2.coinmarketcap.com/currencies" - globalMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-total" - altcoinMarketGraphURL = "https://graphs2.coinmarketcap.com/global/marketcap-altcoin" -) - -// GetGlobalMarketData get information about the global market data of the cryptocurrencies -func GetGlobalMarketData() (GlobalMarketData, error) { - url := fmt.Sprintf(baseURL + "/global/") - - resp, err := makeReq(url) - - var data GlobalMarketData - err = json.Unmarshal(resp, &data) - if err != nil { - return GlobalMarketData{}, err - } - - return data, nil -} - -// GetGlobalMarketGraphData get graph data points of global market -func GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error) { - url := fmt.Sprintf("%s/%d/%d", globalMarketGraphURL, start*1000, end*1000) - resp, err := makeReq(url) - if err != nil { - return MarketGraph{}, err - } - var data MarketGraph - err = json.Unmarshal(resp, &data) - if err != nil { - return MarketGraph{}, err - } - - return data, nil -} - -// GetAltcoinMarketGraphData get graph data points of altcoin market -func GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error) { - url := fmt.Sprintf("%s/%d/%d", altcoinMarketGraphURL, start*1000, end*1000) - resp, err := makeReq(url) - if err != nil { - return MarketGraph{}, err - } - var data MarketGraph - err = json.Unmarshal(resp, &data) - if err != nil { - return MarketGraph{}, err - } - - return data, nil -} - -// GetCoinData get information about a crypto currency -func GetCoinData(coin string) (Coin, error) { - coin = strings.ToLower(coin) - url := fmt.Sprintf("%s/ticker/%s", baseURL, coin) - resp, err := makeReq(url) - if err != nil { - return Coin{}, err - } - var data []Coin - err = json.Unmarshal(resp, &data) - if err != nil { - return Coin{}, err - } - - return data[0], nil -} - -// GetAllCoinData get information about all coins listed in Coin Market Cap -func GetAllCoinData(limit int) (map[string]Coin, error) { - var l string - if limit >= 0 { - l = fmt.Sprintf("?limit=%v", limit) - } - url := fmt.Sprintf("%s/ticker/%s", baseURL, l) - - resp, err := makeReq(url) - - var data []Coin - err = json.Unmarshal(resp, &data) - if err != nil { - return nil, err - } - // creating map from the array - allCoins := make(map[string]Coin) - for i := 0; i < len(data); i++ { - allCoins[data[i].ID] = data[i] - } - - return allCoins, nil -} - -// GetCoinGraphData get graph data points for a crypto currency -func GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error) { - url := fmt.Sprintf("%s/%s/%d/%d", coinGraphURL, strings.ToLower(coin), start*1000, end*1000) - resp, err := makeReq(url) - if err != nil { - return CoinGraph{}, err - } - var data CoinGraph - err = json.Unmarshal(resp, &data) - if err != nil { - return CoinGraph{}, err - } - - return data, nil -} - -// GetCoinPriceUSD get USD price of crypto currency -func GetCoinPriceUSD(coin string) (float64, error) { - data, err := GetCoinData(strings.ToLower(coin)) - if err != nil { - return float64(0), nil - } - return data.PriceUSD, nil -} - -// GetCoinMarkets get market data for a coin name -func GetCoinMarkets(coin string) ([]Market, error) { - url := fmt.Sprintf("https://coinmarketcap.com/currencies/%s/#markets", strings.ToLower(coin)) - var markets []Market - response, err := soup.Get(url) - if err != nil { - return nil, err - } - rows := soup.HTMLParse(response).Find("table", "id", "markets-table").Find("tbody").FindAll("tr") - for _, row := range rows { - var data []string - for _, column := range row.FindAll("td") { - attrs := column.Attrs() - if attrs["data-sort"] != "" { - data = append(data, attrs["data-sort"]) - } else { - data = append(data, column.Text()) - } - } - markets = append(markets, Market{ - Rank: toInt(data[0]), - Exchange: data[1], - Pair: data[2], - VolumeUSD: toFloat(data[3]), - Price: toFloat(data[4]), - VolumePercent: toFloat(data[5]), - Updated: data[6], - }) - } - return markets, nil -} - -// doReq HTTP client -func doReq(req *http.Request) ([]byte, error) { - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - if 200 != resp.StatusCode { - return nil, fmt.Errorf("%s", body) - } - - return body, nil -} - -// makeReq HTTP request helper -func makeReq(url string) ([]byte, error) { - req, err := http.NewRequest("GET", url, nil) - if err != nil { - return nil, err - } - resp, err := doReq(req) - if err != nil { - return nil, err - } - - return resp, err -} - -// toInt helper for parsing strings to int -func toInt(rawInt string) int { - parsed, _ := strconv.Atoi(strings.Replace(strings.Replace(rawInt, "$", "", -1), ",", "", -1)) - return parsed -} - -// toFloat helper for parsing strings to float -func toFloat(rawFloat string) float64 { - parsed, _ := strconv.ParseFloat(strings.Replace(strings.Replace(strings.Replace(rawFloat, "$", "", -1), ",", "", -1), "%", "", -1), 64) - return parsed -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap_test.go b/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap_test.go deleted file mode 100644 index 8898e07..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/coinmarketcap_test.go +++ /dev/null @@ -1,219 +0,0 @@ -package coinmarketcap - -import ( - "testing" - "time" -) - -func TestGetGlobalMarketData(t *testing.T) { - market, err := GetGlobalMarketData() - if err != nil { - t.FailNow() - } - - if market.ActiveAssets == 0 { - t.FailNow() - } - if market.ActiveCurrencies == 0 { - t.FailNow() - } - if market.ActiveMarkets == 0 { - t.FailNow() - } - if market.BitcoinPercentageOfMarketCap == 0 { - t.FailNow() - } - if market.Total24HVolumeUSD == 0 { - t.FailNow() - } - if market.TotalMarketCapUSD == 0 { - t.FailNow() - } -} - -func TestGetGlobalMarketGraphData(t *testing.T) { - var threeMonths int64 = (60 * 60 * 24 * 90) - end := time.Now().Unix() - start := end - threeMonths - - graph, err := GetGlobalMarketGraphData(start, end) - if err != nil { - t.FailNow() - } - - if graph.MarketCapByAvailableSupply[0][0] == 0 { - t.FailNow() - } - - if graph.VolumeUSD[0][0] == 0 { - t.FailNow() - } -} - -func TestGetAltcoinMarketGraphData(t *testing.T) { - var threeMonths int64 = (60 * 60 * 24 * 90) - end := time.Now().Unix() - start := end - threeMonths - - graph, err := GetAltcoinMarketGraphData(start, end) - if err != nil { - t.FailNow() - } - - if graph.MarketCapByAvailableSupply[0][0] == 0 { - t.FailNow() - } - - if graph.VolumeUSD[0][0] == 0 { - t.FailNow() - } -} - -func TestGetCoinData(t *testing.T) { - coin, err := GetCoinData("ethereum") - if err != nil { - t.FailNow() - } - - if coin.AvailableSupply == 0 { - t.FailNow() - } - if coin.ID == "" { - t.FailNow() - } - if coin.LastUpdated == "" { - t.FailNow() - } - if coin.MarketCapUSD == 0 { - t.FailNow() - } - if coin.Name == "" { - t.FailNow() - } - if coin.PercentChange1H == 0 { - t.FailNow() - } - if coin.PercentChange24H == 0 { - t.FailNow() - } - if coin.PercentChange7D == 0 { - t.FailNow() - } - if coin.PriceBTC == 0 { - t.FailNow() - } - if coin.PriceUSD == 0 { - t.FailNow() - } - if coin.Rank == 0 { - t.FailNow() - } - if coin.Symbol == "" { - t.FailNow() - } - if coin.TotalSupply == 0 { - t.FailNow() - } - if coin.USD24HVolume == 0 { - t.FailNow() - } -} - -func TestGetAllCoinData(t *testing.T) { - coins, err := GetAllCoinData(10) - if err != nil { - t.FailNow() - } - - if len(coins) != 10 { - t.FailNow() - } -} - -func TestGetCoinGraphData(t *testing.T) { - var threeMonths int64 = (60 * 60 * 24 * 90) - end := time.Now().Unix() - start := end - threeMonths - - graph, err := GetCoinGraphData("ethereum", start, end) - if err != nil { - t.FailNow() - } - - if graph.MarketCapByAvailableSupply[0][0] == 0 { - t.FailNow() - } - if graph.PriceBTC[0][0] == 0 { - t.FailNow() - } - if graph.PriceUSD[0][0] == 0 { - t.FailNow() - } - if graph.VolumeUSD[0][0] == 0 { - t.FailNow() - } -} - -func TestGetCoinPriceUSD(t *testing.T) { - price, err := GetCoinPriceUSD("ethereum") - if err != nil { - t.FailNow() - } - if price <= 0 { - t.FailNow() - } -} - -func TestGetCoinMarkets(t *testing.T) { - markets, err := GetCoinMarkets("ethereum") - if err != nil { - t.FailNow() - } - if len(markets) == 0 { - t.FailNow() - } - - market := markets[0] - if market.Rank == 0 { - t.FailNow() - } - if market.Exchange == "" { - t.FailNow() - } - if market.Pair == "" { - t.FailNow() - } - if market.VolumeUSD == 0 { - t.FailNow() - } - if market.Price == 0 { - t.FailNow() - } - if market.VolumePercent == 0 { - t.FailNow() - } - if market.Updated == "" { - } -} - -func TestDoReq(t *testing.T) { - // TODO -} - -func TestMakeReq(t *testing.T) { - // TODO -} - -func TestToInt(t *testing.T) { - v := toInt("5") - if v != 5 { - t.FailNow() - } -} - -func TestToFloat(t *testing.T) { - v := toFloat("5.2") - if v != 5.2 { - t.FailNow() - } -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/example/all_coins.go b/vendor/github.com/miguelmota/go-coinmarketcap/example/all_coins.go deleted file mode 100644 index 33f8be6..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/example/all_coins.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "fmt" - "log" - - cmc "github.com/miguelmota/go-coinmarketcap" -) - -func main() { - // get data for all coins - coins, err := cmc.GetAllCoinData(0) - if err != nil { - log.Fatal(err) - } - - for _, coin := range coins { - fmt.Println(coin.Symbol, coin.PriceUSD) - } -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/example/coin.go b/vendor/github.com/miguelmota/go-coinmarketcap/example/coin.go deleted file mode 100644 index daad6ca..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/example/coin.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "fmt" - "log" - - cmc "github.com/miguelmota/go-coinmarketcap" -) - -func main() { - // Get info about coin - coinInfo, err := cmc.GetCoinData("ethereum") - if err != nil { - log.Fatal(err) - } - - fmt.Println(coinInfo) -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/example/coin_graph.go b/vendor/github.com/miguelmota/go-coinmarketcap/example/coin_graph.go deleted file mode 100644 index 1eee507..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/example/coin_graph.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "fmt" - "log" - "time" - - cmc "github.com/miguelmota/go-coinmarketcap" -) - -func main() { - threeMonths := int64(60 * 60 * 24 * 90) - now := time.Now() - secs := now.Unix() - start := secs - threeMonths - end := secs - - // Get graph data for coin - coinGraphData, err := cmc.GetCoinGraphData("ethereum", start, end) - if err != nil { - log.Fatal(err) - } - - fmt.Println(coinGraphData) -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/example/global_market.go b/vendor/github.com/miguelmota/go-coinmarketcap/example/global_market.go deleted file mode 100644 index d9cbafd..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/example/global_market.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "fmt" - "log" - - cmc "github.com/miguelmota/go-coinmarketcap" -) - -func main() { - // Get global market data - marketInfo, err := cmc.GetGlobalMarketData() - if err != nil { - log.Fatal(err) - } - - fmt.Println(marketInfo) -} diff --git a/vendor/github.com/miguelmota/go-coinmarketcap/types.go b/vendor/github.com/miguelmota/go-coinmarketcap/types.go deleted file mode 100644 index 93fd77a..0000000 --- a/vendor/github.com/miguelmota/go-coinmarketcap/types.go +++ /dev/null @@ -1,66 +0,0 @@ -package coinmarketcap - -// Interface interface -type Interface interface { - GetGlobalMarketData() (GlobalMarketData, error) - GetGlobalMarketGraphData(start int64, end int64) (MarketGraph, error) - GetAltcoinMarketGraphData(start int64, end int64) (MarketGraph, error) - GetCoinData(coin string) (Coin, error) - GetAllCoinData(limit int) (map[string]Coin, error) - GetCoinGraphData(coin string, start int64, end int64) (CoinGraph, error) - GetCoinPriceUSD(coin string) (float64, error) - GetCoinMarkets(coin string) ([]Market, error) -} - -// Coin struct -type Coin struct { - ID string `json:"id"` - Name string `json:"name"` - Symbol string `json:"symbol"` - Rank int `json:"rank,string"` - PriceUSD float64 `json:"price_usd,string"` - PriceBTC float64 `json:"price_btc,string"` - USD24HVolume float64 `json:"24h_volume_usd,string"` - MarketCapUSD float64 `json:"market_cap_usd,string"` - AvailableSupply float64 `json:"available_supply,string"` - TotalSupply float64 `json:"total_supply,string"` - PercentChange1H float64 `json:"percent_change_1h,string"` - PercentChange24H float64 `json:"percent_change_24h,string"` - PercentChange7D float64 `json:"percent_change_7d,string"` - LastUpdated string `json:"last_updated"` -} - -// GlobalMarketData struct -type GlobalMarketData struct { - TotalMarketCapUSD float64 `json:"total_market_cap_usd"` - Total24HVolumeUSD float64 `json:"total_24h_volume_usd"` - BitcoinPercentageOfMarketCap float64 `json:"bitcoin_percentage_of_market_cap"` - ActiveCurrencies int `json:"active_currencies"` - ActiveAssets int `json:"active_assets"` - ActiveMarkets int `json:"active_markets"` -} - -// CoinGraph struct -type CoinGraph struct { - MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"` - PriceBTC [][]float64 `json:"price_btc"` - PriceUSD [][]float64 `json:"price_usd"` - VolumeUSD [][]float64 `json:"volume_usd"` -} - -// Market struct -type Market struct { - Rank int - Exchange string - Pair string - VolumeUSD float64 - Price float64 - VolumePercent float64 - Updated string -} - -// MarketGraph struct -type MarketGraph struct { - MarketCapByAvailableSupply [][]float64 `json:"market_cap_by_available_supply"` - VolumeUSD [][]float64 `json:"volume_usd"` -}