126 lines
3.2 KiB
Go
126 lines
3.2 KiB
Go
package prices
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/wormhole-foundation/wormhole-explorer/common/types"
|
|
sdk "github.com/wormhole-foundation/wormhole/sdk/vaa"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type Controller struct {
|
|
priceService *PriceService
|
|
logger *zap.Logger
|
|
}
|
|
|
|
func NewController(priceService *PriceService, logger *zap.Logger) *Controller {
|
|
return &Controller{
|
|
priceService: priceService,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
func (c *Controller) FindByToken(ctx *fiber.Ctx) error {
|
|
chainID, err := extractChainID(ctx, c.logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tokenAddress, err := extractTokenAddress(ctx, c.logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dateTime, err := extractDatetime(ctx, c.logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
price, err := c.priceService.GetPrice(ctx.Context(), *chainID, tokenAddress.Hex(), *dateTime)
|
|
|
|
return c.handleResponse(err, ctx, price)
|
|
}
|
|
|
|
func (c *Controller) FindByCoingeckoID(ctx *fiber.Ctx) error {
|
|
coingeckoID, err := extractCoingeckoID(ctx, c.logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dateTime, err := extractDatetime(ctx, c.logger)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
price, err := c.priceService.GetPriceByCoingeckoID(ctx.Context(), coingeckoID, *dateTime)
|
|
|
|
return c.handleResponse(err, ctx, price)
|
|
}
|
|
|
|
func (*Controller) handleResponse(err error, ctx *fiber.Ctx, price *Price) error {
|
|
if err != nil {
|
|
if errors.Is(err, ErrTokenNotFound) {
|
|
return fiber.NewError(fiber.StatusNotFound, "token not found")
|
|
}
|
|
return err
|
|
}
|
|
|
|
return ctx.JSON(price)
|
|
}
|
|
|
|
func extractCoingeckoID(c *fiber.Ctx, l *zap.Logger) (string, error) {
|
|
param := c.Params("coingeckoId")
|
|
if param == "" {
|
|
return "", fiber.NewError(fiber.StatusBadRequest, "missing coingeckoId parameter")
|
|
}
|
|
return param, nil
|
|
}
|
|
|
|
func extractChainID(c *fiber.Ctx, l *zap.Logger) (*sdk.ChainID, error) {
|
|
param := c.Params("tokenChainId")
|
|
if param == "" {
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "missing tokenChainId parameter")
|
|
}
|
|
|
|
chain, err := strconv.ParseInt(param, 10, 16)
|
|
if err != nil {
|
|
l.Error("failed to parse tokenChainId parameter",
|
|
zap.Error(err),
|
|
)
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "invalid chain id parameter")
|
|
}
|
|
result := sdk.ChainID(chain)
|
|
return &result, nil
|
|
}
|
|
|
|
func extractTokenAddress(c *fiber.Ctx, l *zap.Logger) (*types.Address, error) {
|
|
tokenAddressStr := c.Params("tokenAddress")
|
|
tokenAddress, err := types.StringToAddress(tokenAddressStr, true)
|
|
if err != nil {
|
|
l.Error("failed to convert token address to wormhole address",
|
|
zap.Error(err),
|
|
zap.String("tokenAddressStr", tokenAddressStr))
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "invalid token address")
|
|
}
|
|
|
|
return tokenAddress, nil
|
|
}
|
|
|
|
func extractDatetime(c *fiber.Ctx, l *zap.Logger) (*time.Time, error) {
|
|
datetime := c.Params("datetime")
|
|
if datetime == "" {
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "missing datetime parameter")
|
|
}
|
|
v, err := time.Parse(time.RFC3339, datetime)
|
|
if err != nil {
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "invalid datetime parameter")
|
|
}
|
|
if v.After(time.Now()) {
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "datetime must be in the past")
|
|
}
|
|
return &v, nil
|
|
}
|