github.com/0xPolygon/supernets2-node@v0.0.0-20230711153321-2fe574524eaa/pricegetter/pricegetter.go (about)

     1  package pricegetter
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math/big"
     7  	"time"
     8  
     9  	"github.com/0xPolygon/supernets2-node/log"
    10  	"github.com/0xPolygon/supernets2-node/pricegetter/priceprovider"
    11  	"github.com/0xPolygon/supernets2-node/pricegetter/priceprovider/uniswap"
    12  )
    13  
    14  // Client for the pricegetter
    15  type Client interface {
    16  	// Start price getter client
    17  	Start(ctx context.Context)
    18  	// GetEthToMaticPrice getting eth to matic price
    19  	GetEthToMaticPrice(ctx context.Context) (*big.Float, error)
    20  }
    21  
    22  // NewClient inits price getter client
    23  func NewClient(cfg Config) (Client, error) {
    24  	var (
    25  		priceProvider priceprovider.PriceProvider
    26  		err           error
    27  	)
    28  	switch cfg.PriceProvider.Type {
    29  	case priceprovider.UniswapType:
    30  		priceProvider, err = uniswap.NewPriceProvider(cfg.PriceProvider.URL)
    31  		if err != nil {
    32  			return nil, err
    33  		}
    34  	}
    35  	switch cfg.Type {
    36  	case SyncType:
    37  		return &syncClient{priceProvider: priceProvider}, nil
    38  	case AsyncType:
    39  		return &asyncClient{
    40  			cfg:           cfg,
    41  			priceProvider: priceProvider,
    42  			price:         nil,
    43  			lastUpdated:   time.Time{},
    44  		}, nil
    45  	case DefaultType:
    46  		return &defaultClient{defaultPrice: cfg.DefaultPrice.Float}, nil
    47  	}
    48  	return nil, fmt.Errorf("pricegetter type is not specified")
    49  }
    50  
    51  // defaultClient using default price set by config
    52  type defaultClient struct {
    53  	defaultPrice *big.Float
    54  }
    55  
    56  // GetEthToMaticPrice getting default price
    57  func (c *defaultClient) GetEthToMaticPrice(ctx context.Context) (*big.Float, error) {
    58  	return c.defaultPrice, nil
    59  }
    60  
    61  // Start function for default client
    62  func (c *defaultClient) Start(ctx context.Context) {}
    63  
    64  // syncClient using synchronous request
    65  type syncClient struct {
    66  	priceProvider priceprovider.PriceProvider
    67  }
    68  
    69  // GetEthToMaticPrice getting price from the price provider
    70  func (c *syncClient) GetEthToMaticPrice(ctx context.Context) (*big.Float, error) {
    71  	return c.priceProvider.GetEthToMaticPrice(ctx)
    72  }
    73  
    74  // Start starting sync client
    75  func (c *syncClient) Start(ctx context.Context) {}
    76  
    77  // asyncClient
    78  type asyncClient struct {
    79  	cfg           Config
    80  	priceProvider priceprovider.PriceProvider
    81  	price         *big.Float
    82  	lastUpdated   time.Time
    83  }
    84  
    85  // SyncPrice syncing price with the price provider every n second
    86  func (c *asyncClient) syncPrice(ctx context.Context) {
    87  	ticker := time.NewTicker(c.cfg.UpdateFrequency.Duration)
    88  	defer ticker.Stop()
    89  	var err error
    90  	for {
    91  		c.price, err = c.priceProvider.GetEthToMaticPrice(ctx)
    92  		if err != nil {
    93  			log.Errorf("failed to get price matic price, err: %v", err)
    94  		} else {
    95  			c.lastUpdated = time.Now()
    96  		}
    97  		select {
    98  		case <-ticker.C:
    99  			// nothing
   100  		case <-ctx.Done():
   101  			return
   102  		}
   103  	}
   104  }
   105  
   106  // GetEthToMaticPrice get price, that is syncing every n second
   107  func (c *asyncClient) GetEthToMaticPrice(ctx context.Context) (*big.Float, error) {
   108  	return c.price, nil
   109  }
   110  
   111  func (c *asyncClient) Start(ctx context.Context) {
   112  	go c.syncPrice(ctx)
   113  }