services/explorer/consumer/parser/utils.go
package parser
import (
"context"
"database/sql"
"fmt"
"math/big"
"strconv"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"gopkg.in/yaml.v2"
)
// ErrUnknownTopic is returned when the topic is unknown.
const ErrUnknownTopic = "unknown topic"
// Parser parses events and stores them.
type Parser interface {
// Parse parses the logs and returns the parsed data.
Parse(ctx context.Context, log ethTypes.Log, chainID uint32) (interface{}, error)
// ParserType returns the type of the parser.
ParserType() string
}
// BoolToUint8 is a helper function to handle bool to uint8 conversion for clickhouse.
func BoolToUint8(input *bool) *uint8 {
if input == nil {
return nil
}
if *input {
one := uint8(1)
return &one
}
zero := uint8(0)
return &zero
}
// ToNullString is a helper function to convert values to null string.
func ToNullString(str *string) sql.NullString {
var newNullStr sql.NullString
if str != nil {
newNullStr.Valid = true
newNullStr.String = *str
} else {
newNullStr.Valid = false
}
return newNullStr
}
// ToNullBool is a helper function to convert values to null bool.
func ToNullBool(b *bool) sql.NullBool {
var newNullBool sql.NullBool
if b != nil {
newNullBool.Valid = true
newNullBool.Bool = *b
} else {
newNullBool.Valid = false
}
return newNullBool
}
// ToNullInt64 is a helper function to convert values to null string.
func ToNullInt64[T int64 | uint64](val *T) sql.NullInt64 {
var newNullInt sql.NullInt64
if val != nil {
newNullInt.Valid = true
newNullInt.Int64 = int64(*val)
} else {
newNullInt.Valid = false
}
return newNullInt
}
// ToNullInt32 is a helper function to convert values to null string.
func ToNullInt32[T int32 | uint32](val *T) sql.NullInt32 {
var newNullInt sql.NullInt32
if val != nil {
newNullInt.Valid = true
newNullInt.Int32 = int32(*val)
} else {
newNullInt.Valid = false
}
return newNullInt
}
// ParseYaml opens yaml file with coin gecko ID mapping and returns it.
func ParseYaml(yamlFile []byte) (res map[string]string, err error) {
if err != nil {
return nil, fmt.Errorf("error opening yaml file %w", err)
}
err = yaml.Unmarshal(yamlFile, &res)
if err != nil {
return nil, fmt.Errorf("error unmarshalling yaml file %w", err)
}
return res, nil
}
// GetAmountUSD computes the USD value of a token amount.
func GetAmountUSD(amount *big.Int, decimals uint8, price *float64) *float64 {
decimalMultiplier := new(big.Float).SetInt(big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil))
adjustedAmount := new(big.Float).Quo(new(big.Float).SetInt(amount), decimalMultiplier)
trueAmount := big.NewFloat(0).Mul(adjustedAmount, big.NewFloat(*price))
trueAmountStr := trueAmount.SetMode(big.AwayFromZero).Text('f', 5)
priceFloat, err := strconv.ParseFloat(trueAmountStr, 64)
if err != nil {
return nil
}
return &priceFloat
}
// GetAdjustedAmount computes the adjusted token amount.
func GetAdjustedAmount(amount *big.Int, decimals uint8) *float64 {
decimalMultiplier := new(big.Float).SetInt(big.NewInt(0).Exp(big.NewInt(10), big.NewInt(int64(decimals)), nil))
adjustedAmount := new(big.Float).Quo(new(big.Float).SetInt(amount), decimalMultiplier)
trueAmountStr := adjustedAmount.SetMode(big.AwayFromZero).Text('f', 5)
fullAmount, err := strconv.ParseFloat(trueAmountStr, 64)
if err != nil {
return nil
}
return &fullAmount
}