diff --git a/internal/handlers/ussd/menuhandler.go b/internal/handlers/ussd/menuhandler.go index d4ed992..231da95 100644 --- a/internal/handlers/ussd/menuhandler.go +++ b/internal/handlers/ussd/menuhandler.go @@ -1055,13 +1055,13 @@ func (h *Handlers) SetDefaultVoucher(ctx context.Context, sym string, input []by if db.IsNotFound(err) { publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) if err != nil { - return res, nil + return res, err } // Fetch vouchers from the API using the public key vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey)) if err != nil { - return res, nil + return res, err } // Return if there is no voucher @@ -1183,7 +1183,7 @@ func (h *Handlers) ViewVoucher(ctx context.Context, sym string, input []byte) (r } res.FlagReset = append(res.FlagReset, flag_incorrect_voucher) - res.Content = fmt.Sprintf("%s\n%s", metadata.Symbol, metadata.Balance) + res.Content = fmt.Sprintf("%s\n%s", metadata.TokenSymbol, metadata.Balance) return res, nil } @@ -1208,6 +1208,6 @@ func (h *Handlers) SetVoucher(ctx context.Context, sym string, input []byte) (re return res, err } - res.Content = tempData.Symbol + res.Content = tempData.TokenSymbol return res, nil } diff --git a/internal/handlers/ussd/menuhandler_test.go b/internal/handlers/ussd/menuhandler_test.go index 6ea44a0..2b76bf1 100644 --- a/internal/handlers/ussd/menuhandler_test.go +++ b/internal/handlers/ussd/menuhandler_test.go @@ -24,6 +24,8 @@ import ( "github.com/grassrootseconomics/eth-custodial/pkg/api" testdataloader "github.com/peteole/testdata-loader" "github.com/stretchr/testify/require" + + dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" ) var ( @@ -1898,12 +1900,10 @@ func TestSetDefaultVoucher(t *testing.T) { if err != nil { t.Logf(err.Error()) } - flag_no_active_voucher, err := fm.GetFlag("flag_no_active_voucher") if err != nil { t.Logf(err.Error()) } - // Define session ID and mock data sessionId := "session123" publicKey := "0X13242618721" @@ -1920,20 +1920,8 @@ func TestSetDefaultVoucher(t *testing.T) { vouchersResp: &models.VoucherHoldingResponse{ Ok: true, Description: "Vouchers fetched successfully", - Result: struct { - Holdings []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - } `json:"holdings"` - }{ - Holdings: []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - }{ + Result: models.VoucherResult{ + Holdings: []dataserviceapi.TokenHoldings{ { ContractAddress: "0x123", TokenSymbol: "TOKEN1", @@ -1950,20 +1938,8 @@ func TestSetDefaultVoucher(t *testing.T) { vouchersResp: &models.VoucherHoldingResponse{ Ok: true, Description: "No vouchers available", - Result: struct { - Holdings []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - } `json:"holdings"` - }{ - Holdings: []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - }{}, + Result: models.VoucherResult{ + Holdings: []dataserviceapi.TokenHoldings{}, }, }, expectedResult: resource.Result{ @@ -2025,12 +2001,7 @@ func TestCheckVouchers(t *testing.T) { mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil) mockVouchersResponse := &models.VoucherHoldingResponse{} - mockVouchersResponse.Result.Holdings = []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - }{ + mockVouchersResponse.Result.Holdings = []dataserviceapi.TokenHoldings{ {ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"}, {ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"}, } diff --git a/internal/models/vouchersresponse.go b/internal/models/vouchersresponse.go index 010730f..09b085d 100644 --- a/internal/models/vouchersresponse.go +++ b/internal/models/vouchersresponse.go @@ -1,15 +1,14 @@ package models -// VoucherHoldingResponse represents a single voucher holding +import dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" + type VoucherHoldingResponse struct { - Ok bool `json:"ok"` - Description string `json:"description"` - Result struct { - Holdings []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - } `json:"holdings"` - } `json:"result"` + Ok bool `json:"ok"` + Description string `json:"description"` + Result VoucherResult `json:"result"` +} + +// VoucherResult holds the list of token holdings +type VoucherResult struct { + Holdings []dataserviceapi.TokenHoldings `json:"holdings"` } diff --git a/internal/testutil/testservice/TestAccountService.go b/internal/testutil/testservice/TestAccountService.go index 6332345..745b80d 100644 --- a/internal/testutil/testservice/TestAccountService.go +++ b/internal/testutil/testservice/TestAccountService.go @@ -7,6 +7,7 @@ import ( "git.grassecon.net/urdt/ussd/internal/models" "github.com/grassrootseconomics/eth-custodial/pkg/api" + dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" ) type TestAccountService struct { @@ -75,20 +76,8 @@ func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) (*models.VoucherHoldingResponse, error) { return &models.VoucherHoldingResponse{ Ok: true, - Result: struct { - Holdings []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - } `json:"holdings"` - }{ - Holdings: []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - }{ + Result: models.VoucherResult{ + Holdings: []dataserviceapi.TokenHoldings{ { ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee", TokenSymbol: "SRF", diff --git a/internal/utils/vouchers.go b/internal/utils/vouchers.go index 11fd7d1..2aed42a 100644 --- a/internal/utils/vouchers.go +++ b/internal/utils/vouchers.go @@ -1,12 +1,12 @@ package utils import ( + "context" "fmt" "strings" - "context" - "git.grassecon.net/urdt/ussd/internal/storage" + dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" ) // VoucherMetadata helps organize voucher data fields @@ -18,12 +18,7 @@ type VoucherMetadata struct { } // ProcessVouchers converts holdings into formatted strings -func ProcessVouchers(holdings []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` -}) VoucherMetadata { +func ProcessVouchers(holdings []dataserviceapi.TokenHoldings) VoucherMetadata { var data VoucherMetadata var symbols, balances, decimals, addresses []string @@ -43,7 +38,7 @@ func ProcessVouchers(holdings []struct { } // GetVoucherData retrieves and matches voucher data -func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*VoucherMetadata, error) { +func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*dataserviceapi.TokenHoldings, error) { keys := []string{"sym", "bal", "deci", "addr"} data := make(map[string]string) @@ -65,11 +60,11 @@ func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*Vo return nil, nil } - return &VoucherMetadata{ - Symbol: symbol, - Balance: balance, - Decimal: decimal, - Address: address, + return &dataserviceapi.TokenHoldings{ + TokenSymbol: string(symbol), + Balance: string(balance), + TokenDecimals: string(decimal), + ContractAddress: string(address), }, nil } @@ -104,12 +99,12 @@ func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol, } // StoreTemporaryVoucher saves voucher metadata as temporary entries in the DataStore. -func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *VoucherMetadata) error { +func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { entries := map[DataTyp][]byte{ - DATA_TEMPORARY_SYM: []byte(data.Symbol), + DATA_TEMPORARY_SYM: []byte(data.TokenSymbol), DATA_TEMPORARY_BAL: []byte(data.Balance), - DATA_TEMPORARY_DECIMAL: []byte(data.Decimal), - DATA_TEMPORARY_ADDRESS: []byte(data.Address), + DATA_TEMPORARY_DECIMAL: []byte(data.TokenDecimals), + DATA_TEMPORARY_ADDRESS: []byte(data.ContractAddress), } for key, value := range entries { @@ -121,7 +116,7 @@ func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId strin } // GetTemporaryVoucherData retrieves temporary voucher metadata from the DataStore. -func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*VoucherMetadata, error) { +func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) { keys := []DataTyp{ DATA_TEMPORARY_SYM, DATA_TEMPORARY_BAL, @@ -129,7 +124,7 @@ func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId str DATA_TEMPORARY_ADDRESS, } - data := &VoucherMetadata{} + data := &dataserviceapi.TokenHoldings{} values := make([][]byte, len(keys)) for i, key := range keys { @@ -140,22 +135,22 @@ func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId str values[i] = value } - data.Symbol = string(values[0]) + data.TokenSymbol = string(values[0]) data.Balance = string(values[1]) - data.Decimal = string(values[2]) - data.Address = string(values[3]) + data.TokenDecimals = string(values[2]) + data.ContractAddress = string(values[3]) return data, nil } // UpdateVoucherData sets the active voucher data and clears the temporary voucher data in the DataStore. -func UpdateVoucherData(ctx context.Context, store DataStore, sessionId string, data *VoucherMetadata) error { +func UpdateVoucherData(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { // Active voucher data entries activeEntries := map[DataTyp][]byte{ - DATA_ACTIVE_SYM: []byte(data.Symbol), + DATA_ACTIVE_SYM: []byte(data.TokenSymbol), DATA_ACTIVE_BAL: []byte(data.Balance), - DATA_ACTIVE_DECIMAL: []byte(data.Decimal), - DATA_ACTIVE_ADDRESS: []byte(data.Address), + DATA_ACTIVE_DECIMAL: []byte(data.TokenDecimals), + DATA_ACTIVE_ADDRESS: []byte(data.ContractAddress), } // Clear temporary voucher data entries diff --git a/internal/utils/vouchers_test.go b/internal/utils/vouchers_test.go index f26ee01..8f8f18e 100644 --- a/internal/utils/vouchers_test.go +++ b/internal/utils/vouchers_test.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/require" memdb "git.defalsify.org/vise.git/db/mem" + dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" ) // InitializeTestDb sets up and returns an in-memory database and store. @@ -61,12 +62,7 @@ func TestMatchVoucher(t *testing.T) { } func TestProcessVouchers(t *testing.T) { - holdings := []struct { - ContractAddress string `json:"contractAddress"` - TokenSymbol string `json:"tokenSymbol"` - TokenDecimals string `json:"tokenDecimals"` - Balance string `json:"balance"` - }{ + holdings := []dataserviceapi.TokenHoldings{ {ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"}, {ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"}, } @@ -112,10 +108,10 @@ func TestGetVoucherData(t *testing.T) { result, err := GetVoucherData(ctx, spdb, "1") assert.NoError(t, err) - assert.Equal(t, "SRF", result.Symbol) + assert.Equal(t, "SRF", result.TokenSymbol) assert.Equal(t, "100", result.Balance) - assert.Equal(t, "6", result.Decimal) - assert.Equal(t, "0xd4c288865Ce", result.Address) + assert.Equal(t, "6", result.TokenDecimals) + assert.Equal(t, "0xd4c288865Ce", result.ContractAddress) } func TestStoreTemporaryVoucher(t *testing.T) { @@ -123,11 +119,11 @@ func TestStoreTemporaryVoucher(t *testing.T) { sessionId := "session123" // Test data - voucherData := &VoucherMetadata{ - Symbol: "SRF", - Balance: "200", - Decimal: "6", - Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", + voucherData := &dataserviceapi.TokenHoldings{ + TokenSymbol: "SRF", + Balance: "200", + TokenDecimals: "6", + ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", } // Execute the function being tested @@ -154,11 +150,11 @@ func TestGetTemporaryVoucherData(t *testing.T) { sessionId := "session123" // Test voucher data - tempData := &VoucherMetadata{ - Symbol: "SRF", - Balance: "200", - Decimal: "6", - Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", + tempData := &dataserviceapi.TokenHoldings{ + TokenSymbol: "SRF", + Balance: "200", + TokenDecimals: "6", + ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", } // Store the data @@ -176,19 +172,19 @@ func TestUpdateVoucherData(t *testing.T) { sessionId := "session123" // New voucher data - newData := &VoucherMetadata{ - Symbol: "SRF", - Balance: "200", - Decimal: "6", - Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", + newData := &dataserviceapi.TokenHoldings{ + TokenSymbol: "SRF", + Balance: "200", + TokenDecimals: "6", + ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", } // Old temporary data - tempData := &VoucherMetadata{ - Symbol: "OLD", - Balance: "100", - Decimal: "8", - Address: "0xold", + tempData := &dataserviceapi.TokenHoldings{ + TokenSymbol: "OLD", + Balance: "100", + TokenDecimals: "8", + ContractAddress: "0xold", } require.NoError(t, StoreTemporaryVoucher(ctx, store, sessionId, tempData)) @@ -198,10 +194,10 @@ func TestUpdateVoucherData(t *testing.T) { // Verify active data was stored correctly activeEntries := map[DataTyp][]byte{ - DATA_ACTIVE_SYM: []byte(newData.Symbol), + DATA_ACTIVE_SYM: []byte(newData.TokenSymbol), DATA_ACTIVE_BAL: []byte(newData.Balance), - DATA_ACTIVE_DECIMAL: []byte(newData.Decimal), - DATA_ACTIVE_ADDRESS: []byte(newData.Address), + DATA_ACTIVE_DECIMAL: []byte(newData.TokenDecimals), + DATA_ACTIVE_ADDRESS: []byte(newData.ContractAddress), } for key, expectedValue := range activeEntries {