github.com/NpoolPlatform/chain-middleware@v0.0.0-20240228100535-eb1bcf896eb9/pkg/currency/coingecko/coingecko.go (about) 1 package coingecko 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 "strings" 8 "time" 9 10 "github.com/NpoolPlatform/go-service-framework/pkg/logger" 11 12 "github.com/shopspring/decimal" 13 14 "github.com/go-resty/resty/v2" 15 ) 16 17 const ( 18 coinAPI = "https://api.coingecko.com/api/v3" 19 timeout = 5 20 ) 21 22 func CoinGeckoPrices(coinNames, fiatNames []string) (map[string]map[string]decimal.Decimal, error) { 23 if len(coinNames) == 0 { 24 return nil, fmt.Errorf("invalid coinnames") 25 } 26 27 coins := strings.Join(coinNames, ",") 28 fiats := strings.Join(fiatNames, ",") 29 30 socksProxy := os.Getenv("ENV_CURRENCY_REQUEST_PROXY") 31 url := fmt.Sprintf("%v%v?ids=%v&vs_currencies=%v", coinAPI, "/simple/price", coins, fiats) 32 cli := resty.New() 33 cli = cli.SetTimeout(timeout * time.Second) 34 if socksProxy != "" { 35 cli = cli.SetProxy(socksProxy) 36 } 37 38 logger.Sugar().Errorw( 39 "CoinGeckoPrices", 40 "URL", url, 41 "Proxy", socksProxy, 42 "Timeout", timeout, 43 ) 44 45 resp, err := cli.R().Get(url) 46 if err != nil { 47 logger.Sugar().Errorw( 48 "CoinGeckoPrices", 49 "URL", url, 50 "Proxy", socksProxy, 51 "Error", err, 52 ) 53 return nil, err 54 } 55 respMap := map[string]map[string]float64{} 56 err = json.Unmarshal(resp.Body(), &respMap) 57 if err != nil { 58 logger.Sugar().Errorw( 59 "CoinGeckoPrices", 60 "URL", url, 61 "Proxy", socksProxy, 62 "Resp", string(resp.Body()), 63 "Error", err, 64 ) 65 return nil, err 66 } 67 68 infoMap := map[string]map[string]decimal.Decimal{} 69 for key, val := range respMap { 70 _infoMap, ok := infoMap[key] 71 if !ok { 72 _infoMap = map[string]decimal.Decimal{} 73 } 74 for _key, _val := range val { 75 _infoMap[_key] = decimal.NewFromFloat(_val) 76 } 77 infoMap[key] = _infoMap 78 } 79 80 return infoMap, nil 81 } 82 83 func CoinGeckoUSDPrices(coinNames []string) (map[string]decimal.Decimal, error) { 84 prices, err := CoinGeckoPrices(coinNames, []string{"usd"}) 85 if err != nil { 86 return map[string]decimal.Decimal{}, err 87 } 88 89 _prices := map[string]decimal.Decimal{} 90 for key, val := range prices { 91 _prices[key] = val["usd"] 92 } 93 94 return _prices, nil 95 } 96 97 func CoinGeckoFiatPrices(fiatNames []string) (map[string]decimal.Decimal, error) { 98 socksProxy := os.Getenv("ENV_CURRENCY_REQUEST_PROXY") 99 fiats := strings.Join(fiatNames, ",") 100 url := fmt.Sprintf("%v%v?ids=usd&vs_currencies=%v", coinAPI, "/simple/price", fiats) 101 cli := resty.New() 102 cli = cli.SetTimeout(timeout * time.Second) 103 if socksProxy != "" { 104 cli = cli.SetProxy(socksProxy) 105 } 106 resp, err := cli.R().Get(url) 107 if err != nil { 108 logger.Sugar().Errorw( 109 "CoinGeckoFiatPrices", 110 "URL", url, 111 "Proxy", socksProxy, 112 "Error", err, 113 ) 114 return nil, err 115 } 116 117 respMap := map[string]map[string]float64{} 118 err = json.Unmarshal(resp.Body(), &respMap) 119 if err != nil { 120 logger.Sugar().Errorw( 121 "CoinGeckoFiatPrices", 122 "URL", url, 123 "Proxy", socksProxy, 124 "Resp", resp.Body(), 125 "Error", err, 126 ) 127 return nil, err 128 } 129 130 respMap1 := map[string]decimal.Decimal{} 131 if _, ok := respMap["usd"]; ok { 132 for key, val := range respMap["usd"] { 133 c := decimal.NewFromFloat(val) 134 respMap1[strings.ToLower(key)] = c 135 } 136 } 137 return respMap1, nil 138 }