github.com/trezor/blockbook@v0.4.1-0.20240328132726-e9a08582ee2c/common/currencyrateticker.go (about)

     1  package common
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  )
     7  
     8  // CurrencyRatesTicker contains coin ticker data fetched from API
     9  type CurrencyRatesTicker struct {
    10  	Timestamp  time.Time          `json:"timestamp"`            // return as unix timestamp in API
    11  	Rates      map[string]float32 `json:"rates"`                // rates of the base currency against a list of vs currencies
    12  	TokenRates map[string]float32 `json:"tokenRates,omitempty"` // rates of the tokens (identified by the address of the contract) against the base currency
    13  }
    14  
    15  var (
    16  	// TickerRecalculateTokenRate signals if it is necessary to recalculate token rate to base rate
    17  	// this happens when token rates are downloaded in TokenVsCurrency different from the base currency
    18  	TickerRecalculateTokenRate bool
    19  	// TickerTokenVsCurrency is the currency in which the token rates are downloaded
    20  	TickerTokenVsCurrency string
    21  )
    22  
    23  // Convert returns token rate in base currency
    24  func (t *CurrencyRatesTicker) GetTokenRate(token string) (float32, bool) {
    25  	if t.TokenRates != nil {
    26  		rate, found := t.TokenRates[strings.ToLower(token)]
    27  		if !found {
    28  			return 0, false
    29  		}
    30  		if TickerRecalculateTokenRate {
    31  			vsRate, found := t.Rates[TickerTokenVsCurrency]
    32  			if !found || vsRate == 0 {
    33  				return 0, false
    34  			}
    35  			rate = rate / vsRate
    36  		}
    37  		return rate, found
    38  	}
    39  	return 0, false
    40  }
    41  
    42  // Convert converts value in base currency to toCurrency
    43  func (t *CurrencyRatesTicker) Convert(baseValue float64, toCurrency string) float64 {
    44  	rate, found := t.Rates[toCurrency]
    45  	if !found {
    46  		return 0
    47  	}
    48  	return baseValue * float64(rate)
    49  }
    50  
    51  // ConvertTokenToBase converts token value to base currency
    52  func (t *CurrencyRatesTicker) ConvertTokenToBase(value float64, token string) float64 {
    53  	rate, found := t.GetTokenRate(token)
    54  	if found {
    55  		return value * float64(rate)
    56  	}
    57  	return 0
    58  }
    59  
    60  // ConvertTokenToBase converts token value to toCurrency currency
    61  func (t *CurrencyRatesTicker) ConvertToken(value float64, token string, toCurrency string) float64 {
    62  	baseValue := t.ConvertTokenToBase(value, token)
    63  	if baseValue > 0 {
    64  		return t.Convert(baseValue, toCurrency)
    65  	}
    66  	return 0
    67  }
    68  
    69  // TokenRateInCurrency return token rate in toCurrency currency
    70  func (t *CurrencyRatesTicker) TokenRateInCurrency(token string, toCurrency string) float32 {
    71  	rate, found := t.GetTokenRate(token)
    72  	if found {
    73  		baseRate, found := t.Rates[toCurrency]
    74  		if found {
    75  			return baseRate * rate
    76  		}
    77  	}
    78  	return 0
    79  }
    80  
    81  // IsSuitableTicker checks if the ticker can provide data for given vsCurrency or token
    82  func IsSuitableTicker(ticker *CurrencyRatesTicker, vsCurrency string, token string) bool {
    83  	if vsCurrency != "" {
    84  		if ticker.Rates == nil {
    85  			return false
    86  		}
    87  		if _, found := ticker.Rates[vsCurrency]; !found {
    88  			return false
    89  		}
    90  	}
    91  	if token != "" {
    92  		if ticker.TokenRates == nil {
    93  			return false
    94  		}
    95  		if _, found := ticker.TokenRates[token]; !found {
    96  			return false
    97  		}
    98  	}
    99  	return true
   100  }