github.com/wormhole-foundation/wormhole-explorer/common@v0.0.0-20240604151348-09585b5b97c5/prices/api.go (about)

     1  package prices
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"time"
     7  
     8  	"github.com/go-resty/resty/v2"
     9  	"github.com/shopspring/decimal"
    10  	"go.uber.org/zap"
    11  )
    12  
    13  type getPriceResponse struct {
    14  	CoingeckoID string `json:"coingeckoId"`
    15  	Symbol      string `json:"symbol"`
    16  	Price       string `json:"price"`
    17  	DateTime    string `json:"dateTime"`
    18  }
    19  
    20  type PricesApi struct {
    21  	client *resty.Client
    22  	log    *zap.Logger
    23  }
    24  
    25  func NewPricesApi(url string, log *zap.Logger) *PricesApi {
    26  	return &PricesApi{
    27  		client: resty.New().SetBaseURL(url),
    28  		log:    log,
    29  	}
    30  }
    31  
    32  func (n *PricesApi) GetPriceByTime(ctx context.Context, coingeckoID string, dateTime time.Time) (decimal.Decimal, error) {
    33  	url := fmt.Sprintf("/api/coingecko/prices/%s/%s", coingeckoID, dateTime.Format(time.RFC3339))
    34  	resp, err := n.client.R().
    35  		SetContext(ctx).
    36  		SetResult(&getPriceResponse{}).
    37  		Get(url)
    38  
    39  	if err != nil {
    40  		return decimal.Zero, err
    41  	}
    42  
    43  	if resp.IsError() {
    44  		return decimal.Zero, fmt.Errorf("status code: %s. %s", resp.Status(), string(resp.Body()))
    45  	}
    46  
    47  	result := resp.Result().(*getPriceResponse)
    48  	if result == nil {
    49  		return decimal.Zero, fmt.Errorf("empty response")
    50  	}
    51  
    52  	return decimal.NewFromString(result.Price)
    53  }