Compare commits
No commits in common. "master" and "exclude-active-data-from-lists" have entirely different histories.
master
...
exclude-ac
@ -21,7 +21,7 @@ RUN make VISE_PATH=/build/go-vise -B
|
||||
WORKDIR /build/sarafu-vise
|
||||
RUN echo "Building on $BUILDPLATFORM, building for $TARGETPLATFORM"
|
||||
RUN go mod download
|
||||
RUN go build -tags logtrace,online -o sarafu-at -ldflags="-X main.build=${BUILD} -s -w" cmd/africastalking/main.go
|
||||
RUN go build -tags logdebug,online -o sarafu-at -ldflags="-X main.build=${BUILD} -s -w" cmd/africastalking/main.go
|
||||
|
||||
FROM debian:bookworm-slim
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@ -5,7 +5,7 @@ go 1.23.4
|
||||
require (
|
||||
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66
|
||||
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20250417111317-2953f4c2f32e
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a
|
||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306
|
||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694
|
||||
github.com/alecthomas/assert/v2 v2.2.2
|
||||
|
||||
4
go.sum
4
go.sum
@ -20,10 +20,6 @@ git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-12940bb5f284/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a h1:KuhJ/WY4RCGmrXUA680ciaponM4vM5zBOJfnCpUo2fc=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251021120522-6f7802b58cf5 h1:bQglHVxMilciZ9M2PGuLgA+Wkvqo8OqQh6TFYwjtuSE=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251021120522-6f7802b58cf5/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63 h1:yznaUXeAy+qiZb2nCxosYXE5HyCPpynIoplEuYV/zQM=
|
||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306 h1:Jo+yWysWw/N5BJQtAyEMN8ePVvAyPHv+JG4lQti+1N4=
|
||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306/go.mod h1:FdLwYtzsjOIcDiW4uDgDYnB4Wdzq12uJUe0QHSSPbSo=
|
||||
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 h1:DjJlBSz0S13acft5XZDWk7ZYnzElym0xLMYEVgyNJ+E=
|
||||
|
||||
@ -83,7 +83,6 @@ func (h *MenuHandlers) CheckAccountCreated(ctx context.Context, sym string, inpu
|
||||
// CheckBlockedStatus:
|
||||
// 1. Checks whether the DATA_SELF_PIN_RESET is 1 and sets the flag_account_pin_reset
|
||||
// 2. resets the account blocked flag if the PIN attempts have been reset by an admin.
|
||||
// 3. Sets key flags (language and PIN) if the data exists
|
||||
func (h *MenuHandlers) CheckBlockedStatus(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||
var res resource.Result
|
||||
store := h.userdataStore
|
||||
@ -91,30 +90,11 @@ func (h *MenuHandlers) CheckBlockedStatus(ctx context.Context, sym string, input
|
||||
flag_account_blocked, _ := h.flagManager.GetFlag("flag_account_blocked")
|
||||
flag_account_pin_reset, _ := h.flagManager.GetFlag("flag_account_pin_reset")
|
||||
|
||||
flag_pin_set, _ := h.flagManager.GetFlag("flag_pin_set")
|
||||
flag_language_set, _ := h.flagManager.GetFlag("flag_language_set")
|
||||
pinFlagSet := h.st.MatchFlag(flag_pin_set, true)
|
||||
languageFlagSet := h.st.MatchFlag(flag_language_set, true)
|
||||
|
||||
sessionId, ok := ctx.Value("SessionId").(string)
|
||||
if !ok {
|
||||
return res, fmt.Errorf("missing session")
|
||||
}
|
||||
|
||||
// only check the data if the flag isn't set
|
||||
if !pinFlagSet {
|
||||
accountPin, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_PIN)
|
||||
if len(accountPin) > 0 {
|
||||
res.FlagSet = append(res.FlagSet, flag_pin_set)
|
||||
}
|
||||
}
|
||||
if !languageFlagSet {
|
||||
languageCode, _ := store.ReadEntry(ctx, sessionId, storedb.DATA_SELECTED_LANGUAGE_CODE)
|
||||
if len(languageCode) > 0 {
|
||||
res.FlagSet = append(res.FlagSet, flag_language_set)
|
||||
}
|
||||
}
|
||||
|
||||
res.FlagReset = append(res.FlagReset, flag_account_pin_reset)
|
||||
|
||||
selfPinReset, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SELF_PIN_RESET)
|
||||
|
||||
@ -5,7 +5,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"git.defalsify.org/vise.git/resource"
|
||||
"git.defalsify.org/vise.git/state"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-api/testutil/mocks"
|
||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||
@ -94,24 +93,16 @@ func TestCheckBlockedStatus(t *testing.T) {
|
||||
}
|
||||
flag_account_blocked, _ := fm.GetFlag("flag_account_blocked")
|
||||
flag_account_pin_reset, _ := fm.GetFlag("flag_account_pin_reset")
|
||||
flag_pin_set, _ := fm.GetFlag("flag_pin_set")
|
||||
flag_language_set, _ := fm.GetFlag("flag_language_set")
|
||||
|
||||
// Set the flag in the State
|
||||
mockState := state.NewState(128)
|
||||
|
||||
h := &MenuHandlers{
|
||||
userdataStore: store,
|
||||
flagManager: fm,
|
||||
st: mockState,
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
currentWrongPinAttempts string
|
||||
expectedResult resource.Result
|
||||
languageSet bool
|
||||
PinSet bool
|
||||
}{
|
||||
{
|
||||
name: "Currently blocked account",
|
||||
@ -127,16 +118,6 @@ func TestCheckBlockedStatus(t *testing.T) {
|
||||
FlagReset: []uint32{flag_account_pin_reset, flag_account_blocked},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid account with reset language and PIN flags",
|
||||
currentWrongPinAttempts: "0",
|
||||
languageSet: true,
|
||||
PinSet: true,
|
||||
expectedResult: resource.Result{
|
||||
FlagReset: []uint32{flag_account_pin_reset, flag_account_blocked},
|
||||
FlagSet: []uint32{flag_pin_set, flag_language_set},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -145,18 +126,6 @@ func TestCheckBlockedStatus(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if tt.languageSet {
|
||||
if err := store.WriteEntry(ctx, sessionId, storedb.DATA_SELECTED_LANGUAGE_CODE, []byte("eng")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if tt.PinSet {
|
||||
if err := store.WriteEntry(ctx, sessionId, storedb.DATA_ACCOUNT_PIN, []byte("hasedPinValue")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
res, err := h.CheckBlockedStatus(ctx, "", []byte(""))
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
@ -2,7 +2,6 @@ package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -12,7 +11,6 @@ import (
|
||||
"git.grassecon.net/grassrootseconomics/common/identity"
|
||||
"git.grassecon.net/grassrootseconomics/common/phone"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-api/models"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-api/remote/http"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
||||
@ -359,20 +357,9 @@ func (h *MenuHandlers) InitiateTransaction(ctx context.Context, sym string, inpu
|
||||
// Call TokenTransfer
|
||||
r, err := h.accountService.TokenTransfer(ctx, finalAmountStr, data.PublicKey, data.Recipient, data.ActiveAddress)
|
||||
if err != nil {
|
||||
var apiErr *http.APIError
|
||||
if errors.As(err, &apiErr) {
|
||||
switch apiErr.Code {
|
||||
case "E10":
|
||||
res.Content = l.Get("Only USD vouchers are allowed to mpesa.sarafu.eth.")
|
||||
default:
|
||||
res.Content = l.Get("Your request failed. Please try again later.")
|
||||
}
|
||||
} else {
|
||||
res.Content = l.Get("An unexpected error occurred. 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, nil
|
||||
}
|
||||
|
||||
@ -289,11 +289,8 @@ func (h *MenuHandlers) GetVoucherDetails(ctx context.Context, sym string, input
|
||||
}
|
||||
res.FlagReset = append(res.FlagReset, flag_api_error)
|
||||
|
||||
// sanitize invalid characters
|
||||
symbol := strings.ReplaceAll(voucherData.TokenSymbol, "USD₮", "USDT")
|
||||
|
||||
res.Content = fmt.Sprintf(
|
||||
"Name: %s\nSymbol: %s\nProduct: %s\nLocation: %s", voucherData.TokenName, symbol, voucherData.TokenCommodity, voucherData.TokenLocation,
|
||||
"Name: %s\nSymbol: %s\nCommodity: %s\nLocation: %s", voucherData.TokenName, voucherData.TokenSymbol, voucherData.TokenCommodity, voucherData.TokenLocation,
|
||||
)
|
||||
|
||||
return res, nil
|
||||
|
||||
@ -272,7 +272,7 @@ func TestGetVoucherDetails(t *testing.T) {
|
||||
TokenCommodity: "Farming",
|
||||
}
|
||||
expectedResult.Content = fmt.Sprintf(
|
||||
"Name: %s\nSymbol: %s\nProduct: %s\nLocation: %s", tokenDetails.TokenName, tokenDetails.TokenSymbol, tokenDetails.TokenCommodity, tokenDetails.TokenLocation,
|
||||
"Name: %s\nSymbol: %s\nCommodity: %s\nLocation: %s", tokenDetails.TokenName, tokenDetails.TokenSymbol, tokenDetails.TokenCommodity, tokenDetails.TokenLocation,
|
||||
)
|
||||
mockAccountService.On("VoucherData", string(tokA_AAddress)).Return(tokenDetails, nil)
|
||||
res, err := h.GetVoucherDetails(ctx, "SessionId", []byte(""))
|
||||
|
||||
@ -41,7 +41,4 @@ msgid "%s is not in %s. Please update your voucher and try again."
|
||||
msgstr "%s haipo kwenye %s. Tafadhali badilisha sarafu yako na ujaribu tena."
|
||||
|
||||
msgid "Name: %s\nSymbol: %s"
|
||||
msgstr "Jina: %s\nSarafu: %s"
|
||||
|
||||
msgid "Only USD vouchers are allowed to mpesa.sarafu.eth."
|
||||
msgstr "Ni sarafu za USD pekee zinazoruhusiwa kwa mpesa.sarafu.eth."
|
||||
msgstr "Jina: %s\nSarafu: %s"
|
||||
@ -15,11 +15,6 @@ var (
|
||||
logg = logging.NewVanilla().WithDomain("vouchers").WithContextKey("SessionId")
|
||||
)
|
||||
|
||||
// symbolReplacements holds mappings of invalid symbols → valid ones
|
||||
var symbolReplacements = map[string]string{
|
||||
"USD₮": "USDT",
|
||||
}
|
||||
|
||||
// VoucherMetadata helps organize data fields
|
||||
type VoucherMetadata struct {
|
||||
Symbols string
|
||||
@ -28,24 +23,13 @@ type VoucherMetadata struct {
|
||||
Addresses string
|
||||
}
|
||||
|
||||
// sanitizeSymbol replaces known invalid token symbols with normalized ones
|
||||
func sanitizeSymbol(symbol string) string {
|
||||
if replacement, ok := symbolReplacements[symbol]; ok {
|
||||
return replacement
|
||||
}
|
||||
return symbol
|
||||
}
|
||||
|
||||
// ProcessVouchers converts holdings into formatted strings
|
||||
func ProcessVouchers(holdings []dataserviceapi.TokenHoldings) VoucherMetadata {
|
||||
var data VoucherMetadata
|
||||
var symbols, balances, decimals, addresses []string
|
||||
|
||||
for i, h := range holdings {
|
||||
// normalize token symbol before use
|
||||
cleanSymbol := sanitizeSymbol(h.TokenSymbol)
|
||||
|
||||
symbols = append(symbols, fmt.Sprintf("%d:%s", i+1, cleanSymbol))
|
||||
symbols = append(symbols, fmt.Sprintf("%d:%s", i+1, h.TokenSymbol))
|
||||
|
||||
// Scale down the balance
|
||||
scaledBalance := ScaleDownBalance(h.Balance, h.TokenDecimals)
|
||||
|
||||
@ -61,14 +61,13 @@ func TestProcessVouchers(t *testing.T) {
|
||||
holdings := []dataserviceapi.TokenHoldings{
|
||||
{TokenAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100000000"},
|
||||
{TokenAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200000000"},
|
||||
{TokenAddress: "0x41c143d63Qa", TokenSymbol: "USD₮", TokenDecimals: "6", Balance: "300000000"},
|
||||
}
|
||||
|
||||
expectedResult := VoucherMetadata{
|
||||
Symbols: "1:SRF\n2:MILO\n3:USDT",
|
||||
Balances: "1:100\n2:20000\n3:300",
|
||||
Decimals: "1:6\n2:4\n3:6",
|
||||
Addresses: "1:0xd4c288865Ce\n2:0x41c188d63Qa\n3:0x41c143d63Qa",
|
||||
Symbols: "1:SRF\n2:MILO",
|
||||
Balances: "1:100\n2:20000",
|
||||
Decimals: "1:6\n2:4",
|
||||
Addresses: "1:0xd4c288865Ce\n2:0x41c188d63Qa",
|
||||
}
|
||||
|
||||
result := ProcessVouchers(holdings)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user