Compare commits

..

No commits in common. "caafe495be8d60a04e36d4306d4c2509adce8a22" and "adaa0c63ef78486223ec5e9646640599ceda685d" have entirely different histories.

8 changed files with 124 additions and 78 deletions

2
go.mod
View File

@ -12,8 +12,6 @@ require (
gopkg.in/leonelquinteros/gotext.v1 v1.3.1 gopkg.in/leonelquinteros/gotext.v1 v1.3.1
) )
require github.com/grassrootseconomics/ussd-data-service v0.0.0-20241003123429-4904b4438a3a // indirect
require ( require (
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect

2
go.sum
View File

@ -18,8 +18,6 @@ github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/grassrootseconomics/eth-custodial v1.3.0-beta h1:twrMBhl89GqDUL9PlkzQxMP/6OST1BByrNDj+rqXDmU= github.com/grassrootseconomics/eth-custodial v1.3.0-beta h1:twrMBhl89GqDUL9PlkzQxMP/6OST1BByrNDj+rqXDmU=
github.com/grassrootseconomics/eth-custodial v1.3.0-beta/go.mod h1:7uhRcdnJplX4t6GKCEFkbeDhhjlcaGJeJqevbcvGLZo= github.com/grassrootseconomics/eth-custodial v1.3.0-beta/go.mod h1:7uhRcdnJplX4t6GKCEFkbeDhhjlcaGJeJqevbcvGLZo=
github.com/grassrootseconomics/ussd-data-service v0.0.0-20241003123429-4904b4438a3a h1:q/YH7nE2j8epNmFnTu0tU1vwtCxtQ6nH+d7hRVV5krU=
github.com/grassrootseconomics/ussd-data-service v0.0.0-20241003123429-4904b4438a3a/go.mod h1:hdKaKwqiW6/kphK4j/BhmuRlZDLo1+DYo3gYw5O0siw=
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo= github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo=
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=

View File

@ -1055,13 +1055,13 @@ func (h *Handlers) SetDefaultVoucher(ctx context.Context, sym string, input []by
if db.IsNotFound(err) { if db.IsNotFound(err) {
publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY) publicKey, err := store.ReadEntry(ctx, sessionId, utils.DATA_PUBLIC_KEY)
if err != nil { if err != nil {
return res, err return res, nil
} }
// Fetch vouchers from the API using the public key // Fetch vouchers from the API using the public key
vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey)) vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey))
if err != nil { if err != nil {
return res, err return res, nil
} }
// Return if there is no voucher // 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.FlagReset = append(res.FlagReset, flag_incorrect_voucher)
res.Content = fmt.Sprintf("%s\n%s", metadata.TokenSymbol, metadata.Balance) res.Content = fmt.Sprintf("%s\n%s", metadata.Symbol, metadata.Balance)
return res, nil return res, nil
} }
@ -1208,6 +1208,6 @@ func (h *Handlers) SetVoucher(ctx context.Context, sym string, input []byte) (re
return res, err return res, err
} }
res.Content = tempData.TokenSymbol res.Content = tempData.Symbol
return res, nil return res, nil
} }

View File

@ -24,8 +24,6 @@ import (
"github.com/grassrootseconomics/eth-custodial/pkg/api" "github.com/grassrootseconomics/eth-custodial/pkg/api"
testdataloader "github.com/peteole/testdata-loader" testdataloader "github.com/peteole/testdata-loader"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
var ( var (
@ -1900,10 +1898,12 @@ func TestSetDefaultVoucher(t *testing.T) {
if err != nil { if err != nil {
t.Logf(err.Error()) t.Logf(err.Error())
} }
flag_no_active_voucher, err := fm.GetFlag("flag_no_active_voucher") flag_no_active_voucher, err := fm.GetFlag("flag_no_active_voucher")
if err != nil { if err != nil {
t.Logf(err.Error()) t.Logf(err.Error())
} }
// Define session ID and mock data // Define session ID and mock data
sessionId := "session123" sessionId := "session123"
publicKey := "0X13242618721" publicKey := "0X13242618721"
@ -1920,8 +1920,20 @@ func TestSetDefaultVoucher(t *testing.T) {
vouchersResp: &models.VoucherHoldingResponse{ vouchersResp: &models.VoucherHoldingResponse{
Ok: true, Ok: true,
Description: "Vouchers fetched successfully", Description: "Vouchers fetched successfully",
Result: models.VoucherResult{ Result: struct {
Holdings: []dataserviceapi.TokenHoldings{ 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"`
}{
{ {
ContractAddress: "0x123", ContractAddress: "0x123",
TokenSymbol: "TOKEN1", TokenSymbol: "TOKEN1",
@ -1938,8 +1950,20 @@ func TestSetDefaultVoucher(t *testing.T) {
vouchersResp: &models.VoucherHoldingResponse{ vouchersResp: &models.VoucherHoldingResponse{
Ok: true, Ok: true,
Description: "No vouchers available", Description: "No vouchers available",
Result: models.VoucherResult{ Result: struct {
Holdings: []dataserviceapi.TokenHoldings{}, 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"`
}{},
}, },
}, },
expectedResult: resource.Result{ expectedResult: resource.Result{
@ -2001,7 +2025,12 @@ func TestCheckVouchers(t *testing.T) {
mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil) mockDataStore.On("ReadEntry", ctx, sessionId, utils.DATA_PUBLIC_KEY).Return([]byte(publicKey), nil)
mockVouchersResponse := &models.VoucherHoldingResponse{} mockVouchersResponse := &models.VoucherHoldingResponse{}
mockVouchersResponse.Result.Holdings = []dataserviceapi.TokenHoldings{ mockVouchersResponse.Result.Holdings = []struct {
ContractAddress string `json:"contractAddress"`
TokenSymbol string `json:"tokenSymbol"`
TokenDecimals string `json:"tokenDecimals"`
Balance string `json:"balance"`
}{
{ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"}, {ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"},
{ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"}, {ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"},
} }

View File

@ -1,14 +1,15 @@
package models package models
import dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" // VoucherHoldingResponse represents a single voucher holding
type VoucherHoldingResponse struct { type VoucherHoldingResponse struct {
Ok bool `json:"ok"` Ok bool `json:"ok"`
Description string `json:"description"` Description string `json:"description"`
Result VoucherResult `json:"result"` Result struct {
} Holdings []struct {
ContractAddress string `json:"contractAddress"`
// VoucherResult holds the list of token holdings TokenSymbol string `json:"tokenSymbol"`
type VoucherResult struct { TokenDecimals string `json:"tokenDecimals"`
Holdings []dataserviceapi.TokenHoldings `json:"holdings"` Balance string `json:"balance"`
} `json:"holdings"`
} `json:"result"`
} }

View File

@ -7,7 +7,6 @@ import (
"git.grassecon.net/urdt/ussd/internal/models" "git.grassecon.net/urdt/ussd/internal/models"
"github.com/grassrootseconomics/eth-custodial/pkg/api" "github.com/grassrootseconomics/eth-custodial/pkg/api"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
type TestAccountService struct { type TestAccountService struct {
@ -76,8 +75,20 @@ func (tas *TestAccountService) TrackAccountStatus(ctx context.Context, publicKey
func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) (*models.VoucherHoldingResponse, error) { func (tas *TestAccountService) FetchVouchers(ctx context.Context, publicKey string) (*models.VoucherHoldingResponse, error) {
return &models.VoucherHoldingResponse{ return &models.VoucherHoldingResponse{
Ok: true, Ok: true,
Result: models.VoucherResult{ Result: struct {
Holdings: []dataserviceapi.TokenHoldings{ 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"`
}{
{ {
ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee", ContractAddress: "0x6CC75A06ac72eB4Db2eE22F781F5D100d8ec03ee",
TokenSymbol: "SRF", TokenSymbol: "SRF",

View File

@ -1,12 +1,12 @@
package utils package utils
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
"context"
"git.grassecon.net/urdt/ussd/internal/storage" "git.grassecon.net/urdt/ussd/internal/storage"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
) )
// VoucherMetadata helps organize voucher data fields // VoucherMetadata helps organize voucher data fields
@ -18,7 +18,12 @@ type VoucherMetadata struct {
} }
// ProcessVouchers converts holdings into formatted strings // ProcessVouchers converts holdings into formatted strings
func ProcessVouchers(holdings []dataserviceapi.TokenHoldings) VoucherMetadata { func ProcessVouchers(holdings []struct {
ContractAddress string `json:"contractAddress"`
TokenSymbol string `json:"tokenSymbol"`
TokenDecimals string `json:"tokenDecimals"`
Balance string `json:"balance"`
}) VoucherMetadata {
var data VoucherMetadata var data VoucherMetadata
var symbols, balances, decimals, addresses []string var symbols, balances, decimals, addresses []string
@ -38,7 +43,7 @@ func ProcessVouchers(holdings []dataserviceapi.TokenHoldings) VoucherMetadata {
} }
// GetVoucherData retrieves and matches voucher data // GetVoucherData retrieves and matches voucher data
func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*dataserviceapi.TokenHoldings, error) { func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*VoucherMetadata, error) {
keys := []string{"sym", "bal", "deci", "addr"} keys := []string{"sym", "bal", "deci", "addr"}
data := make(map[string]string) data := make(map[string]string)
@ -60,11 +65,11 @@ func GetVoucherData(ctx context.Context, db storage.PrefixDb, input string) (*da
return nil, nil return nil, nil
} }
return &dataserviceapi.TokenHoldings{ return &VoucherMetadata{
TokenSymbol: string(symbol), Symbol: symbol,
Balance: string(balance), Balance: balance,
TokenDecimals: string(decimal), Decimal: decimal,
ContractAddress: string(address), Address: address,
}, nil }, nil
} }
@ -99,12 +104,12 @@ func MatchVoucher(input, symbols, balances, decimals, addresses string) (symbol,
} }
// StoreTemporaryVoucher saves voucher metadata as temporary entries in the DataStore. // StoreTemporaryVoucher saves voucher metadata as temporary entries in the DataStore.
func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *dataserviceapi.TokenHoldings) error { func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId string, data *VoucherMetadata) error {
entries := map[DataTyp][]byte{ entries := map[DataTyp][]byte{
DATA_TEMPORARY_SYM: []byte(data.TokenSymbol), DATA_TEMPORARY_SYM: []byte(data.Symbol),
DATA_TEMPORARY_BAL: []byte(data.Balance), DATA_TEMPORARY_BAL: []byte(data.Balance),
DATA_TEMPORARY_DECIMAL: []byte(data.TokenDecimals), DATA_TEMPORARY_DECIMAL: []byte(data.Decimal),
DATA_TEMPORARY_ADDRESS: []byte(data.ContractAddress), DATA_TEMPORARY_ADDRESS: []byte(data.Address),
} }
for key, value := range entries { for key, value := range entries {
@ -116,7 +121,7 @@ func StoreTemporaryVoucher(ctx context.Context, store DataStore, sessionId strin
} }
// GetTemporaryVoucherData retrieves temporary voucher metadata from the DataStore. // GetTemporaryVoucherData retrieves temporary voucher metadata from the DataStore.
func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*dataserviceapi.TokenHoldings, error) { func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId string) (*VoucherMetadata, error) {
keys := []DataTyp{ keys := []DataTyp{
DATA_TEMPORARY_SYM, DATA_TEMPORARY_SYM,
DATA_TEMPORARY_BAL, DATA_TEMPORARY_BAL,
@ -124,7 +129,7 @@ func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId str
DATA_TEMPORARY_ADDRESS, DATA_TEMPORARY_ADDRESS,
} }
data := &dataserviceapi.TokenHoldings{} data := &VoucherMetadata{}
values := make([][]byte, len(keys)) values := make([][]byte, len(keys))
for i, key := range keys { for i, key := range keys {
@ -135,22 +140,22 @@ func GetTemporaryVoucherData(ctx context.Context, store DataStore, sessionId str
values[i] = value values[i] = value
} }
data.TokenSymbol = string(values[0]) data.Symbol = string(values[0])
data.Balance = string(values[1]) data.Balance = string(values[1])
data.TokenDecimals = string(values[2]) data.Decimal = string(values[2])
data.ContractAddress = string(values[3]) data.Address = string(values[3])
return data, nil return data, nil
} }
// UpdateVoucherData sets the active voucher data and clears the temporary voucher data in the DataStore. // 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 *dataserviceapi.TokenHoldings) error { func UpdateVoucherData(ctx context.Context, store DataStore, sessionId string, data *VoucherMetadata) error {
// Active voucher data entries // Active voucher data entries
activeEntries := map[DataTyp][]byte{ activeEntries := map[DataTyp][]byte{
DATA_ACTIVE_SYM: []byte(data.TokenSymbol), DATA_ACTIVE_SYM: []byte(data.Symbol),
DATA_ACTIVE_BAL: []byte(data.Balance), DATA_ACTIVE_BAL: []byte(data.Balance),
DATA_ACTIVE_DECIMAL: []byte(data.TokenDecimals), DATA_ACTIVE_DECIMAL: []byte(data.Decimal),
DATA_ACTIVE_ADDRESS: []byte(data.ContractAddress), DATA_ACTIVE_ADDRESS: []byte(data.Address),
} }
// Clear temporary voucher data entries // Clear temporary voucher data entries

View File

@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
memdb "git.defalsify.org/vise.git/db/mem" 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. // InitializeTestDb sets up and returns an in-memory database and store.
@ -62,7 +61,12 @@ func TestMatchVoucher(t *testing.T) {
} }
func TestProcessVouchers(t *testing.T) { func TestProcessVouchers(t *testing.T) {
holdings := []dataserviceapi.TokenHoldings{ holdings := []struct {
ContractAddress string `json:"contractAddress"`
TokenSymbol string `json:"tokenSymbol"`
TokenDecimals string `json:"tokenDecimals"`
Balance string `json:"balance"`
}{
{ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"}, {ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"},
{ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"}, {ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"},
} }
@ -108,10 +112,10 @@ func TestGetVoucherData(t *testing.T) {
result, err := GetVoucherData(ctx, spdb, "1") result, err := GetVoucherData(ctx, spdb, "1")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "SRF", result.TokenSymbol) assert.Equal(t, "SRF", result.Symbol)
assert.Equal(t, "100", result.Balance) assert.Equal(t, "100", result.Balance)
assert.Equal(t, "6", result.TokenDecimals) assert.Equal(t, "6", result.Decimal)
assert.Equal(t, "0xd4c288865Ce", result.ContractAddress) assert.Equal(t, "0xd4c288865Ce", result.Address)
} }
func TestStoreTemporaryVoucher(t *testing.T) { func TestStoreTemporaryVoucher(t *testing.T) {
@ -119,11 +123,11 @@ func TestStoreTemporaryVoucher(t *testing.T) {
sessionId := "session123" sessionId := "session123"
// Test data // Test data
voucherData := &dataserviceapi.TokenHoldings{ voucherData := &VoucherMetadata{
TokenSymbol: "SRF", Symbol: "SRF",
Balance: "200", Balance: "200",
TokenDecimals: "6", Decimal: "6",
ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9",
} }
// Execute the function being tested // Execute the function being tested
@ -150,11 +154,11 @@ func TestGetTemporaryVoucherData(t *testing.T) {
sessionId := "session123" sessionId := "session123"
// Test voucher data // Test voucher data
tempData := &dataserviceapi.TokenHoldings{ tempData := &VoucherMetadata{
TokenSymbol: "SRF", Symbol: "SRF",
Balance: "200", Balance: "200",
TokenDecimals: "6", Decimal: "6",
ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9",
} }
// Store the data // Store the data
@ -172,19 +176,19 @@ func TestUpdateVoucherData(t *testing.T) {
sessionId := "session123" sessionId := "session123"
// New voucher data // New voucher data
newData := &dataserviceapi.TokenHoldings{ newData := &VoucherMetadata{
TokenSymbol: "SRF", Symbol: "SRF",
Balance: "200", Balance: "200",
TokenDecimals: "6", Decimal: "6",
ContractAddress: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9", Address: "0xd4c288865Ce0985a481Eef3be02443dF5E2e4Ea9",
} }
// Old temporary data // Old temporary data
tempData := &dataserviceapi.TokenHoldings{ tempData := &VoucherMetadata{
TokenSymbol: "OLD", Symbol: "OLD",
Balance: "100", Balance: "100",
TokenDecimals: "8", Decimal: "8",
ContractAddress: "0xold", Address: "0xold",
} }
require.NoError(t, StoreTemporaryVoucher(ctx, store, sessionId, tempData)) require.NoError(t, StoreTemporaryVoucher(ctx, store, sessionId, tempData))
@ -194,10 +198,10 @@ func TestUpdateVoucherData(t *testing.T) {
// Verify active data was stored correctly // Verify active data was stored correctly
activeEntries := map[DataTyp][]byte{ activeEntries := map[DataTyp][]byte{
DATA_ACTIVE_SYM: []byte(newData.TokenSymbol), DATA_ACTIVE_SYM: []byte(newData.Symbol),
DATA_ACTIVE_BAL: []byte(newData.Balance), DATA_ACTIVE_BAL: []byte(newData.Balance),
DATA_ACTIVE_DECIMAL: []byte(newData.TokenDecimals), DATA_ACTIVE_DECIMAL: []byte(newData.Decimal),
DATA_ACTIVE_ADDRESS: []byte(newData.ContractAddress), DATA_ACTIVE_ADDRESS: []byte(newData.Address),
} }
for key, expectedValue := range activeEntries { for key, expectedValue := range activeEntries {