package oracle import ( "math/big" "strings" "github.com/tech/sendico/fx/storage/model" "github.com/tech/sendico/pkg/decimal" "github.com/tech/sendico/pkg/merrors" fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1" ) // Convenience aliases to pkg/decimal for backward compatibility var ( ratFromString = decimal.RatFromString mulRat = decimal.MulRat divRat = decimal.DivRat formatRat = decimal.FormatRat ) // roundRatToScale wraps pkg/decimal.RoundRatToScale with model RoundingMode conversion func roundRatToScale(value *big.Rat, scale uint32, mode model.RoundingMode) (*big.Rat, error) { return decimal.RoundRatToScale(value, scale, convertRoundingMode(mode)) } // convertRoundingMode converts fx/storage model.RoundingMode to pkg/decimal.RoundingMode func convertRoundingMode(mode model.RoundingMode) decimal.RoundingMode { switch mode { case model.RoundingModeHalfEven: return decimal.RoundingModeHalfEven case model.RoundingModeHalfUp: return decimal.RoundingModeHalfUp case model.RoundingModeDown: return decimal.RoundingModeDown case model.RoundingModeUnspecified: return decimal.RoundingModeUnspecified default: return decimal.RoundingModeHalfEven } } func priceFromRate(rate *model.RateSnapshot, side fxv1.Side) (*big.Rat, error) { var priceStr string switch side { case fxv1.Side_BUY_BASE_SELL_QUOTE: priceStr = rate.Ask case fxv1.Side_SELL_BASE_BUY_QUOTE: priceStr = rate.Bid default: priceStr = "" } if strings.TrimSpace(priceStr) == "" { priceStr = rate.Mid } if strings.TrimSpace(priceStr) == "" { return nil, merrors.InvalidArgument("oracle: rate snapshot missing price") } return ratFromString(priceStr) }