From de5ecc5fe76fb9d0c07be99d21f1bb315d5a3cdb Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Thu, 14 Nov 2024 21:21:04 +0300 Subject: [PATCH] add the tokens functionality to the common package --- common/tokens.go | 54 +++++++++++++++++++++++++++ internal/handlers/ussd/menuhandler.go | 49 +++++++++--------------- 2 files changed, 71 insertions(+), 32 deletions(-) create mode 100644 common/tokens.go diff --git a/common/tokens.go b/common/tokens.go new file mode 100644 index 0000000..727cbea --- /dev/null +++ b/common/tokens.go @@ -0,0 +1,54 @@ +package common + +import ( + "context" + "math/big" + "strconv" +) + +func ParseAndScaleAmount(storedAmount, activeDecimal []byte) (string, error) { + // Parse token decimal + tokenDecimal, err := strconv.Atoi(string(activeDecimal)) + if err != nil { + + return "", err + } + + // Parse amount + amount, _, err := big.ParseFloat(string(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) + + // Convert finalAmount to a string + finalAmountStr := new(big.Int) + finalAmount.Int(finalAmountStr) + + return finalAmountStr.String(), nil +} + +func ReadTransactionData(ctx context.Context, store DataStore, sessionId string) (map[DataTyp][]byte, error) { + dataKeys := []DataTyp{ + DATA_TEMPORARY_VALUE, + DATA_ACTIVE_SYM, + DATA_AMOUNT, + DATA_PUBLIC_KEY, + DATA_RECIPIENT, + DATA_ACTIVE_DECIMAL, + DATA_ACTIVE_ADDRESS, + } + + data := make(map[DataTyp][]byte) + for _, key := range dataKeys { + value, err := store.ReadEntry(ctx, sessionId, key) + if err != nil { + return nil, err + } + data[key] = value + } + return data, nil +} diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index 00c6ad7..d2411bd 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "math/big" "path" "regexp" "strconv" @@ -1176,7 +1175,7 @@ func (h *Handlers) GetSender(ctx context.Context, sym string, input []byte) (res return res, fmt.Errorf("missing session") } - res.Content = string(sessionId) + res.Content = sessionId return res, nil } @@ -1205,8 +1204,7 @@ func (h *Handlers) GetAmount(ctx context.Context, sym string, input []byte) (res return res, nil } -// InitiateTransaction returns a confirmation and resets the transaction data -// on the gdbm store. +// InitiateTransaction calls the TokenTransfer and returns a confirmation based on the result func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) { var res resource.Result var err error @@ -1215,57 +1213,44 @@ func (h *Handlers) InitiateTransaction(ctx context.Context, sym string, input [] return res, fmt.Errorf("missing session") } - flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error") - account_authorized_flag, _ := h.flagManager.GetFlag("flag_account_authorized") + flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") code := codeFromCtx(ctx) l := gotext.NewLocale(translationDir, code) l.AddDomain("default") - store := h.userdataStore - recipientNumber, _ := store.ReadEntry(ctx, sessionId, common.DATA_TEMPORARY_VALUE) - activeSym, _ := store.ReadEntry(ctx, sessionId, common.DATA_ACTIVE_SYM) - - storedAmount, _ := store.ReadEntry(ctx, sessionId, common.DATA_AMOUNT) - fromAddress, _ := store.ReadEntry(ctx, sessionId, common.DATA_PUBLIC_KEY) - toAddress, _ := store.ReadEntry(ctx, sessionId, common.DATA_RECIPIENT) - activeDecimal, _ := store.ReadEntry(ctx, sessionId, common.DATA_ACTIVE_DECIMAL) - tokenAddress, _ := store.ReadEntry(ctx, sessionId, common.DATA_ACTIVE_ADDRESS) - - // Parse tokendecimal - tokenDecimal, err := strconv.Atoi(string(activeDecimal)) + data, err := common.ReadTransactionData(ctx, h.userdataStore, sessionId) if err != nil { return res, err } - // Parse amount and scale it - amount, _, err := big.ParseFloat(string(storedAmount), 10, 0, big.ToZero) + finalAmountStr, err := common.ParseAndScaleAmount(data[common.DATA_AMOUNT], data[common.DATA_ACTIVE_DECIMAL]) if err != nil { return res, err } - multiplier := new(big.Float).SetInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenDecimal)), nil)) - finalAmount := new(big.Float).Mul(amount, multiplier) - - // Convert finalAmount to a string - finalAmountStr := new(big.Int) - finalAmount.Int(finalAmountStr) - // Call TokenTransfer - r, err := h.accountService.TokenTransfer(ctx, finalAmountStr.String(), string(fromAddress), string(toAddress), string(tokenAddress)) + r, err := h.accountService.TokenTransfer(ctx, finalAmountStr, string(data[common.DATA_PUBLIC_KEY]), string(data[common.DATA_RECIPIENT]), string(data[common.DATA_ACTIVE_ADDRESS])) if err != nil { - res.Content = l.Get("Your request failed. Please try again later.") + flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error") res.FlagSet = append(res.FlagSet, flag_api_error) + res.Content = l.Get("Your request failed. Please try again later.") logg.ErrorCtxf(ctx, "failed on TokenTransfer", "error", err) - return res, err + return res, nil } trackingId := r.TrackingId logg.InfoCtxf(ctx, "TokenTransfer", "trackingId", trackingId) - res.Content = l.Get("Your request has been sent. %s will receive %s %s from %s.", string(recipientNumber), string(storedAmount), string(activeSym), string(sessionId)) + res.Content = l.Get( + "Your request has been sent. %s will receive %s %s from %s.", + string(data[common.DATA_TEMPORARY_VALUE]), + string(data[common.DATA_AMOUNT]), + string(data[common.DATA_ACTIVE_SYM]), + sessionId, + ) - res.FlagReset = append(res.FlagReset, account_authorized_flag) + res.FlagReset = append(res.FlagReset, flag_account_authorized) return res, nil }