From c734165400706b361a7ea777b12a1193a6aa3d3f Mon Sep 17 00:00:00 2001 From: Daniel Wasserman Date: Wed, 20 Dec 2023 12:09:32 -0600 Subject: [PATCH] WIP: remove coingecko price fetching for now; add TokenConfig with USD price param --- services/rfq/relayer/quoter/fee_pricer.go | 48 +++++++---------------- services/rfq/relayer/relconfig/config.go | 15 +++++-- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/services/rfq/relayer/quoter/fee_pricer.go b/services/rfq/relayer/quoter/fee_pricer.go index 673cfb48eb..c2eb465a1a 100644 --- a/services/rfq/relayer/quoter/fee_pricer.go +++ b/services/rfq/relayer/quoter/fee_pricer.go @@ -2,11 +2,8 @@ package quoter import ( "context" - "encoding/json" "fmt" - "io" "math/big" - "net/http" "time" "github.com/jellydator/ttlcache/v3" @@ -28,27 +25,27 @@ type FeePricer interface { } type feePricer struct { + // config is the fee pricer config. config relconfig.FeePricerConfig + // tokenConfigs maps chain ID -> chain config. + chainConfigs map[int]relconfig.ChainConfig // gasPriceCache maps chainID -> gas price gasPriceCache *ttlcache.Cache[uint32, *big.Int] // tokenPriceCache maps token name -> token price tokenPriceCache *ttlcache.Cache[string, *big.Int] - omniClient omnirpcClient.RPCClient - httpClient *http.Client + // omnirpcClient is the omnirpc client. + omniClient omnirpcClient.RPCClient } -const coingeckoURL = "https://api.coingecko.com/api/v3/simple/price?vs_currencies=USD&ids=" - // NewFeePricer creates a new fee pricer. -func NewFeePricer(config relconfig.FeePricerConfig, omnirpcURL string, metricHandler metrics.Handler) FeePricer { +func NewFeePricer(config relconfig.FeePricerConfig, chainConfigs map[int]relconfig.ChainConfig, omnirpcURL string, metricHandler metrics.Handler) FeePricer { omniClient := omnirpcClient.NewOmnirpcClient(omnirpcURL, metricHandler, omnirpcClient.WithCaptureReqRes()) - httpClient := &http.Client{Timeout: time.Duration(config.RequestTimeoutMs) * time.Millisecond} return &feePricer{ config: config, + chainConfigs: chainConfigs, gasPriceCache: ttlcache.New[uint32, *big.Int](ttlcache.WithTTL[uint32, *big.Int](time.Second * time.Duration(config.GasPriceCacheTTL))), tokenPriceCache: ttlcache.New[string, *big.Int](ttlcache.WithTTL[string, *big.Int](time.Second * time.Duration(config.TokenPriceCacheTTL))), omniClient: omniClient, - httpClient: httpClient, } } @@ -158,32 +155,15 @@ func (f *feePricer) getGasPrice(ctx context.Context, chainID uint32) (*big.Int, // getTokenPrice returns the price of a token in USD. func (f *feePricer) getTokenPrice(ctx context.Context, token string) (float64, error) { - resp, err := f.httpClient.Get(fmt.Sprintf("%s%s", coingeckoURL, token)) - if err != nil { - return 0, err - } - if resp.StatusCode != http.StatusOK { - err = fmt.Errorf("bad status code: %v", resp.Status) - return 0, err - } - defer resp.Body.Close() - respBytes, err := io.ReadAll(resp.Body) - if err != nil { - err = fmt.Errorf("could not read response: %w", err) - return 0, err - } - var result map[string]map[string]float64 - err = json.Unmarshal(respBytes, &result) - if err != nil { - err = fmt.Errorf("could not unmarshal response: %w", err) - return 0, err - } - for _, val := range result { - for _, num := range val { - return num, nil + for _, chainConfig := range f.chainConfigs { + for tokenID, tokenConfig := range chainConfig.Tokens { + if token == tokenID { + return tokenConfig.PriceUSD, nil + } + } } - return 0, fmt.Errorf("could not get token price") + return 0, fmt.Errorf("could not get price for token: %s", token) } func (f *feePricer) getTokenDecimals(chainID uint32, token string) (uint8, error) { diff --git a/services/rfq/relayer/relconfig/config.go b/services/rfq/relayer/relconfig/config.go index 1ff8eb46c7..9d42b3813c 100644 --- a/services/rfq/relayer/relconfig/config.go +++ b/services/rfq/relayer/relconfig/config.go @@ -37,6 +37,18 @@ type ChainConfig struct { Bridge string `yaml:"address"` // Confirmations is the number of required confirmations Confirmations uint64 `yaml:"confirmations"` + // Tokens is a map of token ID -> token config. + Tokens map[string]TokenConfig `yaml:"tokens"` + // NativeToken is the native token of the chain (pays gas). + NativeToken string `yaml:"native_token"` +} + +// TokenConfig represents the configuration for a token. +type TokenConfig struct { + // Address is the token address. + Address string `yaml:"address"` + // For now, specify the USD price of the token in the config. + PriceUSD float64 `yaml:"price_usd"` } // DatabaseConfig represents the configuration for the database. @@ -55,9 +67,6 @@ type FeePricerConfig struct { GasPriceCacheTTL int `yaml:"gas_price_cache_ttl"` // TokenPriceCacheTTL is the TTL for the token price cache. TokenPriceCacheTTL int `yaml:"token_price_cache_ttl"` - // Tokens is a map of chain id -> token address -> token name. - Tokens map[uint32]map[string]string `yaml:"tokens"` - RequestTimeoutMs int `yaml:"request_timeout_ms"` } // LoadConfig loads the config from the given path.