From a6cd3d93b4479ea69a3ef5240fc47a7a6f99e17e Mon Sep 17 00:00:00 2001 From: alfred-mk Date: Tue, 1 Jul 2025 01:55:30 +0300 Subject: [PATCH] added transactions.go for transaction histories --- handlers/application/menuhandler.go | 178 ------------------------- handlers/application/transactions.go | 190 +++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 178 deletions(-) create mode 100644 handlers/application/transactions.go diff --git a/handlers/application/menuhandler.go b/handlers/application/menuhandler.go index 56a80fa..827659d 100644 --- a/handlers/application/menuhandler.go +++ b/handlers/application/menuhandler.go @@ -1919,184 +1919,6 @@ func (h *MenuHandlers) SetPool(ctx context.Context, sym string, input []byte) (r return res, nil } -// CheckTransactions retrieves the transactions from the API using the "PublicKey" and stores to prefixDb. -func (h *MenuHandlers) CheckTransactions(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") - } - - flag_no_transfers, _ := h.flagManager.GetFlag("flag_no_transfers") - flag_api_error, _ := h.flagManager.GetFlag("flag_api_error") - - userStore := h.userdataStore - logdb := h.logDb - publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) - if err != nil { - logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) - return res, err - } - - // Fetch transactions from the API using the public key - transactionsResp, err := h.accountService.FetchTransactions(ctx, string(publicKey)) - if err != nil { - res.FlagSet = append(res.FlagSet, flag_api_error) - logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err) - return res, err - } - res.FlagReset = append(res.FlagReset, flag_api_error) - - // Return if there are no transactions - if len(transactionsResp) == 0 { - res.FlagSet = append(res.FlagSet, flag_no_transfers) - return res, nil - } - - data := store.ProcessTransfers(transactionsResp) - - // Store all transaction data - dataMap := map[storedb.DataTyp]string{ - storedb.DATA_TX_SENDERS: data.Senders, - storedb.DATA_TX_RECIPIENTS: data.Recipients, - storedb.DATA_TX_VALUES: data.TransferValues, - storedb.DATA_TX_ADDRESSES: data.Addresses, - storedb.DATA_TX_HASHES: data.TxHashes, - storedb.DATA_TX_DATES: data.Dates, - storedb.DATA_TX_SYMBOLS: data.Symbols, - storedb.DATA_TX_DECIMALS: data.Decimals, - } - - for key, value := range dataMap { - if err := h.prefixDb.Put(ctx, []byte(storedb.ToBytes(key)), []byte(value)); err != nil { - logg.ErrorCtxf(ctx, "failed to write to prefixDb", "error", err) - return res, err - } - err = logdb.WriteLogEntry(ctx, sessionId, key, []byte(value)) - if err != nil { - logg.DebugCtxf(ctx, "Failed to write tx db log entry", "key", key, "value", value) - } - } - - res.FlagReset = append(res.FlagReset, flag_no_transfers) - - return res, nil -} - -// GetTransactionsList fetches the list of transactions and formats them. -func (h *MenuHandlers) GetTransactionsList(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") - } - - userStore := h.userdataStore - publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) - if err != nil { - logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) - return res, err - } - - // Read transactions from the store and format them - TransactionSenders, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_SENDERS)) - if err != nil { - logg.ErrorCtxf(ctx, "Failed to read the TransactionSenders from prefixDb", "error", err) - return res, err - } - TransactionSyms, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_SYMBOLS)) - if err != nil { - logg.ErrorCtxf(ctx, "Failed to read the TransactionSyms from prefixDb", "error", err) - return res, err - } - TransactionValues, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_VALUES)) - if err != nil { - logg.ErrorCtxf(ctx, "Failed to read the TransactionValues from prefixDb", "error", err) - return res, err - } - TransactionDates, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_DATES)) - if err != nil { - logg.ErrorCtxf(ctx, "Failed to read the TransactionDates from prefixDb", "error", err) - return res, err - } - - // Parse the data - senders := strings.Split(string(TransactionSenders), "\n") - syms := strings.Split(string(TransactionSyms), "\n") - values := strings.Split(string(TransactionValues), "\n") - dates := strings.Split(string(TransactionDates), "\n") - - var formattedTransactions []string - for i := 0; i < len(senders); i++ { - sender := strings.TrimSpace(senders[i]) - sym := strings.TrimSpace(syms[i]) - value := strings.TrimSpace(values[i]) - date := strings.Split(strings.TrimSpace(dates[i]), " ")[0] - - status := "Received" - if sender == string(publicKey) { - status = "Sent" - } - - // Use the ReplaceSeparator function for the menu separator - transactionLine := fmt.Sprintf("%d%s%s %s %s %s", i+1, h.ReplaceSeparatorFunc(":"), status, value, sym, date) - formattedTransactions = append(formattedTransactions, transactionLine) - } - - res.Content = strings.Join(formattedTransactions, "\n") - - return res, nil -} - -// ViewTransactionStatement retrieves the transaction statement -// and displays it to the user. -func (h *MenuHandlers) ViewTransactionStatement(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") - } - userStore := h.userdataStore - publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) - if err != nil { - logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) - return res, err - } - - flag_incorrect_statement, _ := h.flagManager.GetFlag("flag_incorrect_statement") - - inputStr := string(input) - if inputStr == "0" || inputStr == "99" || inputStr == "11" || inputStr == "22" { - res.FlagReset = append(res.FlagReset, flag_incorrect_statement) - return res, nil - } - - // Convert input string to integer - index, err := strconv.Atoi(strings.TrimSpace(inputStr)) - if err != nil { - return res, fmt.Errorf("invalid input: must be a number between 1 and 10") - } - - if index < 1 || index > 10 { - return res, fmt.Errorf("invalid input: index must be between 1 and 10") - } - - statement, err := store.GetTransferData(ctx, h.prefixDb, string(publicKey), index) - if err != nil { - return res, fmt.Errorf("failed to retrieve transfer data: %v", err) - } - - if statement == "" { - res.FlagSet = append(res.FlagSet, flag_incorrect_statement) - return res, nil - } - - res.FlagReset = append(res.FlagReset, flag_incorrect_statement) - res.Content = statement - - return res, nil -} - // persistInitialLanguageCode receives an initial language code and persists it to the store func (h *MenuHandlers) persistInitialLanguageCode(ctx context.Context, sessionId string, code string) error { store := h.userdataStore diff --git a/handlers/application/transactions.go b/handlers/application/transactions.go new file mode 100644 index 0000000..62d2a45 --- /dev/null +++ b/handlers/application/transactions.go @@ -0,0 +1,190 @@ +package application + +import ( + "context" + "fmt" + "strconv" + "strings" + + "git.defalsify.org/vise.git/resource" + "git.grassecon.net/grassrootseconomics/sarafu-vise/store" + storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db" +) + +// CheckTransactions retrieves the transactions from the API using the "PublicKey" and stores to prefixDb. +func (h *MenuHandlers) CheckTransactions(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") + } + + flag_no_transfers, _ := h.flagManager.GetFlag("flag_no_transfers") + flag_api_error, _ := h.flagManager.GetFlag("flag_api_error") + + userStore := h.userdataStore + logdb := h.logDb + publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) + return res, err + } + + // Fetch transactions from the API using the public key + transactionsResp, err := h.accountService.FetchTransactions(ctx, string(publicKey)) + if err != nil { + res.FlagSet = append(res.FlagSet, flag_api_error) + logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err) + return res, err + } + res.FlagReset = append(res.FlagReset, flag_api_error) + + // Return if there are no transactions + if len(transactionsResp) == 0 { + res.FlagSet = append(res.FlagSet, flag_no_transfers) + return res, nil + } + + data := store.ProcessTransfers(transactionsResp) + + // Store all transaction data + dataMap := map[storedb.DataTyp]string{ + storedb.DATA_TX_SENDERS: data.Senders, + storedb.DATA_TX_RECIPIENTS: data.Recipients, + storedb.DATA_TX_VALUES: data.TransferValues, + storedb.DATA_TX_ADDRESSES: data.Addresses, + storedb.DATA_TX_HASHES: data.TxHashes, + storedb.DATA_TX_DATES: data.Dates, + storedb.DATA_TX_SYMBOLS: data.Symbols, + storedb.DATA_TX_DECIMALS: data.Decimals, + } + + for key, value := range dataMap { + if err := h.prefixDb.Put(ctx, []byte(storedb.ToBytes(key)), []byte(value)); err != nil { + logg.ErrorCtxf(ctx, "failed to write to prefixDb", "error", err) + return res, err + } + err = logdb.WriteLogEntry(ctx, sessionId, key, []byte(value)) + if err != nil { + logg.DebugCtxf(ctx, "Failed to write tx db log entry", "key", key, "value", value) + } + } + + res.FlagReset = append(res.FlagReset, flag_no_transfers) + + return res, nil +} + +// GetTransactionsList fetches the list of transactions and formats them. +func (h *MenuHandlers) GetTransactionsList(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") + } + + userStore := h.userdataStore + publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) + return res, err + } + + // Read transactions from the store and format them + TransactionSenders, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_SENDERS)) + if err != nil { + logg.ErrorCtxf(ctx, "Failed to read the TransactionSenders from prefixDb", "error", err) + return res, err + } + TransactionSyms, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_SYMBOLS)) + if err != nil { + logg.ErrorCtxf(ctx, "Failed to read the TransactionSyms from prefixDb", "error", err) + return res, err + } + TransactionValues, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_VALUES)) + if err != nil { + logg.ErrorCtxf(ctx, "Failed to read the TransactionValues from prefixDb", "error", err) + return res, err + } + TransactionDates, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_TX_DATES)) + if err != nil { + logg.ErrorCtxf(ctx, "Failed to read the TransactionDates from prefixDb", "error", err) + return res, err + } + + // Parse the data + senders := strings.Split(string(TransactionSenders), "\n") + syms := strings.Split(string(TransactionSyms), "\n") + values := strings.Split(string(TransactionValues), "\n") + dates := strings.Split(string(TransactionDates), "\n") + + var formattedTransactions []string + for i := 0; i < len(senders); i++ { + sender := strings.TrimSpace(senders[i]) + sym := strings.TrimSpace(syms[i]) + value := strings.TrimSpace(values[i]) + date := strings.Split(strings.TrimSpace(dates[i]), " ")[0] + + status := "Received" + if sender == string(publicKey) { + status = "Sent" + } + + // Use the ReplaceSeparator function for the menu separator + transactionLine := fmt.Sprintf("%d%s%s %s %s %s", i+1, h.ReplaceSeparatorFunc(":"), status, value, sym, date) + formattedTransactions = append(formattedTransactions, transactionLine) + } + + res.Content = strings.Join(formattedTransactions, "\n") + + return res, nil +} + +// ViewTransactionStatement retrieves the transaction statement +// and displays it to the user. +func (h *MenuHandlers) ViewTransactionStatement(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") + } + userStore := h.userdataStore + publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) + if err != nil { + logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err) + return res, err + } + + flag_incorrect_statement, _ := h.flagManager.GetFlag("flag_incorrect_statement") + + inputStr := string(input) + if inputStr == "0" || inputStr == "99" || inputStr == "11" || inputStr == "22" { + res.FlagReset = append(res.FlagReset, flag_incorrect_statement) + return res, nil + } + + // Convert input string to integer + index, err := strconv.Atoi(strings.TrimSpace(inputStr)) + if err != nil { + return res, fmt.Errorf("invalid input: must be a number between 1 and 10") + } + + if index < 1 || index > 10 { + return res, fmt.Errorf("invalid input: index must be between 1 and 10") + } + + statement, err := store.GetTransferData(ctx, h.prefixDb, string(publicKey), index) + if err != nil { + return res, fmt.Errorf("failed to retrieve transfer data: %v", err) + } + + if statement == "" { + res.FlagSet = append(res.FlagSet, flag_incorrect_statement) + return res, nil + } + + res.FlagReset = append(res.FlagReset, flag_incorrect_statement) + res.Content = statement + + return res, nil +}