113 lines
2.8 KiB
Go
113 lines
2.8 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
|
|
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
)
|
|
|
|
type TransactionData struct {
|
|
TemporaryValue string
|
|
ActiveSym string
|
|
Amount string
|
|
PublicKey string
|
|
Recipient string
|
|
ActiveDecimal string
|
|
ActiveAddress string
|
|
}
|
|
|
|
// TruncateDecimalString safely truncates (not rounds) a number string to the specified decimal places
|
|
func TruncateDecimalString(input string, decimalPlaces int) (string, error) {
|
|
if _, err := strconv.ParseFloat(input, 64); err != nil {
|
|
return "", fmt.Errorf("invalid input")
|
|
}
|
|
|
|
// Split input into integer and fractional parts
|
|
parts := strings.SplitN(input, ".", 2)
|
|
intPart := parts[0]
|
|
var fracPart string
|
|
|
|
if len(parts) == 2 {
|
|
fracPart = parts[1]
|
|
}
|
|
|
|
// Truncate or pad fractional part
|
|
if len(fracPart) > decimalPlaces {
|
|
fracPart = fracPart[:decimalPlaces]
|
|
} else {
|
|
fracPart = fracPart + strings.Repeat("0", decimalPlaces-len(fracPart))
|
|
}
|
|
|
|
// Handle zero decimal places
|
|
if decimalPlaces == 0 {
|
|
return intPart, nil
|
|
}
|
|
|
|
return fmt.Sprintf("%s.%s", intPart, fracPart), nil
|
|
}
|
|
|
|
func ParseAndScaleAmount(storedAmount, activeDecimal string) (string, error) {
|
|
// Parse token decimal
|
|
tokenDecimal, err := strconv.Atoi(activeDecimal)
|
|
if err != nil {
|
|
|
|
return "", err
|
|
}
|
|
|
|
// Parse amount
|
|
amount, _, err := big.ParseFloat(storedAmount, 10, 0, big.ToZero)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Scale the amount
|
|
multiplier := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenDecimal)), nil))
|
|
finalAmount := new(big.Float).Mul(amount, multiplier)
|
|
|
|
// Return finalAmount as a string with 0 decimal places (rounded)
|
|
return finalAmount.Text('f', 0), nil
|
|
}
|
|
|
|
func ReadTransactionData(ctx context.Context, store DataStore, sessionId string) (TransactionData, error) {
|
|
data := TransactionData{}
|
|
fieldToKey := map[string]storedb.DataTyp{
|
|
"TemporaryValue": storedb.DATA_TEMPORARY_VALUE,
|
|
"ActiveSym": storedb.DATA_ACTIVE_SYM,
|
|
"Amount": storedb.DATA_AMOUNT,
|
|
"PublicKey": storedb.DATA_PUBLIC_KEY,
|
|
"Recipient": storedb.DATA_RECIPIENT,
|
|
"ActiveDecimal": storedb.DATA_ACTIVE_DECIMAL,
|
|
"ActiveAddress": storedb.DATA_ACTIVE_ADDRESS,
|
|
}
|
|
|
|
v := reflect.ValueOf(&data).Elem()
|
|
for fieldName, key := range fieldToKey {
|
|
field := v.FieldByName(fieldName)
|
|
if !field.IsValid() || !field.CanSet() {
|
|
return data, errors.New("invalid struct field: " + fieldName)
|
|
}
|
|
|
|
value, err := ReadStringEntry(ctx, store, sessionId, key)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
field.SetString(value)
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func ReadStringEntry(ctx context.Context, store DataStore, sessionId string, key storedb.DataTyp) (string, error) {
|
|
entry, err := store.ReadEntry(ctx, sessionId, key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return string(entry), nil
|
|
}
|