github.com/0chain/gosdk@v1.17.11/core/tokenrate/bancor.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 bancorQuoteQuery struct {
    17  }
    18  
    19  func (qq *bancorQuoteQuery) getUSD(ctx context.Context, symbol string) (float64, error) {
    20  
    21  	var result bancorResponse
    22  
    23  	s := strings.ToLower(symbol)
    24  	var dltId string
    25  	//
    26  	switch s {
    27  	case "zcn":
    28  		dltId = "0xb9EF770B6A5e12E45983C5D80545258aA38F3B78"
    29  	case "eth":
    30  		dltId = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"
    31  	default:
    32  		evnName := "BANCOR_DLTID_" + strings.ToUpper(symbol)
    33  		id, ok := os.LookupEnv(evnName)
    34  		if !ok {
    35  			return 0, errors.New("bancor: please configure dlt_id on environment variable [" + evnName + "] first")
    36  		}
    37  		dltId = id
    38  	}
    39  
    40  	r := resty.New()
    41  	r.DoGet(ctx, "https://api-v3.bancor.network/tokens?dlt_id="+dltId).
    42  		Then(func(req *http.Request, resp *http.Response, respBody []byte, cf context.CancelFunc, err error) error {
    43  
    44  			if err != nil {
    45  				return err
    46  			}
    47  
    48  			if resp.StatusCode != http.StatusOK {
    49  				return errors.New("bancor: " + strconv.Itoa(resp.StatusCode) + resp.Status)
    50  			}
    51  
    52  			err = json.Unmarshal(respBody, &result)
    53  			if err != nil {
    54  				return err
    55  			}
    56  
    57  			result.Raw = string(respBody)
    58  
    59  			return nil
    60  
    61  		})
    62  
    63  	errs := r.Wait()
    64  	if len(errs) > 0 {
    65  		return 0, errs[0]
    66  	}
    67  
    68  	rate, ok := result.Data.Rate24hAgo["usd"]
    69  
    70  	if ok {
    71  
    72  		if rate.Value > 0 {
    73  			return rate.Value, nil
    74  		}
    75  
    76  		//rate24ago is invalid, try get current rate
    77  		rate, ok = result.Data.Rate["usd"]
    78  		if ok && rate.Value > 0 {
    79  			return rate.Value, nil
    80  		}
    81  	}
    82  
    83  	return 0, fmt.Errorf("bancor: %s price is not provided on bancor apis", symbol)
    84  }
    85  
    86  // {
    87  // 	"data": {
    88  // 			"dltId": "0xb9EF770B6A5e12E45983C5D80545258aA38F3B78",
    89  // 			"symbol": "ZCN",
    90  // 			"decimals": 10,
    91  // 			"rate": {
    92  // 					"bnt": "0.271257342312491431",
    93  // 					"usd": "0.118837",
    94  // 					"eur": "0.121062",
    95  // 					"eth": "0.000089243665620809"
    96  // 			},
    97  // 			"rate24hAgo": {
    98  // 					"bnt": "0.273260935543748855",
    99  // 					"usd": "0.120972",
   100  // 					"eur": "0.126301",
   101  // 					"eth": "0.000094001761827049"
   102  // 			}
   103  // 	},
   104  // 	"timestamp": {
   105  // 			"ethereum": {
   106  // 					"block": 15644407,
   107  // 					"timestamp": 1664519843
   108  // 			}
   109  // 	}
   110  // }
   111  
   112  type bancorResponse struct {
   113  	Data bancorMarketData `json:"data"`
   114  	Raw  string           `json:"-"`
   115  }
   116  
   117  type bancorMarketData struct {
   118  	Rate       map[string]Float64 `json:"rate"`
   119  	Rate24hAgo map[string]Float64 `json:"rate24hAgo"`
   120  }
   121  
   122  type Float64 struct {
   123  	Value float64
   124  }
   125  
   126  func (s *Float64) UnmarshalJSON(data []byte) error {
   127  
   128  	if data == nil {
   129  		s.Value = 0
   130  		return nil
   131  	}
   132  
   133  	js := strings.Trim(string(data), "\"")
   134  
   135  	v, err := strconv.ParseFloat(js, 64)
   136  	if err != nil {
   137  		return err
   138  	}
   139  
   140  	s.Value = v
   141  	return nil
   142  
   143  }