Compare commits

..

No commits in common. "master" and "v1.4.6-rc.6" have entirely different histories.

45 changed files with 295 additions and 598 deletions

View File

@ -39,7 +39,7 @@ DEFAULT_MPESA_ASSET=cUSD
MPESA_BEARER_TOKEN=eyJeSIsInRcCI6IkpXVCJ.yJwdWJsaWNLZXkiOiIwrrrrrr MPESA_BEARER_TOKEN=eyJeSIsInRcCI6IkpXVCJ.yJwdWJsaWNLZXkiOiIwrrrrrr
MPESA_ONRAMP_BASE=https://pretium.v1.grassecon.net MPESA_ONRAMP_BASE=https://pretium.v1.grassecon.net
# Known stable voucher addresses (USDm, USD₮, USDC) # Known stable voucher addresses (USDm, USD₮)
STABLE_VOUCHER_ADDRESSES=0x765DE816845861e75A25fCA122bb6898B8B1282a,0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e,0xcebA9300f2b948710d2653dD7B07f33A8B32118C STABLE_VOUCHER_ADDRESSES=0x765DE816845861e75A25fCA122bb6898B8B1282a,0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e
DEFAULT_STABLE_VOUCHER_ADDRESS=0x765DE816845861e75A25fCA122bb6898B8B1282a DEFAULT_STABLE_VOUCHER_ADDRESS=0x765DE816845861e75A25fCA122bb6898B8B1282a
DEFAULT_STABLE_VOUCHER_DECIMALS=18 DEFAULT_STABLE_VOUCHER_DECIMALS=18

View File

@ -3,10 +3,12 @@ package application
import ( import (
"context" "context"
"fmt" "fmt"
"sort"
"strconv" "strconv"
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
"git.grassecon.net/grassrootseconomics/sarafu-vise/store" "git.grassecon.net/grassrootseconomics/sarafu-vise/store"
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db" storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
@ -112,6 +114,8 @@ func (h *MenuHandlers) CalculateCreditAndDebt(ctx context.Context, sym string, i
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
userStore := h.userdataStore
code := codeFromCtx(ctx) code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code) l := gotext.NewLocale(translationDir, code)
l.AddDomain("default") l.AddDomain("default")
@ -121,11 +125,13 @@ func (h *MenuHandlers) CalculateCreditAndDebt(ctx context.Context, sym string, i
// Fetch session data // Fetch session data
_, activeBal, activeSym, activeAddress, publicKey, activeDecimal, err := h.getSessionData(ctx, sessionId) _, activeBal, activeSym, activeAddress, publicKey, activeDecimal, err := h.getSessionData(ctx, sessionId)
if err != nil { if err != nil {
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
return res, nil return res, nil
} }
// default response
formattedDebt, _ := store.TruncateDecimalString(string(activeBal), 2)
res.FlagReset = append(res.FlagReset, flag_api_call_error) res.FlagReset = append(res.FlagReset, flag_api_call_error)
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", formattedDebt, string(activeSym))
// Resolve active pool // Resolve active pool
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId) activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
@ -133,93 +139,106 @@ func (h *MenuHandlers) CalculateCreditAndDebt(ctx context.Context, sym string, i
return res, err return res, err
} }
// Fetch swappable vouchers (pool view) // Fetch swappable vouchers
swappableVouchers, err := h.accountService.GetPoolSwappableFromVouchers(ctx, string(activePoolAddress), string(publicKey)) swappableVouchers, err := h.accountService.GetPoolSwappableFromVouchers(ctx, string(activePoolAddress), string(publicKey))
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetPoolSwappableFromVouchers", "error", err) logg.ErrorCtxf(ctx, "failed on GetPoolSwappableFromVouchers", "error", err)
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
return res, nil return res, nil
} }
if len(swappableVouchers) == 0 { if len(swappableVouchers) == 0 {
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
return res, nil return res, nil
} }
// Fetch ALL wallet vouchers (voucher holdings view) // Build stable voucher priority (lower index = higher priority)
allVouchers, err := h.accountService.FetchVouchers(ctx, string(publicKey)) stablePriority := make(map[string]int)
if err != nil { stableAddresses := config.StableVoucherAddresses()
logg.ErrorCtxf(ctx, "failed on FetchVouchers", "error", err) for i, addr := range stableAddresses {
return res, nil stablePriority[addr] = i
} }
// CREDIT calculation stable := make([]dataserviceapi.TokenHoldings, 0)
// Rule: nonStable := make([]dataserviceapi.TokenHoldings, 0)
// 1. Swap quote of active voucher → first stable in pool from GetPoolSwappableFromVouchers
// 2. PLUS all stable balances from FetchVouchers
scaledCredit := "0" // Helper: order vouchers (stable first, priority-based)
orderVouchers := func(vouchers []dataserviceapi.TokenHoldings) []dataserviceapi.TokenHoldings {
// 1. Find first stable voucher in POOL (for swap target) for _, v := range vouchers {
var firstPoolStable *dataserviceapi.TokenHoldings if isStableVoucher(v.TokenAddress) {
for i := range swappableVouchers { stable = append(stable, v)
if isStableVoucher(swappableVouchers[i].TokenAddress) { } else {
firstPoolStable = &swappableVouchers[i] nonStable = append(nonStable, v)
break
}
}
// 2. If pool has a stable, get swap quote
if firstPoolStable != nil {
finalAmountStr, err := store.ParseAndScaleAmount(
string(activeBal),
string(activeDecimal),
)
if err != nil {
return res, err
}
// swap active -> FIRST stable from pool list
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, string(publicKey), string(activeAddress), string(activePoolAddress), firstPoolStable.TokenAddress)
if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_call_error)
res.Content = l.Get("Your request failed. Please try again later.")
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
return res, nil
}
// scale using REAL stable decimals
finalQuote := store.ScaleDownBalance(r.OutValue, firstPoolStable.TokenDecimals)
scaledCredit = store.AddDecimalStrings(scaledCredit, finalQuote)
}
// 3. Add ALL wallet stable balances (from FetchVouchers)
for _, v := range allVouchers {
if isStableVoucher(v.TokenAddress) {
scaled := store.ScaleDownBalance(v.Balance, v.TokenDecimals)
scaledCredit = store.AddDecimalStrings(scaledCredit, scaled)
}
}
// DEBT calculation
// Rule:
// - Default = 0
// - If active is stable → remain 0
// - If active is non-stable and exists in pool → use pool balance
scaledDebt := "0"
if !isStableVoucher(string(activeAddress)) {
for _, v := range swappableVouchers {
if v.TokenSymbol == string(activeSym) {
scaledDebt = store.ScaleDownBalance(v.Balance, v.TokenDecimals)
break
} }
} }
sort.SliceStable(stable, func(i, j int) bool {
ai := stablePriority[stable[i].TokenAddress]
aj := stablePriority[stable[j].TokenAddress]
return ai < aj
})
return append(stable, nonStable...)
} }
formattedDebt, _ := store.TruncateDecimalString(scaledDebt, 2) // Remove active voucher
filteredVouchers := make([]dataserviceapi.TokenHoldings, 0, len(swappableVouchers))
for _, v := range swappableVouchers {
if v.TokenSymbol != string(activeSym) {
filteredVouchers = append(filteredVouchers, v)
}
}
// Order remaining vouchers
orderedFilteredVouchers := orderVouchers(filteredVouchers)
// Process & store
data := store.ProcessVouchers(orderedFilteredVouchers)
dataMap := map[storedb.DataTyp]string{
storedb.DATA_VOUCHER_SYMBOLS: data.Symbols,
storedb.DATA_VOUCHER_BALANCES: data.Balances,
storedb.DATA_VOUCHER_DECIMALS: data.Decimals,
storedb.DATA_VOUCHER_ADDRESSES: data.Addresses,
}
for key, value := range dataMap {
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
logg.ErrorCtxf(ctx, "Failed to write data entry for sessionId: %s", sessionId, "key", key, "error", err)
continue
}
}
// Credit calculation: How much Active Token that can be swapped for a stable coin
// + any stables sendable to Pretium (in KSH value)
scaledCredit := "0"
finalAmountStr, err := store.ParseAndScaleAmount(string(activeBal), string(activeDecimal))
if err != nil {
return res, err
}
// do a swap quote for default stable coin from active voucher
stableAddress := config.DefaultStableVoucherAddress()
stableDecimals := config.DefaultStableVoucherDecimals()
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, string(publicKey), string(activeAddress), string(activePoolAddress), stableAddress)
if err != nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
res.FlagSet = append(res.FlagSet, flag_api_call_error)
res.Content = l.Get("Your request failed. Please try again later.")
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
return res, nil
}
finalQuote := store.ScaleDownBalance(r.OutValue, stableDecimals)
scaledCredit = store.AddDecimalStrings(scaledCredit, finalQuote)
for _, v := range stable {
scaled := store.ScaleDownBalance(v.Balance, v.TokenDecimals)
scaledCredit = store.AddDecimalStrings(scaledCredit, scaled)
}
// DEBT calculation: All outstanding active token that is in the current pool
// (how much of AT that is in the active Pool)
// Fetch MPESA rates // Fetch MPESA rates
rates, err := h.accountService.GetMpesaOnrampRates(ctx) rates, err := h.accountService.GetMpesaOnrampRates(ctx)
@ -231,7 +250,9 @@ func (h *MenuHandlers) CalculateCreditAndDebt(ctx context.Context, sym string, i
} }
creditFloat, _ := strconv.ParseFloat(scaledCredit, 64) creditFloat, _ := strconv.ParseFloat(scaledCredit, 64)
creditKsh := fmt.Sprintf("%f", creditFloat*rates.Buy) creditKsh := fmt.Sprintf("%f", creditFloat*rates.Buy)
kshFormattedCredit, _ := store.TruncateDecimalString(creditKsh, 0) kshFormattedCredit, _ := store.TruncateDecimalString(creditKsh, 0)
res.Content = l.Get( res.Content = l.Get(

View File

@ -36,7 +36,7 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
inputStr := string(input) inputStr := string(input)
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" { if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool) res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher)
return res, nil return res, nil
} }
@ -51,8 +51,8 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
} }
// Store the active transaction voucher data (from token) // Store the active transaction voucher data (from token)
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil { if err := store.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err) logg.ErrorCtxf(ctx, "failed on StoreTemporaryVoucher", "error", err)
return res, err return res, err
} }
@ -100,13 +100,11 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
} }
// Fetch min withdrawal amount from config/env // Fetch min withdrawal amount from config/env
minWithdraw := config.MinMpesaWithdrawAmount() // float64 (20) minksh := fmt.Sprintf("%f", config.MinMpesaWithdrawAmount())
minKshFormatted, _ := store.TruncateDecimalString(fmt.Sprintf("%f", minWithdraw), 0) minKshFormatted, _ := store.TruncateDecimalString(minksh, 0)
// If SAT is the same as RAT (default USDm), // If SAT is the same as RAT, return early with KSH format
// or if the voucher is a stable coin if string(metadata.TokenAddress) == string(recipientActiveAddress) {
// return early with KSH format
if string(metadata.TokenAddress) == string(recipientActiveAddress) || isStableVoucher(metadata.TokenAddress) {
txType = "normal" txType = "normal"
// Save the transaction type // Save the transaction type
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil { if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil {
@ -115,16 +113,9 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
} }
activeFloat, _ := strconv.ParseFloat(string(metadata.Balance), 64) activeFloat, _ := strconv.ParseFloat(string(metadata.Balance), 64)
kshValue := activeFloat * rates.Buy ksh := fmt.Sprintf("%f", activeFloat*rates.Buy)
maxKshFormatted, _ := store.TruncateDecimalString(fmt.Sprintf("%f", kshValue), 0) maxKshFormatted, _ := store.TruncateDecimalString(ksh, 0)
// Ensure that the max is greater than the min
if kshValue < minWithdraw {
res.FlagSet = append(res.FlagSet, flag_low_swap_amount)
res.Content = l.Get("%s Ksh", maxKshFormatted)
return res, nil
}
res.Content = l.Get( res.Content = l.Get(
"Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n", "Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n",
@ -132,8 +123,6 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
maxKshFormatted, maxKshFormatted,
) )
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool)
return res, nil return res, nil
} }
@ -153,7 +142,6 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
if !canSwap.CanSwapFrom { // pool issue (CATCH on .vis) if !canSwap.CanSwapFrom { // pool issue (CATCH on .vis)
res.FlagSet = append(res.FlagSet, flag_incorrect_pool) res.FlagSet = append(res.FlagSet, flag_incorrect_pool)
res.Content = "0"
return res, nil return res, nil
} }
@ -161,13 +149,10 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
_, maxRAT, err := h.calculateSendCreditLimits(ctx, activePoolAddress, []byte(metadata.TokenAddress), recipientActiveAddress, publicKey, []byte(metadata.TokenDecimals), recipientActiveDecimal) _, maxRAT, err := h.calculateSendCreditLimits(ctx, activePoolAddress, []byte(metadata.TokenAddress), recipientActiveAddress, publicKey, []byte(metadata.TokenDecimals), recipientActiveDecimal)
if err != nil { if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
res.Content = "0"
logg.ErrorCtxf(ctx, "failed on calculateSendCreditLimits", "error", err) logg.ErrorCtxf(ctx, "failed on calculateSendCreditLimits", "error", err)
return res, nil return res, nil
} }
res.FlagReset = append(res.FlagReset, flag_api_call_error)
// Fallback if below minimum // Fallback if below minimum
maxFloat, _ := strconv.ParseFloat(maxRAT, 64) maxFloat, _ := strconv.ParseFloat(maxRAT, 64)
if maxFloat < 0.1 { if maxFloat < 0.1 {
@ -177,8 +162,6 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
return res, nil return res, nil
} }
res.FlagReset = append(res.FlagReset, flag_low_swap_amount)
// Save max RAT amount to be used in validating the user's input // Save max RAT amount to be used in validating the user's input
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, []byte(maxRAT)) err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, []byte(maxRAT))
if err != nil { if err != nil {
@ -215,8 +198,6 @@ func (h *MenuHandlers) GetMpesaMaxLimit(ctx context.Context, sym string, input [
maxKshFormatted, maxKshFormatted,
) )
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool)
return res, nil return res, nil
} }
@ -284,9 +265,9 @@ func (h *MenuHandlers) GetMpesaPreview(ctx context.Context, sym string, input []
} }
// get the selected voucher // get the selected voucher
mpesaWithdrawalVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId) mpesaWithdrawalVoucher, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err) logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
return res, err return res, err
} }
@ -425,9 +406,9 @@ func (h *MenuHandlers) InitiateGetMpesa(ctx context.Context, sym string, input [
} }
// get the selected voucher // get the selected voucher
mpesaWithdrawalVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId) mpesaWithdrawalVoucher, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err) logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
return res, err return res, err
} }
@ -506,7 +487,7 @@ func (h *MenuHandlers) InitiateGetMpesa(ctx context.Context, sym string, input [
} }
// Initiate a send to mpesa after the swap // Initiate a send to mpesa after the swap
tokenTransfer, err := h.accountService.TokenTransfer(ctx, string(amount), string(publicKey), mpesaAddress, swapToVoucher.TokenAddress) tokenTransfer, err := h.accountService.TokenTransfer(ctx, string(amount),string(publicKey), mpesaAddress, swapToVoucher.TokenAddress)
if err != nil { if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
res.Content = l.Get("Your request failed. Please try again later.") res.Content = l.Get("Your request failed. Please try again later.")
@ -544,7 +525,7 @@ func (h *MenuHandlers) SendMpesaMinLimit(ctx context.Context, sym string, input
kshFormatted, _ := store.TruncateDecimalString(ksh, 0) kshFormatted, _ := store.TruncateDecimalString(ksh, 0)
res.Content = l.Get( res.Content = l.Get(
"Enter the amount of credit to deposit: (Minimum %s Ksh)\n", "Enter the amount of Mpesa to send: (Minimum %s Ksh)\n",
kshFormatted, kshFormatted,
) )
@ -613,11 +594,9 @@ func (h *MenuHandlers) SendMpesaPreview(ctx context.Context, sym string, input [
estimateStr := fmt.Sprintf("%f", estimateValue) estimateStr := fmt.Sprintf("%f", estimateValue)
estimateFormatted, _ := store.TruncateDecimalString(estimateStr, 2) estimateFormatted, _ := store.TruncateDecimalString(estimateStr, 2)
defaultAsset := config.DefaultMpesaAsset()
res.Content = l.Get( res.Content = l.Get(
"You will get a prompt for your Mpesa PIN shortly to send %s ksh and receive ~ %s %s", "You will get a prompt for your M-Pesa PIN shortly to send %s ksh and receive ~ %s cUSD",
inputStr, estimateFormatted, defaultAsset, inputStr, estimateFormatted,
) )
return res, nil return res, nil

View File

@ -43,7 +43,7 @@ func (h *MenuHandlers) CalculateMaxPayDebt(ctx context.Context, sym string, inpu
} }
// Resolve active pool // Resolve active pool
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId) activePoolAddress, activePoolName, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error) res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error)
return res, err return res, err
@ -64,7 +64,6 @@ func (h *MenuHandlers) CalculateMaxPayDebt(ctx context.Context, sym string, inpu
r, err := h.accountService.GetSwapFromTokenMaxLimit(ctx, string(activePoolAddress), metadata.TokenAddress, string(activeAddress), string(publicKey)) r, err := h.accountService.GetSwapFromTokenMaxLimit(ctx, string(activePoolAddress), metadata.TokenAddress, string(activeAddress), string(publicKey))
if err != nil { if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
res.Content = "0"
logg.ErrorCtxf(ctx, "failed on GetSwapFromTokenMaxLimit", "error", err) logg.ErrorCtxf(ctx, "failed on GetSwapFromTokenMaxLimit", "error", err)
return res, nil return res, nil
} }
@ -127,10 +126,10 @@ func (h *MenuHandlers) CalculateMaxPayDebt(ctx context.Context, sym string, inpu
quoteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2) quoteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2)
res.Content = l.Get( res.Content = l.Get(
"You can remove a max of %s %s from '%s' pool\nEnter amount of %s:(Max: %s)", "You can remove a max of %s %s from '%s'\nEnter amount of %s:(Max: %s)",
quoteStr, quoteStr,
string(activeSym), string(activeSym),
string(activePoolSymbol), string(activePoolName),
metadata.TokenSymbol, metadata.TokenSymbol,
maxStr, maxStr,
) )
@ -238,7 +237,7 @@ func (h *MenuHandlers) ConfirmDebtRemoval(ctx context.Context, sym string, input
} }
res.Content = l.Get( res.Content = l.Get(
"Please confirm that you will use %s %s to remove your debt of %s %s\nEnter your PIN:", "Please confirm that you will use %s %s to remove your debt of %s %s\n",
inputStr, payDebtVoucher.TokenSymbol, qouteStr, string(activeSym), inputStr, payDebtVoucher.TokenSymbol, qouteStr, string(activeSym),
) )
@ -269,7 +268,7 @@ func (h *MenuHandlers) InitiatePayDebt(ctx context.Context, sym string, input []
} }
// Resolve active pool // Resolve active pool
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId) activePoolAddress, activePoolName, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
return res, err return res, err
} }
@ -311,7 +310,7 @@ func (h *MenuHandlers) InitiatePayDebt(ctx context.Context, sym string, input []
"Your request has been sent. You will receive an SMS when your debt of %s %s has been removed from %s.", "Your request has been sent. You will receive an SMS when your debt of %s %s has been removed from %s.",
string(debtQuotedAmount), string(debtQuotedAmount),
string(activeSym), string(activeSym),
activePoolSymbol, activePoolName,
) )
res.FlagReset = append(res.FlagReset, flag_account_authorized) res.FlagReset = append(res.FlagReset, flag_account_authorized)

View File

@ -83,8 +83,8 @@ func (h *MenuHandlers) PoolDepositMaxAmount(ctx context.Context, sym string, inp
} }
// Store the pool deposit voucher data // Store the pool deposit voucher data
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil { if err := store.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err) logg.ErrorCtxf(ctx, "failed on StoreTemporaryVoucher", "error", err)
return res, err return res, err
} }
@ -119,9 +119,9 @@ func (h *MenuHandlers) ConfirmPoolDeposit(ctx context.Context, sym string, input
userStore := h.userdataStore userStore := h.userdataStore
poolDepositVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId) poolDepositVoucher, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err) logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
return res, err return res, err
} }
@ -145,14 +145,14 @@ func (h *MenuHandlers) ConfirmPoolDeposit(ctx context.Context, sym string, input
} }
// Resolve active pool // Resolve active pool
_, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId) _, activePoolName, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
return res, err return res, err
} }
res.Content = l.Get( res.Content = l.Get(
"You will deposit %s %s into %s\n", "You will deposit %s %s into %s\n",
inputStr, poolDepositVoucher.TokenSymbol, activePoolSymbol, inputStr, poolDepositVoucher.TokenSymbol, activePoolName,
) )
return res, nil return res, nil
@ -173,41 +173,30 @@ func (h *MenuHandlers) InitiatePoolDeposit(ctx context.Context, sym string, inpu
l := gotext.NewLocale(translationDir, code) l := gotext.NewLocale(translationDir, code)
l.AddDomain("default") l.AddDomain("default")
userStore := h.userdataStore
// Resolve active pool // Resolve active pool
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId) activePoolAddress, activePoolName, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on resolveActivePoolDetails", "error", err)
return res, err return res, err
} }
poolDepositVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId) poolDepositVoucher, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err) logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
return res, err return res, err
} }
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) poolDepositdata, err := store.ReadTransactionData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
return res, err return res, err
} }
amount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_AMOUNT) finalAmountStr, err := store.ParseAndScaleAmount(poolDepositdata.Amount, poolDepositVoucher.TokenDecimals)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to read amount entry", "key", storedb.DATA_AMOUNT, "error", err)
return res, err return res, err
} }
finalAmountStr, err := store.ParseAndScaleAmount(string(amount), poolDepositVoucher.TokenDecimals) // Call pool deposit API
if err != nil { r, err := h.accountService.PoolDeposit(ctx, finalAmountStr, poolDepositdata.PublicKey, string(activePoolAddress), poolDepositVoucher.TokenAddress)
logg.ErrorCtxf(ctx, "failed on ParseAndScaleAmount", "error", err)
return res, err
}
// Call token transfer API and send the token to the pool address
r, err := h.accountService.TokenTransfer(ctx, finalAmountStr, string(publicKey), string(activePoolAddress), poolDepositVoucher.TokenAddress)
if err != nil { if err != nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
@ -221,9 +210,9 @@ func (h *MenuHandlers) InitiatePoolDeposit(ctx context.Context, sym string, inpu
res.Content = l.Get( res.Content = l.Get(
"Your request has been sent. You will receive an SMS when %s %s has been deposited into %s.", "Your request has been sent. You will receive an SMS when %s %s has been deposited into %s.",
string(amount), poolDepositdata.Amount,
poolDepositVoucher.TokenSymbol, poolDepositVoucher.TokenSymbol,
activePoolSymbol, activePoolName,
) )
res.FlagReset = append(res.FlagReset, flag_account_authorized) res.FlagReset = append(res.FlagReset, flag_account_authorized)

View File

@ -3,7 +3,6 @@ package application
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
"git.defalsify.org/vise.git/db" "git.defalsify.org/vise.git/db"
"git.defalsify.org/vise.git/resource" "git.defalsify.org/vise.git/resource"
@ -105,7 +104,6 @@ func (h *MenuHandlers) GetDefaultPool(ctx context.Context, sym string, input []b
// ViewPool retrieves the pool details from the user store // ViewPool retrieves the pool details from the user store
// and displays it to the user for them to select it. // and displays it to the user for them to select it.
// if the data does not exist, it calls the API to get the pool details
func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
@ -133,11 +131,8 @@ func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (
if poolData == nil { if poolData == nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
// convert to uppercase before the call
poolSymbol := strings.ToUpper(inputStr)
// no match found. Call the API using the inputStr as the symbol // no match found. Call the API using the inputStr as the symbol
poolResp, err := h.accountService.RetrievePoolDetails(ctx, poolSymbol) poolResp, err := h.accountService.RetrievePoolDetails(ctx, inputStr)
if err != nil { if err != nil {
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
return res, nil return res, nil

View File

@ -175,10 +175,6 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
return res, nil return res, nil
} }
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
userStore := h.userdataStore userStore := h.userdataStore
metadata, err := store.GetSwapToVoucherData(ctx, userStore, sessionId, inputStr) metadata, err := store.GetSwapToVoucherData(ctx, userStore, sessionId, inputStr)
if err != nil { if err != nil {
@ -239,9 +235,9 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
return res, err return res, err
} }
res.Content = l.Get( res.Content = fmt.Sprintf(
"Maximum: %s %s\n\nEnter amount of %s to swap for %s:", "Maximum: %s\n\nEnter amount of %s to swap for %s:",
maxStr, swapData.ActiveSwapFromSym, swapData.ActiveSwapFromSym, swapData.ActiveSwapToSym, maxStr, swapData.ActiveSwapFromSym, swapData.ActiveSwapToSym,
) )
return res, nil return res, nil
@ -327,8 +323,8 @@ func (h *MenuHandlers) SwapPreview(ctx context.Context, sym string, input []byte
// Format to 2 decimal places // Format to 2 decimal places
qouteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2) qouteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2)
res.Content = l.Get( res.Content = fmt.Sprintf(
"You will swap %s %s for %s %s:", "You will swap:\n%s %s for %s %s:",
inputStr, swapData.ActiveSwapFromSym, qouteStr, swapData.ActiveSwapToSym, inputStr, swapData.ActiveSwapFromSym, qouteStr, swapData.ActiveSwapToSym,
) )

View File

@ -48,10 +48,10 @@ func (h *MenuHandlers) ValidateRecipient(ctx context.Context, sym string, input
return res, nil return res, nil
} }
// save the recipient under recipient input // save the recipient as the temporaryRecipient
err = store.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT_INPUT, []byte(recipient)) err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(recipient))
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to write recipient input entry with", "key", storedb.DATA_RECIPIENT_INPUT, "value", recipient, "error", err) logg.ErrorCtxf(ctx, "failed to write temporaryRecipient entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", recipient, "error", err)
return res, err return res, err
} }
@ -203,11 +203,11 @@ func (h *MenuHandlers) determineAndSaveTransactionType(
publicKey []byte, publicKey []byte,
recipientPhoneNumber []byte, recipientPhoneNumber []byte,
) error { ) error {
userStore := h.userdataStore store := h.userdataStore
txType := "swap" txType := "swap"
// Read sender's active address // Read sender's active address
senderActiveAddress, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS) senderActiveAddress, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "Failed to read sender active address", "error", err) logg.ErrorCtxf(ctx, "Failed to read sender active address", "error", err)
return err return err
@ -215,7 +215,7 @@ func (h *MenuHandlers) determineAndSaveTransactionType(
var recipientActiveAddress []byte var recipientActiveAddress []byte
if recipientPhoneNumber != nil { if recipientPhoneNumber != nil {
recipientActiveAddress, _ = userStore.ReadEntry(ctx, string(recipientPhoneNumber), storedb.DATA_ACTIVE_ADDRESS) recipientActiveAddress, _ = store.ReadEntry(ctx, string(recipientPhoneNumber), storedb.DATA_ACTIVE_ADDRESS)
} }
// recipient has no active token → normal transaction // recipient has no active token → normal transaction
@ -227,34 +227,17 @@ func (h *MenuHandlers) determineAndSaveTransactionType(
} }
// Save the transaction type // Save the transaction type
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil { if err := store.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil {
logg.ErrorCtxf(ctx, "Failed to write transaction type", "type", txType, "error", err) logg.ErrorCtxf(ctx, "Failed to write transaction type", "type", txType, "error", err)
return err return err
} }
// Save the recipient's phone number only if it exists // Save the recipient's phone number only if it exists
if recipientPhoneNumber != nil { if recipientPhoneNumber != nil {
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER, recipientPhoneNumber); err != nil { if err := store.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER, recipientPhoneNumber); err != nil {
logg.ErrorCtxf(ctx, "Failed to write recipient phone number", "type", txType, "error", err) logg.ErrorCtxf(ctx, "Failed to write recipient phone number", "type", txType, "error", err)
return err return err
} }
// fetch data for use (to_voucher data)
recipientActiveSym, recipientActiveAddress, recipientActiveDecimal, err := h.getRecipientData(ctx, string(recipientPhoneNumber))
if err != nil {
return err
}
swapMetadata := &dataserviceapi.TokenHoldings{
TokenAddress: string(recipientActiveAddress),
TokenSymbol: string(recipientActiveSym),
TokenDecimals: string(recipientActiveDecimal),
}
// Store the active swap_to data
if err := store.UpdateSwapToVoucherData(ctx, userStore, sessionId, swapMetadata); err != nil {
logg.ErrorCtxf(ctx, "failed on UpdateSwapToVoucherData", "error", err)
return err
}
} else { } else {
logg.InfoCtxf(ctx, "No recipient phone number found for public key", "publicKey", string(publicKey)) logg.InfoCtxf(ctx, "No recipient phone number found for public key", "publicKey", string(publicKey))
} }
@ -326,7 +309,6 @@ func (h *MenuHandlers) ResetTransactionAmount(ctx context.Context, sym string, i
} }
// MaxAmount checks the transaction type to determine the displayed max amount. // MaxAmount checks the transaction type to determine the displayed max amount.
// Checks whether the user selected a custom voucher
// If the transaction type is "swap", it checks the max swappable amount and sets this as the content. // If the transaction type is "swap", it checks the max swappable amount and sets this as the content.
// If the transaction type is "normal", gets the current sender's balance from the store and sets it as // If the transaction type is "normal", gets the current sender's balance from the store and sets it as
// the result content. // the result content.
@ -352,54 +334,9 @@ func (h *MenuHandlers) MaxAmount(ctx context.Context, sym string, input []byte)
return res, err return res, err
} }
customVoucherSelection, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE)
if err == nil {
customVoucherValue, _ := strconv.ParseUint(string(customVoucherSelection), 0, 64)
if customVoucherValue == 1 {
// use the custom voucher
customTransactionVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
activeSym = []byte(customTransactionVoucher.TokenSymbol)
activeBal = []byte(customTransactionVoucher.Balance)
activeDecimal = []byte(customTransactionVoucher.TokenDecimals)
activeAddress = []byte(customTransactionVoucher.TokenAddress)
}
}
// Format the active balance amount to 2 decimal places // Format the active balance amount to 2 decimal places
formattedBalance, _ := store.TruncateDecimalString(string(activeBal), 2) formattedBalance, _ := store.TruncateDecimalString(string(activeBal), 2)
// confirm the transaction type
swapToVoucher, err := store.ReadSwapToVoucher(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
return res, err
}
// Case for M-Pesa
// if the recipient is Mpesa (address), check if the sender's voucher is a stable coin
recipientAddress, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT)
if err != nil {
logg.ErrorCtxf(ctx, "Failed to read recipient's address", "error", err)
return res, err
}
if string(recipientAddress) == config.DefaultMpesaAddress() && isStableVoucher(string(activeAddress)) {
res.FlagReset = append(res.FlagReset, flag_swap_transaction)
res.Content = l.Get("Maximum amount: %s %s\nEnter amount:", formattedBalance, string(activeSym))
return res, nil
}
if string(swapToVoucher.TokenAddress) == string(activeAddress) {
// recipient has active token same as selected token → normal transaction
transactionType = []byte("normal")
} else {
transactionType = []byte("swap")
}
// If normal transaction return balance // If normal transaction return balance
if string(transactionType) == "normal" { if string(transactionType) == "normal" {
res.FlagReset = append(res.FlagReset, flag_swap_transaction) res.FlagReset = append(res.FlagReset, flag_swap_transaction)
@ -427,15 +364,12 @@ func (h *MenuHandlers) MaxAmount(ctx context.Context, sym string, input []byte)
return res, nil return res, nil
} }
// Get the recipient's phone number to read other data items (*) // Get the recipient's phone number to read other data items
recipientPhoneNumber, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER) recipientPhoneNumber, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER)
if err != nil || !phone.IsValidPhoneNumber(string(recipientPhoneNumber)) { if err != nil {
// revert to normal transaction // invalid state
res.FlagReset = append(res.FlagReset, flag_swap_transaction) return res, err
res.Content = l.Get("Maximum amount: %s %s\nEnter amount:", formattedBalance, string(activeSym))
return res, nil
} }
recipientActiveSym, recipientActiveAddress, recipientActiveDecimal, err := h.getRecipientData(ctx, string(recipientPhoneNumber)) recipientActiveSym, recipientActiveAddress, recipientActiveDecimal, err := h.getRecipientData(ctx, string(recipientPhoneNumber))
if err != nil { if err != nil {
return res, err return res, err
@ -545,7 +479,7 @@ func (h *MenuHandlers) getRecipientData(ctx context.Context, sessionId string) (
return return
} }
func (h *MenuHandlers) resolveActivePoolDetails(ctx context.Context, sessionId string) (defaultPoolAddress, defaultPoolSymbol []byte, err error) { func (h *MenuHandlers) resolveActivePoolDetails(ctx context.Context, sessionId string) (defaultPoolAddress, defaultPoolName []byte, err error) {
store := h.userdataStore store := h.userdataStore
// Try read address // Try read address
@ -555,21 +489,21 @@ func (h *MenuHandlers) resolveActivePoolDetails(ctx context.Context, sessionId s
return nil, nil, err return nil, nil, err
} }
// Try read symbol // Try read name
defaultPoolSymbol, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_POOL_SYM) defaultPoolName, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_POOL_NAME)
if err != nil && !db.IsNotFound(err) { if err != nil && !db.IsNotFound(err) {
logg.ErrorCtxf(ctx, "failed to read active pool name", "error", err) logg.ErrorCtxf(ctx, "failed to read active pool name", "error", err)
return nil, nil, err return nil, nil, err
} }
// If both exist, return them // If both exist, return them
if defaultPoolAddress != nil && defaultPoolSymbol != nil { if defaultPoolAddress != nil && defaultPoolName != nil {
return defaultPoolAddress, defaultPoolSymbol, nil return defaultPoolAddress, defaultPoolName, nil
} }
// Fallback to config defaults // Fallback to config defaults
defaultPoolAddress = []byte(config.DefaultPoolAddress()) defaultPoolAddress = []byte(config.DefaultPoolAddress())
defaultPoolSymbol = []byte(config.DefaultPoolSymbol()) defaultPoolName = []byte(config.DefaultPoolName())
if err := store.WriteEntry( if err := store.WriteEntry(
ctx, ctx,
@ -584,14 +518,14 @@ func (h *MenuHandlers) resolveActivePoolDetails(ctx context.Context, sessionId s
if err := store.WriteEntry( if err := store.WriteEntry(
ctx, ctx,
sessionId, sessionId,
storedb.DATA_ACTIVE_POOL_SYM, storedb.DATA_ACTIVE_POOL_NAME,
defaultPoolSymbol, defaultPoolName,
); err != nil { ); err != nil {
logg.ErrorCtxf(ctx, "failed to write default pool symbol", "error", err) logg.ErrorCtxf(ctx, "failed to write default pool name", "error", err)
return nil, nil, err return nil, nil, err
} }
return defaultPoolAddress, defaultPoolSymbol, nil return defaultPoolAddress, defaultPoolName, nil
} }
func (h *MenuHandlers) calculateSendCreditLimits(ctx context.Context, poolAddress, fromAddress, toAddress, publicKey, fromDecimal, toDecimal []byte) (string, string, error) { func (h *MenuHandlers) calculateSendCreditLimits(ctx context.Context, poolAddress, fromAddress, toAddress, publicKey, fromDecimal, toDecimal []byte) (string, string, error) {
@ -635,46 +569,40 @@ func (h *MenuHandlers) ValidateAmount(ctx context.Context, sym string, input []b
userStore := h.userdataStore userStore := h.userdataStore
var balanceValue float64
// retrieve the active balance // retrieve the active balance
activeBal, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL) activeBal, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err) logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err)
return res, err return res, err
} }
balanceValue, err = strconv.ParseFloat(string(activeBal), 64)
customVoucherSelection, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE)
if err == nil {
customVoucherValue, _ := strconv.ParseUint(string(customVoucherSelection), 0, 64)
if customVoucherValue == 1 {
// use the custom voucher
customTransactionVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
activeBal = []byte(customTransactionVoucher.Balance)
}
}
maxValue, err := strconv.ParseFloat(string(activeBal), 64)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "Failed to convert the activeBal to a float", "error", err) logg.ErrorCtxf(ctx, "Failed to convert the activeBal to a float", "error", err)
return res, err return res, err
} }
inputAmount, err := strconv.ParseFloat(inputStr, 64) // Extract numeric part from the input amount
if err != nil || inputAmount > maxValue || inputAmount < 0.1 { amountStr := strings.TrimSpace(inputStr)
inputAmount, err := strconv.ParseFloat(amountStr, 64)
if err != nil {
res.FlagSet = append(res.FlagSet, flag_invalid_amount) res.FlagSet = append(res.FlagSet, flag_invalid_amount)
res.Content = inputStr res.Content = amountStr
return res, nil
}
if inputAmount > balanceValue || inputAmount < 0.1 {
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
res.Content = amountStr
return res, nil return res, nil
} }
// Format the amount to 2 decimal places before saving (truncated) // Format the amount to 2 decimal places before saving (truncated)
formattedAmount, err := store.TruncateDecimalString(inputStr, 2) formattedAmount, err := store.TruncateDecimalString(amountStr, 2)
if err != nil { if err != nil {
res.FlagSet = append(res.FlagSet, flag_invalid_amount) res.FlagSet = append(res.FlagSet, flag_invalid_amount)
res.Content = inputStr res.Content = amountStr
return res, nil return res, nil
} }
@ -746,62 +674,8 @@ func (h *MenuHandlers) GetAmount(ctx context.Context, sym string, input []byte)
return res, nil return res, nil
} }
// NormalTransactionPreview displays the token transfer preview awaiting authorization // InitiateTransaction calls the TokenTransfer and returns a confirmation based on the result.
func (h *MenuHandlers) NormalTransactionPreview(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) InitiateTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
// Input in RAT
inputStr := string(input)
if inputStr == "0" {
return res, nil
}
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
userStore := h.userdataStore
data, err := store.ReadTransactionData(ctx, h.userdataStore, sessionId)
if err != nil {
return res, err
}
customVoucherSelection, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE)
if err == nil {
customVoucherValue, _ := strconv.ParseUint(string(customVoucherSelection), 0, 64)
if customVoucherValue == 1 {
// use the custom voucher
customTransactionVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
data.ActiveSym = customTransactionVoucher.TokenSymbol
data.ActiveDecimal = customTransactionVoucher.TokenDecimals
data.ActiveAddress = customTransactionVoucher.TokenAddress
}
}
res.Content = l.Get(
"%s will receive %s %s from %s",
data.RecipientInput,
data.Amount,
data.ActiveSym,
sessionId,
)
return res, nil
}
// InitiateNormalTransaction calls the TokenTransfer and returns a confirmation based on the result.
// used for non-swap transactions
func (h *MenuHandlers) InitiateNormalTransaction(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
var err error var err error
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
@ -811,8 +685,6 @@ func (h *MenuHandlers) InitiateNormalTransaction(ctx context.Context, sym string
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
userStore := h.userdataStore
code := codeFromCtx(ctx) code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code) l := gotext.NewLocale(translationDir, code)
l.AddDomain("default") l.AddDomain("default")
@ -822,23 +694,6 @@ func (h *MenuHandlers) InitiateNormalTransaction(ctx context.Context, sym string
return res, err return res, err
} }
customVoucherSelection, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE)
if err == nil {
customVoucherValue, _ := strconv.ParseUint(string(customVoucherSelection), 0, 64)
if customVoucherValue == 1 {
// use the custom voucher
customTransactionVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
data.ActiveSym = customTransactionVoucher.TokenSymbol
data.ActiveDecimal = customTransactionVoucher.TokenDecimals
data.ActiveAddress = customTransactionVoucher.TokenAddress
}
}
finalAmountStr, err := store.ParseAndScaleAmount(data.Amount, data.ActiveDecimal) finalAmountStr, err := store.ParseAndScaleAmount(data.Amount, data.ActiveDecimal)
if err != nil { if err != nil {
return res, err return res, err
@ -870,7 +725,7 @@ func (h *MenuHandlers) InitiateNormalTransaction(ctx context.Context, sym string
res.Content = l.Get( res.Content = l.Get(
"Your request has been sent. %s will receive %s %s from %s.", "Your request has been sent. %s will receive %s %s from %s.",
data.RecipientInput, data.TemporaryValue,
data.Amount, data.Amount,
data.ActiveSym, data.ActiveSym,
sessionId, sessionId,
@ -902,40 +757,19 @@ func (h *MenuHandlers) TransactionSwapPreview(ctx context.Context, sym string, i
userStore := h.userdataStore userStore := h.userdataStore
// the initial recipient that the sender input recipientPhoneNumber, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER)
recipientInput, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_INPUT)
if err != nil { if err != nil {
// invalid state // invalid state
return res, err return res, err
} }
// Resolve active pool swapData, err := store.ReadSwapPreviewData(ctx, userStore, sessionId)
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
return res, err return res, err
} }
// get the selected voucher
selectedVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
swapToVoucher, err := store.ReadSwapToVoucher(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
return res, err
}
swapMaxAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT)
if err != nil {
logg.ErrorCtxf(ctx, "failed to read swapMaxAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, "error", err)
return res, err
}
// use the stored max RAT // use the stored max RAT
maxRATValue, err := strconv.ParseFloat(string(swapMaxAmount), 64) maxRATValue, err := strconv.ParseFloat(swapData.ActiveSwapMaxAmount, 64)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "Failed to convert the swapMaxAmount to a float", "error", err) logg.ErrorCtxf(ctx, "Failed to convert the swapMaxAmount to a float", "error", err)
return res, err return res, err
@ -956,13 +790,13 @@ func (h *MenuHandlers) TransactionSwapPreview(ctx context.Context, sym string, i
return res, nil return res, nil
} }
finalAmountStr, err := store.ParseAndScaleAmount(formattedAmount, swapToVoucher.TokenDecimals) finalAmountStr, err := store.ParseAndScaleAmount(formattedAmount, swapData.ActiveSwapToDecimal)
if err != nil { if err != nil {
return res, err return res, err
} }
// call the credit send API to get the reverse quote // call the credit send API to get the reverse quote
r, err := h.accountService.GetCreditSendReverseQuote(ctx, string(activePoolAddress), selectedVoucher.TokenAddress, swapToVoucher.TokenAddress, finalAmountStr) r, err := h.accountService.GetCreditSendReverseQuote(ctx, swapData.ActivePoolAddress, swapData.ActiveSwapFromAddress, swapData.ActiveSwapToAddress, finalAmountStr)
if err != nil { if err != nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
@ -971,19 +805,26 @@ func (h *MenuHandlers) TransactionSwapPreview(ctx context.Context, sym string, i
return res, nil return res, nil
} }
sendInputAmount := r.InputAmount // amount of SAT that should be swapped sendInputAmount := r.InputAmount // amount of SAT that should be swapped
sendOutputAmount := r.OutputAmount // amount of RAT that will be received
// store the finalAmountStr as the final amount (that will be sent after the swap) // store the sendOutputAmount as the final amount (that will be sent)
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(finalAmountStr)) err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(sendOutputAmount))
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to write output amount value entry with", "key", storedb.DATA_AMOUNT, "value", finalAmountStr, "error", err) logg.ErrorCtxf(ctx, "failed to write output amount value entry with", "key", storedb.DATA_AMOUNT, "value", sendOutputAmount, "error", err)
return res, err return res, err
} }
// Scale down the quoted output amount
quoteAmountStr := store.ScaleDownBalance(sendOutputAmount, swapData.ActiveSwapToDecimal)
// Format the qouteAmount amount to 2 decimal places
qouteAmount, _ := store.TruncateDecimalString(quoteAmountStr, 2)
// store the qouteAmount in the temporary value // store the qouteAmount in the temporary value
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(inputStr)) err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(qouteAmount))
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to write temporary inputStr entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", inputStr, "error", err) logg.ErrorCtxf(ctx, "failed to write temporary qouteAmount entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", qouteAmount, "error", err)
return res, err return res, err
} }
@ -996,9 +837,7 @@ func (h *MenuHandlers) TransactionSwapPreview(ctx context.Context, sym string, i
res.Content = l.Get( res.Content = l.Get(
"%s will receive %s %s", "%s will receive %s %s",
string(recipientInput), string(recipientPhoneNumber), qouteAmount, swapData.ActiveSwapToSym,
inputStr,
swapToVoucher.TokenSymbol,
) )
return res, nil return res, nil
@ -1022,37 +861,11 @@ func (h *MenuHandlers) TransactionInitiateSwap(ctx context.Context, sym string,
userStore := h.userdataStore userStore := h.userdataStore
// Resolve active pool swapData, err := store.ReadSwapPreviewData(ctx, userStore, sessionId)
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
if err != nil { if err != nil {
return res, err return res, err
} }
// get the selected voucher
selectedVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
return res, err
}
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
if err != nil {
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
return res, err
}
swapToVoucher, err := store.ReadSwapToVoucher(ctx, h.userdataStore, sessionId)
if err != nil {
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
return res, err
}
quotedAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
if err != nil {
logg.ErrorCtxf(ctx, "failed to read quotedAmount entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
return res, err
}
swapAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT) swapAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err) logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err)
@ -1062,7 +875,7 @@ func (h *MenuHandlers) TransactionInitiateSwap(ctx context.Context, sym string,
swapAmountStr := string(swapAmount) swapAmountStr := string(swapAmount)
// Call the poolSwap API // Call the poolSwap API
poolSwap, err := h.accountService.PoolSwap(ctx, swapAmountStr, string(publicKey), selectedVoucher.TokenAddress, string(activePoolAddress), swapToVoucher.TokenAddress) poolSwap, err := h.accountService.PoolSwap(ctx, swapAmountStr, swapData.PublicKey, swapData.ActiveSwapFromAddress, swapData.ActivePoolAddress, swapData.ActiveSwapToAddress)
if err != nil { if err != nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
@ -1083,7 +896,7 @@ func (h *MenuHandlers) TransactionInitiateSwap(ctx context.Context, sym string,
logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err) logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err)
return res, err return res, err
} }
recipientInput, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_INPUT) recipientPhoneNumber, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER)
if err != nil { if err != nil {
// invalid state // invalid state
return res, err return res, err
@ -1097,7 +910,7 @@ func (h *MenuHandlers) TransactionInitiateSwap(ctx context.Context, sym string,
} }
// Call TokenTransfer with the expected swap amount // Call TokenTransfer with the expected swap amount
tokenTransfer, err := h.accountService.TokenTransfer(ctx, string(amount), string(publicKey), string(recipientPublicKey), swapToVoucher.TokenAddress) tokenTransfer, err := h.accountService.TokenTransfer(ctx, string(amount), swapData.PublicKey, string(recipientPublicKey), swapData.ActiveSwapToAddress)
if err != nil { if err != nil {
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
res.FlagSet = append(res.FlagSet, flag_api_call_error) res.FlagSet = append(res.FlagSet, flag_api_call_error)
@ -1111,9 +924,9 @@ func (h *MenuHandlers) TransactionInitiateSwap(ctx context.Context, sym string,
res.Content = l.Get( res.Content = l.Get(
"Your request has been sent. %s will receive %s %s from %s.", "Your request has been sent. %s will receive %s %s from %s.",
string(recipientInput), string(recipientPhoneNumber),
string(quotedAmount), swapData.TemporaryValue,
swapToVoucher.TokenSymbol, swapData.ActiveSwapToSym,
sessionId, sessionId,
) )
@ -1126,11 +939,10 @@ func (h *MenuHandlers) ClearTransactionTypeFlag(ctx context.Context, sym string,
var res resource.Result var res resource.Result
flag_swap_transaction, _ := h.flagManager.GetFlag("flag_swap_transaction") flag_swap_transaction, _ := h.flagManager.GetFlag("flag_swap_transaction")
flag_multiple_voucher, _ := h.flagManager.GetFlag("flag_multiple_voucher")
inputStr := string(input) inputStr := string(input)
if inputStr == "0" { if inputStr == "0" {
res.FlagReset = append(res.FlagReset, flag_swap_transaction, flag_multiple_voucher) res.FlagReset = append(res.FlagReset, flag_swap_transaction)
return res, nil return res, nil
} }

View File

@ -452,7 +452,7 @@ func TestGetAmount(t *testing.T) {
assert.Equal(t, formattedAmount, res.Content) assert.Equal(t, formattedAmount, res.Content)
} }
func TestInitiateNormalTransaction(t *testing.T) { func TestInitiateTransaction(t *testing.T) {
sessionId := "254712345678" sessionId := "254712345678"
ctx, store := InitializeTestStore(t) ctx, store := InitializeTestStore(t)
ctx = context.WithValue(ctx, "SessionId", sessionId) ctx = context.WithValue(ctx, "SessionId", sessionId)
@ -538,7 +538,7 @@ func TestInitiateNormalTransaction(t *testing.T) {
mockAccountService.On("TokenTransfer").Return(tt.TransferResponse, nil) mockAccountService.On("TokenTransfer").Return(tt.TransferResponse, nil)
// Call the method under test // Call the method under test
res, _ := h.InitiateNormalTransaction(ctx, "transaction_reset_amount", []byte("")) res, _ := h.InitiateTransaction(ctx, "transaction_reset_amount", []byte(""))
// Assert that no errors occurred // Assert that no errors occurred
assert.NoError(t, err) assert.NoError(t, err)

View File

@ -17,8 +17,8 @@ import (
// ManageVouchers retrieves the token holdings from the API using the "PublicKey" and // ManageVouchers retrieves the token holdings from the API using the "PublicKey" and
// 1. sets the first as the default voucher if no active voucher is set. // 1. sets the first as the default voucher if no active voucher is set.
// 2. Stores list of filtered ordered vouchers (exclude the active voucher) // 2. Stores list of vouchers
// 3. Stores list of ordered vouchers (all vouchers) // 3. Stores list of filtered stable vouchers
// 4. updates the balance of the active voucher // 4. updates the balance of the active voucher
func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
@ -32,7 +32,7 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher") flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher")
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error") flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
flag_multiple_voucher, _ := h.flagManager.GetFlag("flag_multiple_voucher") flag_no_stable_vouchers, _ := h.flagManager.GetFlag("flag_no_stable_vouchers")
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
if err != nil { if err != nil {
@ -73,13 +73,6 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
return res, nil return res, nil
} }
// only set the flag if the user has a single voucher
if len(vouchersResp) == 1 {
res.FlagReset = append(res.FlagReset, flag_multiple_voucher)
} else {
res.FlagSet = append(res.FlagSet, flag_multiple_voucher)
}
res.FlagReset = append(res.FlagReset, flag_no_active_voucher) res.FlagReset = append(res.FlagReset, flag_no_active_voucher)
// add a variable to filter out the active voucher // add a variable to filter out the active voucher
@ -215,6 +208,21 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
// Order all vouchers // Order all vouchers
orderedVouchers := orderVouchers(vouchersResp) orderedVouchers := orderVouchers(vouchersResp)
// Stable voucher presence flag (based on full list)
hasStable := false
for _, v := range orderedVouchers {
if isStableVoucher(v.TokenAddress) {
hasStable = true
break
}
}
if !hasStable {
res.FlagSet = append(res.FlagSet, flag_no_stable_vouchers)
} else {
res.FlagReset = append(res.FlagReset, flag_no_stable_vouchers)
}
// Process ALL vouchers (stable first) // Process ALL vouchers (stable first)
orderedVoucherData := store.ProcessVouchers(orderedVouchers) orderedVoucherData := store.ProcessVouchers(orderedVouchers)
@ -237,7 +245,6 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
} }
// GetVoucherList fetches the list of vouchers from the store and formats them. // GetVoucherList fetches the list of vouchers from the store and formats them.
// does not include the active voucher and is used in select_voucher and pay_debt
func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
@ -266,12 +273,7 @@ func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []b
} }
if len(voucherData) == 0 { if len(voucherData) == 0 {
if sym == "get_paydebt_voucher_list" { res.Content = l.Get("Your active voucher %s is already set", string(activeSym))
res.Content = l.Get("You need another voucher to proceed. Only found %s.", string(activeSym))
} else {
res.Content = l.Get("Your active voucher %s is already set", string(activeSym))
}
return res, nil return res, nil
} }
@ -323,8 +325,8 @@ func (h *MenuHandlers) ViewVoucher(ctx context.Context, sym string, input []byte
return res, nil return res, nil
} }
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil { if err := store.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err) logg.ErrorCtxf(ctx, "failed on StoreTemporaryVoucher", "error", err)
return res, err return res, err
} }
@ -352,9 +354,9 @@ func (h *MenuHandlers) SetVoucher(ctx context.Context, sym string, input []byte)
} }
// Get temporary data // Get temporary data
tempData, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId) tempData, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err) logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
return res, err return res, err
} }
@ -402,50 +404,3 @@ func (h *MenuHandlers) GetVoucherDetails(ctx context.Context, sym string, input
return res, nil return res, nil
} }
// ValidateCreditVoucher sets the selected voucher as the active transaction voucher
func (h *MenuHandlers) ValidateCreditVoucher(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher)
inputStr := string(input)
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
return res, nil
}
userStore := h.userdataStore
metadata, err := store.GetOrderedVoucherData(ctx, userStore, sessionId, inputStr)
if err != nil {
return res, fmt.Errorf("failed to retrieve swap to voucher data: %v", err)
}
if metadata == nil {
res.FlagSet = append(res.FlagSet, flag_incorrect_voucher)
return res, nil
}
// Store the transaction voucher data
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err)
return res, err
}
// Store the state of the custom transaction voucher
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE, []byte("1"))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write custom transaction voucher", "key", storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE, "error", err)
return res, err
}
return res, nil
}

View File

@ -105,14 +105,12 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
ls.DbRs.AddLocalFunc("get_profile_info", appHandlers.GetProfileInfo) ls.DbRs.AddLocalFunc("get_profile_info", appHandlers.GetProfileInfo)
ls.DbRs.AddLocalFunc("verify_yob", appHandlers.VerifyYob) ls.DbRs.AddLocalFunc("verify_yob", appHandlers.VerifyYob)
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", appHandlers.ResetIncorrectYob) ls.DbRs.AddLocalFunc("reset_incorrect_date_format", appHandlers.ResetIncorrectYob)
ls.DbRs.AddLocalFunc("normal_transaction_preview", appHandlers.NormalTransactionPreview) ls.DbRs.AddLocalFunc("initiate_transaction", appHandlers.InitiateTransaction)
ls.DbRs.AddLocalFunc("initiate_normal_transaction", appHandlers.InitiateNormalTransaction)
ls.DbRs.AddLocalFunc("confirm_pin_change", appHandlers.ConfirmPinChange) ls.DbRs.AddLocalFunc("confirm_pin_change", appHandlers.ConfirmPinChange)
ls.DbRs.AddLocalFunc("quit_with_help", appHandlers.QuitWithHelp) ls.DbRs.AddLocalFunc("quit_with_help", appHandlers.QuitWithHelp)
ls.DbRs.AddLocalFunc("fetch_community_balance", appHandlers.FetchCommunityBalance) ls.DbRs.AddLocalFunc("fetch_community_balance", appHandlers.FetchCommunityBalance)
ls.DbRs.AddLocalFunc("manage_vouchers", appHandlers.ManageVouchers) ls.DbRs.AddLocalFunc("manage_vouchers", appHandlers.ManageVouchers)
ls.DbRs.AddLocalFunc("get_voucher_list", appHandlers.GetVoucherList) ls.DbRs.AddLocalFunc("get_vouchers", appHandlers.GetVoucherList)
ls.DbRs.AddLocalFunc("get_paydebt_voucher_list", appHandlers.GetVoucherList)
ls.DbRs.AddLocalFunc("view_voucher", appHandlers.ViewVoucher) ls.DbRs.AddLocalFunc("view_voucher", appHandlers.ViewVoucher)
ls.DbRs.AddLocalFunc("set_voucher", appHandlers.SetVoucher) ls.DbRs.AddLocalFunc("set_voucher", appHandlers.SetVoucher)
ls.DbRs.AddLocalFunc("get_voucher_details", appHandlers.GetVoucherDetails) ls.DbRs.AddLocalFunc("get_voucher_details", appHandlers.GetVoucherDetails)
@ -156,7 +154,6 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
ls.DbRs.AddLocalFunc("pool_deposit_max_amount", appHandlers.PoolDepositMaxAmount) ls.DbRs.AddLocalFunc("pool_deposit_max_amount", appHandlers.PoolDepositMaxAmount)
ls.DbRs.AddLocalFunc("confirm_pool_deposit", appHandlers.ConfirmPoolDeposit) ls.DbRs.AddLocalFunc("confirm_pool_deposit", appHandlers.ConfirmPoolDeposit)
ls.DbRs.AddLocalFunc("initiate_pool_deposit", appHandlers.InitiatePoolDeposit) ls.DbRs.AddLocalFunc("initiate_pool_deposit", appHandlers.InitiatePoolDeposit)
ls.DbRs.AddLocalFunc("validate_credit_voucher", appHandlers.ValidateCreditVoucher)
ls.first = appHandlers.Init ls.first = appHandlers.Init

View File

@ -1 +1,2 @@
{{.confirm_debt_removal}} {{.confirm_debt_removal}}
Enter your PIN:

View File

@ -13,4 +13,7 @@ LOAD validate_amount 64
RELOAD validate_amount RELOAD validate_amount
CATCH invalid_amount flag_invalid_amount 1 CATCH invalid_amount flag_invalid_amount 1
INCMP _ 0 INCMP _ 0
LOAD get_recipient 0
LOAD get_sender 64
LOAD get_amount 32
INCMP transaction_pin * INCMP transaction_pin *

View File

@ -3,13 +3,10 @@ RELOAD transaction_reset
CATCH no_voucher flag_no_active_voucher 1 CATCH no_voucher flag_no_active_voucher 1
MOUT back 0 MOUT back 0
HALT HALT
LOAD clear_trans_type_flag 6
RELOAD clear_trans_type_flag
LOAD validate_recipient 50 LOAD validate_recipient 50
RELOAD validate_recipient RELOAD validate_recipient
CATCH api_failure flag_api_call_error 1 CATCH api_failure flag_api_call_error 1
CATCH invalid_recipient flag_invalid_recipient 1 CATCH invalid_recipient flag_invalid_recipient 1
CATCH invite_recipient flag_invalid_recipient_with_invite 1 CATCH invite_recipient flag_invalid_recipient_with_invite 1
CATCH credit_vouchers flag_multiple_voucher 1
INCMP _ 0 INCMP _ 0
INCMP credit_amount * INCMP credit_amount *

View File

@ -1 +0,0 @@
{{.get_ordered_vouchers}}

View File

@ -1,15 +0,0 @@
LOAD get_ordered_vouchers 0
MAP get_ordered_vouchers
MOUT back 0
MOUT quit 99
MNEXT next 88
MPREV prev 98
HALT
INCMP > 88
INCMP < 98
INCMP _ 0
INCMP quit 99
LOAD validate_credit_voucher 67
RELOAD validate_credit_voucher
CATCH . flag_incorrect_voucher 1
INCMP credit_amount *

View File

@ -10,10 +10,6 @@ INCMP > 88
INCMP < 98 INCMP < 98
INCMP _ 0 INCMP _ 0
INCMP quit 99 INCMP quit 99
LOAD get_mpesa_max_limit 89 LOAD get_mpesa_max_limit 0
RELOAD get_mpesa_max_limit RELOAD get_mpesa_max_limit
CATCH . flag_incorrect_voucher 1
CATCH low_withdraw_mpesa_amount flag_incorrect_pool 1
CATCH low_withdraw_mpesa_amount flag_low_swap_amount 1
CATCH low_withdraw_mpesa_amount flag_api_call_error 1
INCMP mpesa_max_limit * INCMP mpesa_max_limit *

View File

@ -59,7 +59,7 @@ msgid "Enter the amount of M-Pesa to get: (Max %s Ksh)\n"
msgstr "Weka kiasi cha M-Pesa cha kupata: (Kikomo %s Ksh)\n" msgstr "Weka kiasi cha M-Pesa cha kupata: (Kikomo %s Ksh)\n"
msgid "You are sending %s %s in order to receive ~ %s ksh" msgid "You are sending %s %s in order to receive ~ %s ksh"
msgstr "Unatuma ~ %s %s ili upokee %s ksh" msgstr "Unatuma ~ %s %s ili upoke %s ksh"
msgid "Your request has been sent. Please await confirmation" msgid "Your request has been sent. Please await confirmation"
msgstr "Ombi lako limetumwa. Tafadhali subiri" msgstr "Ombi lako limetumwa. Tafadhali subiri"
@ -67,16 +67,16 @@ msgstr "Ombi lako limetumwa. Tafadhali subiri"
msgid "Enter the amount of M-Pesa to send: (Minimum %s Ksh)\n" msgid "Enter the amount of M-Pesa to send: (Minimum %s Ksh)\n"
msgstr "Weka kiasi cha M-Pesa cha kutuma: (Kima cha chini %s Ksh)\n" msgstr "Weka kiasi cha M-Pesa cha kutuma: (Kima cha chini %s Ksh)\n"
msgid "You will get a prompt for your Mpesa PIN shortly to send %s ksh and receive ~ %s %s" msgid "You will get a prompt for your M-Pesa PIN shortly to send %s ksh and receive ~ %s cUSD"
msgstr "Utapokea kidokezo cha PIN yako ya Mpesa hivi karibuni kutuma %s ksh na kupokea ~ %s %s" msgstr "Utapokea kidokezo cha PIN yako ya M-Pesa hivi karibuni kutuma %s ksh na kupokea ~ %s cUSD"
msgid "Your request has been sent. Thank you for using Sarafu" msgid "Your request has been sent. Thank you for using Sarafu"
msgstr "Ombi lako limetumwa. Asante kwa kutumia huduma ya Sarafu" msgstr "Ombi lako limetumwa. Asante kwa kutumia huduma ya Sarafu"
msgid "You can remove a max of %s %s from '%s' pool\nEnter amount of %s:(Max: %s)" msgid "You can remove a maximum of %s %s from '%s' pool\n\nEnter amount of %s:"
msgstr "Unaweza kuondoa kiwango cha juu cha %s %s kutoka kwenye '%s'\n\nWeka kiwango cha %s:(Kikomo: %s)" msgstr "Unaweza kuondoa kiwango cha juu cha %s %s kutoka kwenye '%s'\n\nWeka kiwango cha %s:"
msgid "Please confirm that you will use %s %s to remove your debt of %s %s\nEnter your PIN:" msgid "Please confirm that you will use %s %s to remove your debt of %s %s\n"
msgstr "Tafadhali thibitisha kwamba utatumia %s %s kulipa deni lako la %s %s.\nWeka PIN yako:" msgstr "Tafadhali thibitisha kwamba utatumia %s %s kulipa deni lako la %s %s.\nWeka PIN yako:"
msgid "Your active voucher %s is already set" msgid "Your active voucher %s is already set"
@ -89,25 +89,4 @@ msgid "You will deposit %s %s into %s\n"
msgstr "Utaweka %s %s kwenye %s\n" msgstr "Utaweka %s %s kwenye %s\n"
msgid "Your request has been sent. You will receive an SMS when %s %s has been deposited into %s." msgid "Your request has been sent. You will receive an SMS when %s %s has been deposited into %s."
msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati %s %s itawekwa kwenye %s." msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati %s %s itawekwa kwenye %s."
msgid "%s will receive %s %s from %s"
msgstr %s atapokea %s %s kutoka kwa %s"
msgid "You need another voucher to proceed. Only found %s."
msgstr "Unahitaji kua na sarafu nyingine. Tumepata tu %s."
msgid "Maximum: %s %s\n\nEnter amount of %s to swap for %s:"
msgstr "Kikimo: %s %s\n\nWeka kiasi cha %s kitakacho badilishwa kua %s:"
msgid "You will swap %s %s for %s %s:"
msgstr "Utabadilisha %s %s kua %s %s:"
msgid "Your request has been sent. You will receive an SMS when your debt of %s %s has been removed from %s."
msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati deni lako la %s %s litatolewa kwa %s."
msgid "Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n"
msgstr "Weka kiasi cha Mpesa utakacho toa: (Min: Ksh %s, Max %s Ksh)\n"
msgid "Enter the amount of credit to deposit: (Minimum %s Ksh)\n"
msgstr "Weka kiasi utakacho weka (Kima cha chini: %s Ksh)\n"

View File

@ -1 +1 @@
Available amount {{.calculate_max_pay_debt}} is too low, please choose a different voucher: You have a low debt amount

View File

@ -1,6 +1,5 @@
MAP calculate_max_pay_debt
MOUT back 0 MOUT back 0
MOUT quit 9 MOUT quit 9
HALT HALT
INCMP _ 0 INCMP ^ 0
INCMP quit 9 INCMP quit 9

View File

@ -1 +1 @@
Kiasi kinachopatikana {{.calculate_max_pay_debt}} ni cha chini sana, tafadhali chagua sarafu tofauti: Kiasi cha deni lako ni cha chini sana

View File

@ -1 +1 @@
Available amount {{.swap_max_limit}} is too low, please choose a different voucher: Available amount {{.swap_max_limit}} is too low, please try again:

View File

@ -1 +1 @@
Kiasi kinachopatikana {{.swap_max_limit}} ni cha chini sana, tafadhali chagua sarafu tofauti: Kiasi kinachopatikana {{.swap_max_limit}} ni cha chini sana, tafadhali jaribu tena:

View File

@ -1 +0,0 @@
Available amount {{.get_mpesa_max_limit}} is too low, please choose a different voucher:

View File

@ -1,6 +0,0 @@
MAP get_mpesa_max_limit
MOUT back 0
MOUT quit 9
HALT
INCMP _ 0
INCMP quit 9

View File

@ -1 +0,0 @@
Kiasi kinachopatikana {{.get_mpesa_max_limit}} ni cha chini sana, tafadhali chagua sarafu tofauti:

View File

@ -1 +1 @@
{{.get_paydebt_voucher_list}} {{.get_vouchers}}

View File

@ -1,6 +1,6 @@
CATCH no_voucher flag_no_active_voucher 1 CATCH no_voucher flag_no_active_voucher 1
LOAD get_paydebt_voucher_list 0 LOAD get_vouchers 0
MAP get_paydebt_voucher_list MAP get_vouchers
MOUT back 0 MOUT back 0
MOUT quit 99 MOUT quit 99
MNEXT next 88 MNEXT next 88
@ -13,6 +13,4 @@ INCMP quit 99
LOAD calculate_max_pay_debt 0 LOAD calculate_max_pay_debt 0
RELOAD calculate_max_pay_debt RELOAD calculate_max_pay_debt
CATCH . flag_incorrect_voucher 1 CATCH . flag_incorrect_voucher 1
CATCH low_pay_debt_amount flag_low_swap_amount 1
CATCH low_pay_debt_amount flag_api_call_error 1
INCMP calculate_max_pay_debt * INCMP calculate_max_pay_debt *

View File

@ -0,0 +1 @@
{{.calculate_max_pay_debt}}

View File

@ -1,4 +1,5 @@
CATCH no_voucher flag_no_active_voucher 1 CATCH no_voucher flag_no_active_voucher 1
CATCH no_stable_voucher flag_no_stable_vouchers 1
LOAD get_ordered_vouchers 0 LOAD get_ordered_vouchers 0
MAP get_ordered_vouchers MAP get_ordered_vouchers
MOUT back 0 MOUT back 0

View File

@ -37,4 +37,3 @@ flag,flag_low_swap_amount,43,this is set when the swap max limit is less than 0.
flag,flag_alias_unavailable,44,this is set when the preferred alias is not available flag,flag_alias_unavailable,44,this is set when the preferred alias is not available
flag,flag_swap_transaction,45,this is set when the transaction will involve performing a swap flag,flag_swap_transaction,45,this is set when the transaction will involve performing a swap
flag,flag_no_stable_vouchers,46,this is set when the user does not have a stable voucher flag,flag_no_stable_vouchers,46,this is set when the user does not have a stable voucher
flag,flag_multiple_voucher,47,this is set when the user only has a multiple voucher

1 flag flag_language_set 8 checks whether the user has set their prefered language
37 flag flag_alias_unavailable 44 this is set when the preferred alias is not available
38 flag flag_swap_transaction 45 this is set when the transaction will involve performing a swap
39 flag flag_no_stable_vouchers 46 this is set when the user does not have a stable voucher
flag flag_multiple_voucher 47 this is set when the user only has a multiple voucher

View File

@ -1 +1 @@
{{.get_voucher_list}} {{.get_vouchers}}

View File

@ -1,6 +1,6 @@
CATCH no_voucher flag_no_active_voucher 1 CATCH no_voucher flag_no_active_voucher 1
LOAD get_voucher_list 0 LOAD get_vouchers 0
MAP get_voucher_list MAP get_vouchers
MOUT back 0 MOUT back 0
MOUT quit 99 MOUT quit 99
MNEXT next 88 MNEXT next 88

View File

@ -1,2 +1,3 @@
{{.send_mpesa_preview}} {{.send_mpesa_preview}}
Enter your PIN to confirm:
Please enter your account PIN to confirm:

View File

@ -1,2 +1,3 @@
{{.send_mpesa_preview}} {{.send_mpesa_preview}}
Weka PIN yako kudhibitisha:
Tafadhali weka PIN ya akaunti yako kudhibitisha:

View File

@ -12,7 +12,7 @@ INCMP > 88
INCMP < 98 INCMP < 98
INCMP _ 0 INCMP _ 0
INCMP quit 99 INCMP quit 99
LOAD swap_max_limit 138 LOAD swap_max_limit 64
RELOAD swap_max_limit RELOAD swap_max_limit
CATCH api_failure flag_api_call_error 1 CATCH api_failure flag_api_call_error 1
CATCH . flag_incorrect_voucher 1 CATCH . flag_incorrect_voucher 1

View File

@ -1,4 +1,10 @@
LOAD reset_incorrect_pin 6 LOAD reset_incorrect_pin 6
CATCH _ flag_account_authorized 0 CATCH _ flag_account_authorized 0
LOAD initiate_normal_transaction 0 RELOAD get_amount
MAP get_amount
RELOAD get_recipient
MAP get_recipient
RELOAD get_sender
MAP get_sender
LOAD initiate_transaction 0
HALT HALT

View File

@ -1,2 +1,2 @@
{{.normal_transaction_preview}} {{.get_recipient}} will receive {{.get_amount}} from {{.get_sender}}
Please enter your PIN to confirm: Please enter your PIN to confirm:

View File

@ -1,5 +1,9 @@
LOAD normal_transaction_preview 0 RELOAD get_amount
MAP normal_transaction_preview MAP get_amount
RELOAD get_recipient
MAP get_recipient
RELOAD get_sender
MAP get_sender
MOUT back 0 MOUT back 0
MOUT quit 9 MOUT quit 9
LOAD authorize_account 6 LOAD authorize_account 6

View File

@ -0,0 +1,2 @@
{{.get_recipient}} atapokea {{.get_amount}} kutoka kwa {{.get_sender}}
Tafadhali weka PIN yako kudhibitisha:

View File

@ -95,12 +95,6 @@ const (
DATA_RECIPIENT_PHONE_NUMBER DATA_RECIPIENT_PHONE_NUMBER
// Currently active swap from balance for the swap // Currently active swap from balance for the swap
DATA_ACTIVE_SWAP_FROM_BALANCE DATA_ACTIVE_SWAP_FROM_BALANCE
// Holds the state whether the transaction uses a custom voucher
DATA_TRANSACTION_CUSTOM_VOUCHER_STATE
// Holds the initial recipient input given by the user
DATA_RECIPIENT_INPUT
// Holds the transaction voucher
DATA_TRANSACTION_CUSTOM_VOUCHER
) )
const ( const (

View File

@ -13,7 +13,7 @@ import (
) )
type TransactionData struct { type TransactionData struct {
RecipientInput string TemporaryValue string
ActiveSym string ActiveSym string
Amount string Amount string
PublicKey string PublicKey string
@ -77,7 +77,7 @@ func ParseAndScaleAmount(storedAmount, activeDecimal string) (string, error) {
func ReadTransactionData(ctx context.Context, store DataStore, sessionId string) (TransactionData, error) { func ReadTransactionData(ctx context.Context, store DataStore, sessionId string) (TransactionData, error) {
data := TransactionData{} data := TransactionData{}
fieldToKey := map[string]storedb.DataTyp{ fieldToKey := map[string]storedb.DataTyp{
"RecipientInput": storedb.DATA_RECIPIENT_INPUT, "TemporaryValue": storedb.DATA_TEMPORARY_VALUE,
"ActiveSym": storedb.DATA_ACTIVE_SYM, "ActiveSym": storedb.DATA_ACTIVE_SYM,
"Amount": storedb.DATA_AMOUNT, "Amount": storedb.DATA_AMOUNT,
"PublicKey": storedb.DATA_PUBLIC_KEY, "PublicKey": storedb.DATA_PUBLIC_KEY,

View File

@ -221,7 +221,7 @@ func TestReadTransactionData(t *testing.T) {
// Test transaction data // Test transaction data
transactionData := map[storedb.DataTyp]string{ transactionData := map[storedb.DataTyp]string{
storedb.DATA_RECIPIENT_INPUT: "0712345678", storedb.DATA_TEMPORARY_VALUE: "0712345678",
storedb.DATA_ACTIVE_SYM: "SRF", storedb.DATA_ACTIVE_SYM: "SRF",
storedb.DATA_AMOUNT: "1000000", storedb.DATA_AMOUNT: "1000000",
storedb.DATA_PUBLIC_KEY: publicKey, storedb.DATA_PUBLIC_KEY: publicKey,
@ -238,7 +238,7 @@ func TestReadTransactionData(t *testing.T) {
} }
expectedResult := TransactionData{ expectedResult := TransactionData{
RecipientInput: "0712345678", TemporaryValue: "0712345678",
ActiveSym: "SRF", ActiveSym: "SRF",
Amount: "1000000", Amount: "1000000",
PublicKey: publicKey, PublicKey: publicKey,

View File

@ -159,10 +159,6 @@ func GetOrderedVoucherData(ctx context.Context, store DataStore, sessionId strin
// MatchVoucher finds the matching voucher symbol, balance, decimals and contract address based on the input. // MatchVoucher finds the matching voucher symbol, balance, decimals and contract address based on the input.
func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol, balance, decimal, address string) { func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol, balance, decimal, address string) {
// case for invalid input with no current symbols
if symbols == "" {
return
}
symList := strings.Split(symbols, "\n") symList := strings.Split(symbols, "\n")
balList := strings.Split(balances, "\n") balList := strings.Split(balances, "\n")
decList := strings.Split(decimals, "\n") decList := strings.Split(decimals, "\n")
@ -189,20 +185,20 @@ func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol,
return return
} }
// StoreTransactionVoucher saves voucher metadata in the DataStore. // StoreTemporaryVoucher saves voucher metadata as temporary entries in the DataStore.
func StoreTransactionVoucher(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error {
tempData := fmt.Sprintf("%s,%s,%s,%s", data.TokenSymbol, data.Balance, data.TokenDecimals, data.TokenAddress) tempData := fmt.Sprintf("%s,%s,%s,%s", data.TokenSymbol, data.Balance, data.TokenDecimals, data.TokenAddress)
if err := store.WriteEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER, []byte(tempData)); err != nil { if err := store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(tempData)); err != nil {
return err return err
} }
return nil return nil
} }
// GetTransactionVoucherData retrieves the transaction voucher metadata from the DataStore. // GetTemporaryVoucherData retrieves temporary voucher metadata from the DataStore.
func GetTransactionVoucherData(ctx context.Context, store DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) { func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) {
temp_data, err := store.ReadEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER) temp_data, err := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -118,7 +118,7 @@ func TestStoreTemporaryVoucher(t *testing.T) {
} }
// Execute the function being tested // Execute the function being tested
err := StoreTransactionVoucher(ctx, store, sessionId, voucherData) err := StoreTemporaryVoucher(ctx, store, sessionId, voucherData)
require.NoError(t, err) require.NoError(t, err)
// Verify stored data // Verify stored data
@ -142,11 +142,11 @@ func TestGetTemporaryVoucherData(t *testing.T) {
} }
// Store the data // Store the data
err := StoreTransactionVoucher(ctx, store, sessionId, tempData) err := StoreTemporaryVoucher(ctx, store, sessionId, tempData)
require.NoError(t, err) require.NoError(t, err)
// Execute the function being tested // Execute the function being tested
data, err := GetTransactionVoucherData(ctx, store, sessionId) data, err := GetTemporaryVoucherData(ctx, store, sessionId)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tempData, data) require.Equal(t, tempData, data)
} }
@ -170,7 +170,7 @@ func TestUpdateVoucherData(t *testing.T) {
TokenDecimals: "8", TokenDecimals: "8",
TokenAddress: "0xold", TokenAddress: "0xold",
} }
require.NoError(t, StoreTransactionVoucher(ctx, store, sessionId, tempData)) require.NoError(t, StoreTemporaryVoucher(ctx, store, sessionId, tempData))
// Execute update // Execute update
err := UpdateVoucherData(ctx, store, sessionId, newData) err := UpdateVoucherData(ctx, store, sessionId, newData)