diff --git a/handlers/application/vouchers.go b/handlers/application/vouchers.go index d3d219c..056f989 100644 --- a/handlers/application/vouchers.go +++ b/handlers/application/vouchers.go @@ -289,8 +289,11 @@ 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\nCommodity: %s\nLocation: %s", voucherData.TokenName, voucherData.TokenSymbol, voucherData.TokenCommodity, voucherData.TokenLocation, + "Name: %s\nSymbol: %s\nProduct: %s\nLocation: %s", voucherData.TokenName, symbol, voucherData.TokenCommodity, voucherData.TokenLocation, ) return res, nil diff --git a/handlers/application/vouchers_test.go b/handlers/application/vouchers_test.go index 1113a72..cbe3ddf 100644 --- a/handlers/application/vouchers_test.go +++ b/handlers/application/vouchers_test.go @@ -272,7 +272,7 @@ func TestGetVoucherDetails(t *testing.T) { TokenCommodity: "Farming", } expectedResult.Content = fmt.Sprintf( - "Name: %s\nSymbol: %s\nCommodity: %s\nLocation: %s", tokenDetails.TokenName, tokenDetails.TokenSymbol, tokenDetails.TokenCommodity, tokenDetails.TokenLocation, + "Name: %s\nSymbol: %s\nProduct: %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("")) diff --git a/store/vouchers.go b/store/vouchers.go index a8f4504..efb59ed 100644 --- a/store/vouchers.go +++ b/store/vouchers.go @@ -15,6 +15,11 @@ 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 @@ -23,13 +28,24 @@ 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 { - symbols = append(symbols, fmt.Sprintf("%d:%s", i+1, h.TokenSymbol)) + // normalize token symbol before use + cleanSymbol := sanitizeSymbol(h.TokenSymbol) + + symbols = append(symbols, fmt.Sprintf("%d:%s", i+1, cleanSymbol)) // Scale down the balance scaledBalance := ScaleDownBalance(h.Balance, h.TokenDecimals) diff --git a/store/vouchers_test.go b/store/vouchers_test.go index 3526772..ff756b6 100644 --- a/store/vouchers_test.go +++ b/store/vouchers_test.go @@ -61,13 +61,14 @@ 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", - Balances: "1:100\n2:20000", - Decimals: "1:6\n2:4", - Addresses: "1:0xd4c288865Ce\n2:0x41c188d63Qa", + 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", } result := ProcessVouchers(holdings)