Compare commits

...

73 Commits

Author SHA1 Message Date
a11ca2a618
reset the flag_language_set and flag_account_created flags if the publicKey does not exist on the db
Some checks failed
release / docker (push) Has been cancelled
2025-04-04 12:05:04 +03:00
4268cc0589
build: logdebug mode
Some checks failed
release / docker (push) Has been cancelled
2025-04-03 15:45:41 +03:00
ae0672c7da
updated the vise version to pop the cache on a new session
Some checks failed
release / docker (push) Has been cancelled
2025-04-02 18:34:04 +03:00
c3567313af Merge pull request 'manage vouchers in single function' (#42) from manage-vouchers-in-single-function into master
Reviewed-on: #42
2025-04-01 21:26:28 +02:00
f82b413e34 Merge branch 'master' into manage-vouchers-in-single-function 2025-04-01 21:26:16 +02:00
ea0fc4491d
removed debug related logs 2025-04-01 11:12:38 +03:00
2634790118 Merge pull request 'use a different key for the suggested aliases' (#47) from fix-double-alias-request into master
Some checks failed
release / docker (push) Has been cancelled
Reviewed-on: #47
2025-03-28 09:35:10 +01:00
272a7ac05f
chore: remove extra colon 2025-03-28 11:32:24 +03:00
39c0d31995
remove verbose logs 2025-03-28 11:26:32 +03:00
18acb53ead
add alias logs
Some checks failed
release / docker (push) Has been cancelled
2025-03-28 11:08:50 +03:00
43d91f84f6
use a different key for the suggested aliases 2025-03-28 10:49:31 +03:00
0914217769
increase the size limit for the manage_vouchers 2025-03-26 14:33:23 +03:00
ea117b7222
replace SetDefaultVoucher and CheckVouchers with ManageVouchers 2025-03-26 14:28:43 +03:00
39e1c84a45
added TestManageVouchers for ManageVouchers 2025-03-26 14:27:17 +03:00
20ee4dfb24
replace SetDefaultVoucher and CheckVouchers with ManageVouchers 2025-03-26 14:26:31 +03:00
0791eb1f11
ci/cd: build with log warn only
Some checks failed
release / docker (push) Has been cancelled
2025-03-25 09:52:37 +03:00
8ebd2bbbfa
remove alias updates from TestUpdateAllProfileItems
Some checks failed
release / docker (push) Has been cancelled
2025-03-24 20:06:07 +03:00
06c534cbb1
remove the subprefix db from TestViewVoucher 2025-03-24 20:03:20 +03:00
b8d53f82bb
remove the subprefix db from TestGetVoucherList 2025-03-24 20:01:44 +03:00
71c01e00cd
remove commented out code 2025-03-24 19:58:43 +03:00
419716a2b4
remove the subprefix db from TestCheckVouchers 2025-03-24 19:57:08 +03:00
54b2088842
Pass correct arguments in the TestGetVoucherData 2025-03-24 19:53:02 +03:00
b2208359d6 Add missing param to the GetVoucherData 2025-03-24 19:46:58 +03:00
0828b1eb10 Increase the limit for the max_amount output 2025-03-24 19:46:58 +03:00
c22f9edeca Merge pull request 'fix-multiple-alias-requests' (#38) from fix-multiple-alias-requests into master
Some checks failed
release / docker (push) Has been cancelled
Reviewed-on: #38
2025-03-24 15:47:26 +01:00
c81b17994a
remove redundant cast on sanitized input 2025-03-24 16:03:30 +03:00
64b42b92ec
Merge branch 'master' into fix-multiple-alias-requests 2025-03-24 16:00:20 +03:00
493f64157b
sanitize alias hint before request 2025-03-24 15:59:13 +03:00
f6c9d54a65
register check-account_created handler
Some checks failed
release / docker (push) Has been cancelled
2025-03-24 12:39:03 +03:00
74c82de472
add check for if public key exists,then explicitly set flag_account_created
Some checks failed
release / docker (push) Has been cancelled
2025-03-24 12:29:40 +03:00
ddb8c6e748
add lowercase balance text translation 2025-03-22 18:39:05 +03:00
87ebd0029b
chore: show default value when profile info is not set 2025-03-22 18:38:35 +03:00
b941cf2562
chore: match profile text prompt 2025-03-22 18:37:27 +03:00
1c8bda5ded
fix(alias): remove alias requests made when a profile item is edited,show a default value when an alias is not set 2025-03-22 09:49:19 +03:00
30cb800450
Added log lines for voucherlist
Some checks failed
release / docker (push) Has been cancelled
2025-03-21 13:58:30 +03:00
680a1e9681
Use userstore for the voucher data instead of subprefixdb
Some checks failed
release / docker (push) Has been cancelled
2025-03-21 13:46:13 +03:00
b327b569fb
fix failing test 2025-03-21 09:05:51 +03:00
445ca0d0ff
Add a default alias to remove bug in retrieving the data
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 22:34:04 +03:00
e681c9cfca
Added debug logs
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 15:23:36 +03:00
d504571014
Added debug logs
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 15:07:02 +03:00
3b16e25ebd
Added debug logs
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 14:54:06 +03:00
5f37856927
Added activeSym logs
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 14:35:06 +03:00
e564f1328b
add fetched vouchers log
Some checks failed
release / docker (push) Has been cancelled
2025-03-20 13:48:34 +03:00
374f79388c
ci/cd: remove ssh binary from Docker builds
Some checks failed
release / docker (push) Has been cancelled
2025-03-18 17:48:55 +03:00
lash
30644d3535 Merge branch 'lash/more-edbug' 2025-03-15 03:12:05 +00:00
lash
e5e857e3cb
Upgrade deps 2025-03-15 03:02:25 +00:00
1af826e87f
dep: update sarafu-api dep
Some checks failed
release / docker (push) Has been cancelled
2025-03-10 12:41:16 +03:00
38ef3b623e
dep: update sarafu-api dep
Some checks failed
release / docker (push) Has been cancelled
2025-03-10 11:53:47 +03:00
f7e7f7bd1c
add for check back,add logs for the alias 2025-03-10 11:51:02 +03:00
bd0e7822ed
dep: upgrade sarafu-api dep
Some checks failed
release / docker (push) Has been cancelled
2025-03-07 16:13:23 +03:00
4dba5f2ab5
dep: upgrade sarafu-api dep
Some checks failed
release / docker (push) Has been cancelled
2025-03-07 09:48:30 +03:00
144398e18b Merge pull request 'ens' (#32) from ens into master
Reviewed-on: #32
Reviewed-by: lash <accounts-grassrootseconomics@holbrook.no>
2025-03-07 06:00:17 +01:00
e97d4be296
refactor: break down checkbalance function to avoild code redandancy,remove misplaced flag setting 2025-03-03 12:16:45 +03:00
c2a0b05c84
fix: update expected content in checkbalance function 2025-03-03 12:12:46 +03:00
20c8af582c
switch to use ens api endpoint for the aliases requests 2025-02-28 17:29:18 +03:00
101afd5ebd
update check balance test 2025-02-27 16:35:41 +03:00
830d867ac8
chore: remove alias tag,use lower case b for balance 2025-02-27 16:35:17 +03:00
0cbe391209
update test data file to include my alias menu option 2025-02-27 16:00:54 +03:00
226d1f5697
fix: update authorize test function 2025-02-27 13:21:42 +03:00
3e422f269f
feat: show alias if set on main node 2025-02-27 13:14:27 +03:00
7a6e5b094f
load current alias 2025-02-27 09:42:25 +03:00
5ed63cec39
reset invalid PIN flag 2025-02-27 09:41:02 +03:00
8f7d5ff66d
feat: add request for ens based names from user input 2025-02-26 16:34:00 +03:00
f922fb6d43
update authorize_account sink value 2025-02-26 15:48:25 +03:00
78af4d225f
add alias account template 2025-02-26 15:47:17 +03:00
b887c67e5d
add node to confirm your alias 2025-02-26 15:14:04 +03:00
0816190469
feat: add node to update your alias 2025-02-26 15:08:29 +03:00
28e734e0ba
feat: add my alias menu option 2025-02-26 15:02:28 +03:00
d92dc026f5
check for invalid PIN 2025-02-26 14:51:16 +03:00
939df35c8c
register new menu handlers 2025-02-26 14:48:19 +03:00
c09ce32010
feat: reset invalid pin flag,update template text 2025-02-26 14:46:09 +03:00
1f0e7c016e
add check for account alias data type 2025-02-26 14:40:17 +03:00
a984c9dd06
add invalid and account alias flags 2025-02-26 14:37:54 +03:00
43 changed files with 489 additions and 311 deletions

View File

@ -21,8 +21,7 @@ RUN make VISE_PATH=/build/go-vise -B
WORKDIR /build/sarafu-vise WORKDIR /build/sarafu-vise
RUN echo "Building on $BUILDPLATFORM, building for $TARGETPLATFORM" RUN echo "Building on $BUILDPLATFORM, building for $TARGETPLATFORM"
RUN go mod download 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
RUN go build -tags logtrace,online -o sarafu-ssh -ldflags="-X main.build=${BUILD} -s -w" cmd/ssh/main.go
FROM debian:bookworm-slim FROM debian:bookworm-slim
@ -37,7 +36,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
WORKDIR /service WORKDIR /service
COPY --from=build /build/sarafu-vise/sarafu-at . COPY --from=build /build/sarafu-vise/sarafu-at .
COPY --from=build /build/sarafu-vise/sarafu-ssh .
COPY --from=build /build/sarafu-vise/LICENSE . COPY --from=build /build/sarafu-vise/LICENSE .
COPY --from=build /build/sarafu-vise/README.md . COPY --from=build /build/sarafu-vise/README.md .
COPY --from=build /build/sarafu-vise/services ./services COPY --from=build /build/sarafu-vise/services ./services
@ -45,6 +43,5 @@ COPY --from=build /build/sarafu-vise/.env.example .
RUN mv .env.example .env RUN mv .env.example .env
EXPOSE 7123 EXPOSE 7123
EXPOSE 7122
CMD ["./sarafu-at"] CMD ["./sarafu-at"]

6
go.mod
View File

@ -3,10 +3,10 @@ module git.grassecon.net/grassrootseconomics/sarafu-vise
go 1.23.4 go 1.23.4
require ( require (
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac git.defalsify.org/vise.git v0.3.2-0.20250401123711-d481b04a6805
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69 git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250310093912-8145b4bd004b
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244 git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694
github.com/alecthomas/assert/v2 v2.2.2 github.com/alecthomas/assert/v2 v2.2.2
github.com/gofrs/uuid v4.4.0+incompatible github.com/gofrs/uuid v4.4.0+incompatible

14
go.sum
View File

@ -1,11 +1,13 @@
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac h1:f/E0ZTclVfMEnD/3Alrzzbg+dOm138zGydV42jT0JPw= git.defalsify.org/vise.git v0.3.1 h1:A6FhMcur09ft/JzUPGXR+KpA17fltfeBnasyvLMZmq4=
git.defalsify.org/vise.git v0.2.3-0.20250205173834-d1f6647211ac/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck= git.defalsify.org/vise.git v0.3.1/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
git.defalsify.org/vise.git v0.3.2-0.20250401123711-d481b04a6805 h1:FnT39aqXcP5YWhwPDBABopSjCu2SlbPFoOVitSpAVxU=
git.defalsify.org/vise.git v0.3.2-0.20250401123711-d481b04a6805/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d h1:5mzLas+jxTUtusOKx4XvU+n2QvrV/mH17MnJRy46siQ= git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d h1:5mzLas+jxTUtusOKx4XvU+n2QvrV/mH17MnJRy46siQ=
git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60= git.grassecon.net/grassrootseconomics/common v0.0.0-20250121134736-ba8cbbccea7d/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60=
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69 h1:cbBpm9uNJak58MpFpNXJuvgCmz+A8kquXr9har4expg= git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250310093912-8145b4bd004b h1:xiTpaqWWoF5qcnarY/9ZkT6aVdnKwqztb2gzIahJn4w=
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250206112944-31eb30de0f69/go.mod h1:gOn89ipaDcDvmQXRMQYKUqcw/sJcwVOPVt2eC6Geip8= git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250310093912-8145b4bd004b/go.mod h1:gOn89ipaDcDvmQXRMQYKUqcw/sJcwVOPVt2eC6Geip8=
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244 h1:BXotWSKg04U97sf/xeWJuUTSVgKk2aEK+5BtBrnafXQ= git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2 h1:YFztSsexCUgFo6M0tbngRwYdgJd3LQV3RO/Jw09u3+k=
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.1.0.20250204132347-1eb0b1555244/go.mod h1:6B6ByxXOiRY0NR7K02Bf3fEu7z+2c/6q8PFVNjC5G8w= git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2/go.mod h1:6B6ByxXOiRY0NR7K02Bf3fEu7z+2c/6q8PFVNjC5G8w=
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 h1:DjJlBSz0S13acft5XZDWk7ZYnzElym0xLMYEVgyNJ+E= git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694 h1:DjJlBSz0S13acft5XZDWk7ZYnzElym0xLMYEVgyNJ+E=
git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694/go.mod h1:DpibtYpnT3nG4Kn556hRAkdu4+CtiI/6MbnQHal51mQ= git.grassecon.net/grassrootseconomics/visedriver-africastalking v0.0.0-20250129070628-5a539172c694/go.mod h1:DpibtYpnT3nG4Kn556hRAkdu4+CtiI/6MbnQHal51mQ=
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=

View File

@ -1,11 +1,14 @@
package application package application
import ( import (
"bytes"
"context" "context"
"errors"
"fmt" "fmt"
"path" "path"
"strconv" "strconv"
"strings" "strings"
"unicode"
"gopkg.in/leonelquinteros/gotext.v1" "gopkg.in/leonelquinteros/gotext.v1"
@ -191,8 +194,9 @@ func (h *MenuHandlers) createAccountNoExist(ctx context.Context, sessionId strin
publicKey := r.PublicKey publicKey := r.PublicKey
data := map[storedb.DataTyp]string{ data := map[storedb.DataTyp]string{
storedb.DATA_TRACKING_ID: trackingId, storedb.DATA_TRACKING_ID: trackingId,
storedb.DATA_PUBLIC_KEY: publicKey, storedb.DATA_PUBLIC_KEY: publicKey,
storedb.DATA_ACCOUNT_ALIAS: "",
} }
store := h.userdataStore store := h.userdataStore
for key, value := range data { for key, value := range data {
@ -239,6 +243,35 @@ func (h *MenuHandlers) CreateAccount(ctx context.Context, sym string, input []by
return res, nil return res, nil
} }
func (h *MenuHandlers) CheckAccountCreated(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
flag_language_set, _ := h.flagManager.GetFlag("flag_language_set")
flag_account_created, _ := h.flagManager.GetFlag("flag_account_created")
store := h.userdataStore
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
_, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
if err != nil {
if db.IsNotFound(err) {
// reset major flags
res.FlagReset = append(res.FlagReset, flag_language_set)
res.FlagReset = append(res.FlagReset, flag_account_created)
return res, nil
}
return res, nil
}
res.FlagSet = append(res.FlagSet, flag_account_created)
return res, nil
}
// ResetValidPin resets the flag_valid_pin flag. // ResetValidPin resets the flag_valid_pin flag.
func (h *MenuHandlers) ResetValidPin(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) ResetValidPin(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
@ -453,6 +486,14 @@ func (h *MenuHandlers) CheckBlockedNumPinMisMatch(ctx context.Context, sym strin
return res, nil return res, nil
} }
// ResetInvalidPIN resets the invalid PIN flag
func (h *MenuHandlers) ResetInvalidPIN(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
flag_invalid_pin, _ := h.flagManager.GetFlag("flag_invalid_pin")
res.FlagReset = append(res.FlagReset, flag_invalid_pin)
return res, nil
}
// ConfirmPinChange validates user's new PIN. If input matches the temporary PIN, saves it as the new account PIN. // ConfirmPinChange validates user's new PIN. If input matches the temporary PIN, saves it as the new account PIN.
func (h *MenuHandlers) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) ConfirmPinChange(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
@ -707,10 +748,6 @@ func (h *MenuHandlers) SaveFirstname(ctx context.Context, sym string, input []by
logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err) logg.ErrorCtxf(ctx, "failed to write firstName entry with", "key", storedb.DATA_FIRST_NAME, "value", temporaryFirstName, "error", err)
return res, err return res, err
} }
err := h.constructAccountAlias(ctx)
if err != nil {
return res, err
}
res.FlagSet = append(res.FlagSet, flag_firstname_set) res.FlagSet = append(res.FlagSet, flag_firstname_set)
} else { } else {
if firstNameSet { if firstNameSet {
@ -1104,6 +1141,22 @@ func (h *MenuHandlers) GetCurrentProfileInfo(ctx context.Context, sym string, in
} }
res.FlagSet = append(res.FlagSet, flag_offerings_set) res.FlagSet = append(res.FlagSet, flag_offerings_set)
res.Content = string(profileInfo) res.Content = string(profileInfo)
case storedb.DATA_ACCOUNT_ALIAS:
profileInfo, err = store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
if err != nil {
if db.IsNotFound(err) {
res.Content = defaultValue
break
}
logg.ErrorCtxf(ctx, "Failed to read account alias entry with", "key", "error", storedb.DATA_ACCOUNT_ALIAS, err)
return res, err
}
alias := string(profileInfo)
if alias == "" {
res.Content = defaultValue
} else {
res.Content = alias
}
default: default:
break break
} }
@ -1147,8 +1200,10 @@ func (h *MenuHandlers) GetProfileInfo(ctx context.Context, sym string, input []b
offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS)) offerings := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_OFFERINGS))
alias := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)) alias := getEntryOrDefault(store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS))
if alias != defaultValue { if alias != defaultValue && alias != "" {
alias = strings.Split(alias, ".")[0] alias = strings.Split(alias, ".")[0]
} else {
alias = defaultValue
} }
// Construct the full name // Construct the full name
@ -1233,10 +1288,6 @@ func (h *MenuHandlers) UpdateAllProfileItems(ctx context.Context, sym string, in
if err != nil { if err != nil {
return res, err return res, err
} }
err = h.constructAccountAlias(ctx)
if err != nil {
return res, err
}
return res, nil return res, nil
} }
@ -1275,6 +1326,7 @@ func (h *MenuHandlers) Authorize(ctx context.Context, sym string, input []byte)
flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin") flag_incorrect_pin, _ := h.flagManager.GetFlag("flag_incorrect_pin")
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized") flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update") flag_allow_update, _ := h.flagManager.GetFlag("flag_allow_update")
flag_invalid_pin, _ := h.flagManager.GetFlag("flag_invalid_pin")
store := h.userdataStore store := h.userdataStore
AccountPin, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_PIN) AccountPin, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_PIN)
@ -1311,6 +1363,9 @@ func (h *MenuHandlers) Authorize(ctx context.Context, sym string, input []byte)
return res, nil return res, nil
} }
} else { } else {
if string(input) != "0" {
res.FlagSet = append(res.FlagSet, flag_invalid_pin)
}
return res, nil return res, nil
} }
return res, nil return res, nil
@ -1411,53 +1466,83 @@ func (h *MenuHandlers) ShowBlockedAccount(ctx context.Context, sym string, input
return res, nil return res, nil
} }
// loadUserContent loads the main user content in the main menu: the alias,balance associated with active voucher
func loadUserContent(ctx context.Context, activeSym string, balance string, alias string) (string, error) {
var content string
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
balFloat, err := strconv.ParseFloat(balance, 64)
if err != nil {
//Only exclude ErrSyntax error to avoid returning an error if the active bal is not available yet
if !errors.Is(err, strconv.ErrSyntax) {
logg.ErrorCtxf(ctx, "failed to parse activeBal as float", "value", balance, "error", err)
return "", err
}
balFloat = 0.00
}
// Format to 2 decimal places
balStr := fmt.Sprintf("%.2f %s", balFloat, activeSym)
if alias != "" {
content = l.Get("%s balance: %s\n", alias, balStr)
} else {
content = l.Get("Balance: %s\n", balStr)
}
return content, nil
}
// CheckBalance retrieves the balance of the active voucher and sets // CheckBalance retrieves the balance of the active voucher and sets
// the balance as the result content. // the balance as the result content.
func (h *MenuHandlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) CheckBalance(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var (
var err error res resource.Result
err error
alias string
content string
)
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
if !ok { if !ok {
return res, fmt.Errorf("missing session") return res, fmt.Errorf("missing session")
} }
code := codeFromCtx(ctx)
l := gotext.NewLocale(translationDir, code)
l.AddDomain("default")
store := h.userdataStore store := h.userdataStore
// get the active sym and active balance // get the active sym and active balance
activeSym, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM) activeSym, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM)
if err != nil { if err != nil {
if db.IsNotFound(err) { logg.InfoCtxf(ctx, "could not find the activeSym in checkBalance:", "err", err)
balance := "0.00" if !db.IsNotFound(err) {
res.Content = l.Get("Balance: %s\n", balance) logg.ErrorCtxf(ctx, "failed to read activeSym entry with", "key", storedb.DATA_ACTIVE_SYM, "error", err)
return res, nil return res, err
} }
logg.ErrorCtxf(ctx, "failed to read activeSym entry with", "key", storedb.DATA_ACTIVE_SYM, "error", err)
return res, err
} }
activeBal, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL) activeBal, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err) if !db.IsNotFound(err) {
return res, err logg.ErrorCtxf(ctx, "failed to read activeBal entry with", "key", storedb.DATA_ACTIVE_BAL, "error", err)
return res, err
}
} }
// Convert activeBal from []byte to float64 accAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
balFloat, err := strconv.ParseFloat(string(activeBal), 64)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "failed to parse activeBal as float", "value", string(activeBal), "error", err) if !db.IsNotFound(err) {
return res, err logg.ErrorCtxf(ctx, "failed to read account alias entry with", "key", storedb.DATA_ACCOUNT_ALIAS, "error", err)
return res, err
}
} else {
alias = strings.Split(string(accAlias), ".")[0]
} }
// Format to 2 decimal places content, err = loadUserContent(ctx, string(activeSym), string(activeBal), alias)
balStr := fmt.Sprintf("%.2f %s", balFloat, activeSym) if err != nil {
return res, err
res.Content = l.Get("Balance: %s\n", balStr) }
res.Content = content
return res, nil return res, nil
} }
@ -1561,6 +1646,7 @@ func (h *MenuHandlers) ValidateRecipient(ctx context.Context, sym string, input
//Perform a search for each search domain,break on first match //Perform a search for each search domain,break on first match
for _, domain := range config.SearchDomains() { for _, domain := range config.SearchDomains() {
fqdn := fmt.Sprintf("%s.%s", recipient, domain) fqdn := fmt.Sprintf("%s.%s", recipient, domain)
logg.InfoCtxf(ctx, "Resolving with fqdn alias", "alias", fqdn)
AliasAddress, err = h.accountService.CheckAliasAddress(ctx, fqdn) AliasAddress, err = h.accountService.CheckAliasAddress(ctx, fqdn)
if err == nil { if err == nil {
AliasAddressResult = AliasAddress.Address AliasAddressResult = AliasAddress.Address
@ -1867,11 +1953,12 @@ func (h *MenuHandlers) InitiateTransaction(ctx context.Context, sym string, inpu
return res, nil return res, nil
} }
// SetDefaultVoucher retrieves the current vouchers // ManageVouchers retrieves the token holdings from the API using the "PublicKey" and
// and sets the first as the default voucher, if no active voucher is set. // 1. sets the first as the default voucher if no active voucher is set.
func (h *MenuHandlers) SetDefaultVoucher(ctx context.Context, sym string, input []byte) (resource.Result, error) { // 2. Stores list of vouchers
// 3. updates the balance of the active voucher
func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
var err error
userStore := h.userdataStore userStore := h.userdataStore
sessionId, ok := ctx.Value("SessionId").(string) sessionId, ok := ctx.Value("SessionId").(string)
@ -1881,31 +1968,31 @@ func (h *MenuHandlers) SetDefaultVoucher(ctx context.Context, sym string, input
flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher") flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher")
// check if the user has an active sym publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
_, err = userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM) if err != nil {
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
return res, err
}
// Fetch vouchers from API
vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey))
if err != nil {
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
return res, nil
}
if len(vouchersResp) == 0 {
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
return res, nil
}
res.FlagReset = append(res.FlagReset, flag_no_active_voucher)
// Check if user has an active voucher with proper error handling
activeSym, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM)
if err != nil { if err != nil {
if db.IsNotFound(err) { if db.IsNotFound(err) {
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY) // No active voucher, set the first one as default
if err != nil {
logg.ErrorCtxf(ctx, "failed to read publicKey entry with", "key", storedb.DATA_PUBLIC_KEY, "error", err)
return res, err
}
// Fetch vouchers from the API using the public key
vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey))
if err != nil {
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
return res, nil
}
// Return if there is no voucher
if len(vouchersResp) == 0 {
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
return res, nil
}
// Use only the first voucher
firstVoucher := vouchersResp[0] firstVoucher := vouchersResp[0]
defaultSym := firstVoucher.TokenSymbol defaultSym := firstVoucher.TokenSymbol
defaultBal := firstVoucher.Balance defaultBal := firstVoucher.Balance
@ -1915,69 +2002,27 @@ func (h *MenuHandlers) SetDefaultVoucher(ctx context.Context, sym string, input
// Scale down the balance // Scale down the balance
scaledBalance := store.ScaleDownBalance(defaultBal, defaultDec) scaledBalance := store.ScaleDownBalance(defaultBal, defaultDec)
// TODO: implement atomic transaction firstVoucherMap := map[storedb.DataTyp]string{
// set the active symbol storedb.DATA_ACTIVE_SYM: defaultSym,
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM, []byte(defaultSym)) storedb.DATA_ACTIVE_BAL: scaledBalance,
if err != nil { storedb.DATA_ACTIVE_DECIMAL: defaultDec,
logg.ErrorCtxf(ctx, "failed to write defaultSym entry with", "key", storedb.DATA_ACTIVE_SYM, "value", defaultSym, "error", err) storedb.DATA_ACTIVE_ADDRESS: defaultAddr,
return res, err
}
// set the active balance
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_BAL, []byte(scaledBalance))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write defaultBal entry with", "key", storedb.DATA_ACTIVE_BAL, "value", scaledBalance, "error", err)
return res, err
}
// set the active decimals
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_DECIMAL, []byte(defaultDec))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write defaultDec entry with", "key", storedb.DATA_ACTIVE_DECIMAL, "value", defaultDec, "error", err)
return res, err
}
// set the active contract address
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS, []byte(defaultAddr))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write defaultAddr entry with", "key", storedb.DATA_ACTIVE_ADDRESS, "value", defaultAddr, "error", err)
return res, err
} }
return res, nil for key, value := range firstVoucherMap {
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
logg.ErrorCtxf(ctx, "Failed to write active voucher data", "key", key, "error", err)
return res, err
}
}
logg.InfoCtxf(ctx, "Default voucher set", "symbol", defaultSym, "balance", defaultBal, "decimals", defaultDec, "address", defaultAddr)
} else {
logg.ErrorCtxf(ctx, "failed to read activeSym entry with", "key", storedb.DATA_ACTIVE_SYM, "error", err)
return res, err
} }
} else {
logg.ErrorCtxf(ctx, "failed to read activeSym entry with", "key", storedb.DATA_ACTIVE_SYM, "error", err) // Update active voucher balance
return res, err
}
res.FlagReset = append(res.FlagReset, flag_no_active_voucher)
return res, nil
}
// CheckVouchers retrieves the token holdings from the API using the "PublicKey" and stores
// them to gdbm.
func (h *MenuHandlers) CheckVouchers(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
}
// Fetch vouchers from the API using the public key
vouchersResp, err := h.accountService.FetchVouchers(ctx, string(publicKey))
if err != nil {
return res, nil
}
// check the current active sym and update the data
activeSym, _ := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM)
if activeSym != nil {
activeSymStr := string(activeSym) activeSymStr := string(activeSym)
// Find the matching voucher data // Find the matching voucher data
@ -2007,9 +2052,8 @@ func (h *MenuHandlers) CheckVouchers(ctx context.Context, sym string, input []by
} }
} }
data := store.ProcessVouchers(vouchersResp)
// Store all voucher data // Store all voucher data
data := store.ProcessVouchers(vouchersResp)
dataMap := map[storedb.DataTyp]string{ dataMap := map[storedb.DataTyp]string{
storedb.DATA_VOUCHER_SYMBOLS: data.Symbols, storedb.DATA_VOUCHER_SYMBOLS: data.Symbols,
storedb.DATA_VOUCHER_BALANCES: data.Balances, storedb.DATA_VOUCHER_BALANCES: data.Balances,
@ -2017,9 +2061,11 @@ func (h *MenuHandlers) CheckVouchers(ctx context.Context, sym string, input []by
storedb.DATA_VOUCHER_ADDRESSES: data.Addresses, storedb.DATA_VOUCHER_ADDRESSES: data.Addresses,
} }
// Write data entries
for key, value := range dataMap { for key, value := range dataMap {
if err := h.prefixDb.Put(ctx, []byte(storedb.ToBytes(key)), []byte(value)); err != nil { if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
return res, nil logg.ErrorCtxf(ctx, "Failed to write data entry for sessionId: %s", sessionId, "key", key, "error", err)
continue
} }
} }
@ -2029,16 +2075,25 @@ func (h *MenuHandlers) CheckVouchers(ctx context.Context, sym string, input []by
// GetVoucherList fetches the list of vouchers and formats them. // GetVoucherList fetches the list of vouchers and formats them.
func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result var res resource.Result
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
userStore := h.userdataStore
// Read vouchers from the store // Read vouchers from the store
voucherData, err := h.prefixDb.Get(ctx, storedb.ToBytes(storedb.DATA_VOUCHER_SYMBOLS)) voucherData, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_SYMBOLS)
logg.InfoCtxf(ctx, "reading GetVoucherList entries for sessionId: %s", sessionId, "key", storedb.DATA_VOUCHER_SYMBOLS, "voucherData", voucherData)
if err != nil { if err != nil {
logg.ErrorCtxf(ctx, "Failed to read the voucherData from prefixDb", "error", err) logg.ErrorCtxf(ctx, "failed to read voucherData entires with", "key", storedb.DATA_VOUCHER_SYMBOLS, "error", err)
return res, err return res, err
} }
formattedData := h.ReplaceSeparatorFunc(string(voucherData)) formattedData := h.ReplaceSeparatorFunc(string(voucherData))
logg.InfoCtxf(ctx, "final output for sessionId: %s", sessionId, "key", storedb.DATA_VOUCHER_SYMBOLS, "formattedData", formattedData)
res.Content = string(formattedData) res.Content = string(formattedData)
return res, nil return res, nil
@ -2065,7 +2120,7 @@ func (h *MenuHandlers) ViewVoucher(ctx context.Context, sym string, input []byte
return res, nil return res, nil
} }
metadata, err := store.GetVoucherData(ctx, h.prefixDb, inputStr) metadata, err := store.GetVoucherData(ctx, h.userdataStore, sessionId, inputStr)
if err != nil { if err != nil {
return res, fmt.Errorf("failed to retrieve voucher data: %v", err) return res, fmt.Errorf("failed to retrieve voucher data: %v", err)
} }
@ -2394,6 +2449,110 @@ func (h *MenuHandlers) constructAccountAlias(ctx context.Context) error {
return nil return nil
} }
// RequestCustomAlias requests an ENS based alias name based on a user's input,then saves it as temporary value
func (h *MenuHandlers) RequestCustomAlias(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")
}
if string(input) == "0" {
return res, nil
}
store := h.userdataStore
aliasHint, err := store.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
if err != nil {
if db.IsNotFound(err) {
return res, nil
}
return res, err
}
//Ensures that the call doesn't happen twice for the same alias hint
if !bytes.Equal(aliasHint, input) {
err = store.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(string(input)))
if err != nil {
return res, err
}
pubKey, err := store.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
if err != nil {
if db.IsNotFound(err) {
return res, nil
}
}
sanitizedInput := sanitizeAliasHint(string(input))
aliasResult, err := h.accountService.RequestAlias(ctx, string(pubKey), sanitizedInput)
if err != nil {
logg.ErrorCtxf(ctx, "failed to retrieve alias", "alias", string(aliasHint), "error_alias_request", err)
return res, fmt.Errorf("Failed to retrieve alias: %s", err.Error())
}
alias := aliasResult.Alias
logg.InfoCtxf(ctx, "Suggested alias ", "alias", alias)
//Store the returned alias,wait for user to confirm it as new account alias
err = store.WriteEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS, []byte(alias))
if err != nil {
logg.ErrorCtxf(ctx, "failed to write account alias", "key", storedb.DATA_TEMPORARY_VALUE, "value", alias, "error", err)
return res, err
}
}
return res, nil
}
func sanitizeAliasHint(input string) string {
for i, r := range input {
// Check if the character is a special character (non-alphanumeric)
if !unicode.IsLetter(r) && !unicode.IsNumber(r) {
return input[:i]
}
}
// If no special character is found, return the whole input
return input
}
// GetSuggestedAlias loads and displays the suggested alias name from the temporary value
func (h *MenuHandlers) GetSuggestedAlias(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
store := h.userdataStore
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
suggestedAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS)
if err != nil {
return res, nil
}
res.Content = string(suggestedAlias)
return res, nil
}
// ConfirmNewAlias reads the suggested alias from the [DATA_SUGGECTED_ALIAS] key and confirms it as the new account alias.
func (h *MenuHandlers) ConfirmNewAlias(ctx context.Context, sym string, input []byte) (resource.Result, error) {
var res resource.Result
store := h.userdataStore
flag_alias_set, _ := h.flagManager.GetFlag("flag_alias_set")
sessionId, ok := ctx.Value("SessionId").(string)
if !ok {
return res, fmt.Errorf("missing session")
}
newAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_SUGGESTED_ALIAS)
if err != nil {
return res, nil
}
logg.InfoCtxf(ctx, "Confirming new alias", "alias", string(newAlias))
err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS, []byte(string(newAlias)))
if err != nil {
logg.ErrorCtxf(ctx, "failed to clear DATA_ACCOUNT_ALIAS_VALUE entry with", "key", storedb.DATA_ACCOUNT_ALIAS, "value", "empty", "error", err)
return res, err
}
res.FlagSet = append(res.FlagSet, flag_alias_set)
return res, nil
}
// ClearTemporaryValue empties the DATA_TEMPORARY_VALUE at the main menu to prevent // ClearTemporaryValue empties the DATA_TEMPORARY_VALUE at the main menu to prevent
// previously stored data from being accessed // previously stored data from being accessed
func (h *MenuHandlers) ClearTemporaryValue(ctx context.Context, sym string, input []byte) (resource.Result, error) { func (h *MenuHandlers) ClearTemporaryValue(ctx context.Context, sym string, input []byte) (resource.Result, error) {

View File

@ -1037,6 +1037,7 @@ func TestAuthorize(t *testing.T) {
flag_incorrect_pin, _ := fm.GetFlag("flag_incorrect_pin") flag_incorrect_pin, _ := fm.GetFlag("flag_incorrect_pin")
flag_account_authorized, _ := fm.GetFlag("flag_account_authorized") flag_account_authorized, _ := fm.GetFlag("flag_account_authorized")
flag_allow_update, _ := fm.GetFlag("flag_allow_update") flag_allow_update, _ := fm.GetFlag("flag_allow_update")
flag_invalid_pin, _ := fm.GetFlag("flag_invalid_pin")
// Set 1234 is the correct account pin // Set 1234 is the correct account pin
accountPIN := "1234" accountPIN := "1234"
@ -1070,9 +1071,11 @@ func TestAuthorize(t *testing.T) {
}, },
}, },
{ {
name: "Test with pin that is not a 4 digit", name: "Test with pin that is not a 4 digit",
input: []byte("1235aqds"), input: []byte("1235aqds"),
expectedResult: resource.Result{}, expectedResult: resource.Result{
FlagSet: []uint32{flag_invalid_pin},
},
}, },
} }
@ -1987,36 +1990,46 @@ func TestFetchCommunityBalance(t *testing.T) {
} }
} }
func TestSetDefaultVoucher(t *testing.T) { func TestManageVouchers(t *testing.T) {
sessionId := "session123" sessionId := "session123"
publicKey := "0X13242618721"
ctx, store := InitializeTestStore(t) ctx, store := InitializeTestStore(t)
ctx = context.WithValue(ctx, "SessionId", sessionId) ctx = context.WithValue(ctx, "SessionId", sessionId)
fm, err := NewFlagManager(flagsPath) fm, err := NewFlagManager(flagsPath)
if err != nil { if err != nil {
t.Logf(err.Error()) t.Fatal(err)
} }
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.Fatal(err)
} }
publicKey := "0X13242618721" err = store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(publicKey))
if err != nil {
t.Fatal(err)
}
tests := []struct { tests := []struct {
name string name string
vouchersResp []dataserviceapi.TokenHoldings vouchersResp []dataserviceapi.TokenHoldings
expectedResult resource.Result storedActiveVoucher string
expectedVoucherSymbols []byte
expectedUpdatedAddress []byte
expectedResult resource.Result
}{ }{
{ {
name: "Test no vouchers available", name: "No vouchers available",
vouchersResp: []dataserviceapi.TokenHoldings{}, vouchersResp: []dataserviceapi.TokenHoldings{},
expectedVoucherSymbols: []byte(""),
expectedUpdatedAddress: []byte(""),
expectedResult: resource.Result{ expectedResult: resource.Result{
FlagSet: []uint32{flag_no_active_voucher}, FlagSet: []uint32{flag_no_active_voucher},
}, },
}, },
{ {
name: "Test set default voucher when no active voucher is set", name: "Set default voucher when no active voucher is set",
vouchersResp: []dataserviceapi.TokenHoldings{ vouchersResp: []dataserviceapi.TokenHoldings{
{ {
ContractAddress: "0x123", ContractAddress: "0x123",
@ -2025,7 +2038,24 @@ func TestSetDefaultVoucher(t *testing.T) {
Balance: "100", Balance: "100",
}, },
}, },
expectedResult: resource.Result{}, expectedVoucherSymbols: []byte("1:TOKEN1"),
expectedUpdatedAddress: []byte("0x123"),
expectedResult: resource.Result{
FlagReset: []uint32{flag_no_active_voucher},
},
},
{
name: "Check and update active voucher balance",
vouchersResp: []dataserviceapi.TokenHoldings{
{ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"},
{ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"},
},
storedActiveVoucher: "SRF",
expectedVoucherSymbols: []byte("1:SRF\n2:MILO"),
expectedUpdatedAddress: []byte("0xd4c288865Ce"),
expectedResult: resource.Result{
FlagReset: []uint32{flag_no_active_voucher},
},
}, },
} }
@ -2039,104 +2069,57 @@ func TestSetDefaultVoucher(t *testing.T) {
flagManager: fm, flagManager: fm,
} }
err := store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(publicKey))
if err != nil {
t.Fatal(err)
}
mockAccountService.On("FetchVouchers", string(publicKey)).Return(tt.vouchersResp, nil) mockAccountService.On("FetchVouchers", string(publicKey)).Return(tt.vouchersResp, nil)
res, err := h.SetDefaultVoucher(ctx, "set_default_voucher", []byte("some-input")) // Store active voucher if needed
if tt.storedActiveVoucher != "" {
err := store.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM, []byte(tt.storedActiveVoucher))
if err != nil {
t.Fatal(err)
}
err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS, []byte("0x41c188D45rfg6ds"))
if err != nil {
t.Fatal(err)
}
}
res, err := h.ManageVouchers(ctx, "manage_vouchers", []byte(""))
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, tt.expectedResult, res)
assert.Equal(t, res, tt.expectedResult, "Expected result should be equal to the actual result") if tt.storedActiveVoucher != "" {
// Validate stored voucher symbols
voucherData, err := store.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_SYMBOLS)
assert.NoError(t, err)
assert.Equal(t, tt.expectedVoucherSymbols, voucherData)
mockAccountService.AssertExpectations(t) // Validate stored active contract address
updatedAddress, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS)
assert.NoError(t, err)
assert.Equal(t, tt.expectedUpdatedAddress, updatedAddress)
mockAccountService.AssertExpectations(t)
}
}) })
} }
} }
func TestCheckVouchers(t *testing.T) {
mockAccountService := new(mocks.MockAccountService)
sessionId := "session123"
publicKey := "0X13242618721"
ctx, store := InitializeTestStore(t)
ctx = context.WithValue(ctx, "SessionId", sessionId)
spdb := InitializeTestSubPrefixDb(t, ctx)
h := &MenuHandlers{
userdataStore: store,
accountService: mockAccountService,
prefixDb: spdb,
}
err := store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(publicKey))
if err != nil {
t.Fatal(err)
}
mockVouchersResponse := []dataserviceapi.TokenHoldings{
{ContractAddress: "0xd4c288865Ce", TokenSymbol: "SRF", TokenDecimals: "6", Balance: "100"},
{ContractAddress: "0x41c188d63Qa", TokenSymbol: "MILO", TokenDecimals: "4", Balance: "200"},
}
// store the default voucher data
err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM, []byte("SRF"))
if err != nil {
t.Fatal(err)
}
err = store.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS, []byte("0x41c188D45rfg6ds"))
if err != nil {
t.Fatal(err)
}
expectedSym := []byte("1:SRF\n2:MILO")
expectedUpdatedAddress := []byte("0xd4c288865Ce")
mockAccountService.On("FetchVouchers", string(publicKey)).Return(mockVouchersResponse, nil)
_, err = h.CheckVouchers(ctx, "check_vouchers", []byte(""))
assert.NoError(t, err)
// Read voucher sym data from the store
voucherData, err := spdb.Get(ctx, storedb.ToBytes(storedb.DATA_VOUCHER_SYMBOLS))
if err != nil {
t.Fatal(err)
}
// Read active contract address from the store
updatedAddress, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_ADDRESS)
if err != nil {
t.Fatal(err)
}
// assert that the data is stored correctly
assert.Equal(t, expectedSym, voucherData)
// assert that the address is updated
assert.Equal(t, expectedUpdatedAddress, updatedAddress)
mockAccountService.AssertExpectations(t)
}
func TestGetVoucherList(t *testing.T) { func TestGetVoucherList(t *testing.T) {
sessionId := "session123" sessionId := "session123"
ctx := context.WithValue(context.Background(), "SessionId", sessionId) ctx, store := InitializeTestStore(t)
ctx = context.WithValue(ctx, "SessionId", sessionId)
spdb := InitializeTestSubPrefixDb(t, ctx)
// Initialize MenuHandlers // Initialize MenuHandlers
h := &MenuHandlers{ h := &MenuHandlers{
prefixDb: spdb, userdataStore: store,
ReplaceSeparatorFunc: mockReplaceSeparator, ReplaceSeparatorFunc: mockReplaceSeparator,
} }
mockSyms := []byte("1:SRF\n2:MILO") mockSyms := []byte("1:SRF\n2:MILO")
// Put voucher sym data from the store // Put voucher sym data from the store
err := spdb.Put(ctx, storedb.ToBytes(storedb.DATA_VOUCHER_SYMBOLS), mockSyms) err := store.WriteEntry(ctx, sessionId, storedb.DATA_VOUCHER_SYMBOLS, mockSyms)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -2156,15 +2139,11 @@ func TestViewVoucher(t *testing.T) {
} }
ctx, store := InitializeTestStore(t) ctx, store := InitializeTestStore(t)
sessionId := "session123" sessionId := "session123"
ctx = context.WithValue(ctx, "SessionId", sessionId) ctx = context.WithValue(ctx, "SessionId", sessionId)
spdb := InitializeTestSubPrefixDb(t, ctx)
h := &MenuHandlers{ h := &MenuHandlers{
userdataStore: store, userdataStore: store,
flagManager: fm, flagManager: fm,
prefixDb: spdb,
} }
// Define mock voucher data // Define mock voucher data
@ -2177,7 +2156,7 @@ func TestViewVoucher(t *testing.T) {
// Put the data // Put the data
for key, value := range mockData { for key, value := range mockData {
err = spdb.Put(ctx, []byte(storedb.ToBytes(key)), []byte(value)) err := store.WriteEntry(ctx, sessionId, key, []byte(value))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -3473,15 +3452,6 @@ func TestUpdateAllProfileItems(t *testing.T) {
err = store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(publicKey)) err = store.WriteEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY, []byte(publicKey))
require.NoError(t, err) require.NoError(t, err)
aliasInput := fmt.Sprintf("%s%s", profileItems[0], profileItems[1])
// Mock the account alias response
mockAccountService.On(
"RequestAlias",
publicKey,
aliasInput,
).Return(&models.RequestAliasResult{Alias: "JohnDoe"}, nil)
// Call the function under test // Call the function under test
res, err := h.UpdateAllProfileItems(ctx, "symbol", nil) res, err := h.UpdateAllProfileItems(ctx, "symbol", nil)
assert.NoError(t, err) assert.NoError(t, err)
@ -3493,10 +3463,6 @@ func TestUpdateAllProfileItems(t *testing.T) {
assert.Equal(t, profileItems[i], string(storedValue)) assert.Equal(t, profileItems[i], string(storedValue))
} }
// Validate alias storage
storedAlias, err := store.ReadEntry(ctx, sessionId, storedb.DATA_ACCOUNT_ALIAS)
assert.NoError(t, err)
assert.Equal(t, "JohnDoe", string(storedAlias))
assert.Equal(t, expectedResult, res) assert.Equal(t, expectedResult, res)
} }

View File

@ -49,9 +49,8 @@ func (eu *EventsUpdater) updateToken(ctx context.Context, identity identity.Iden
// set default token to given symbol. // set default token to given symbol.
func (eu *EventsUpdater) updateDefaultToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, activeSym string) error { func (eu *EventsUpdater) updateDefaultToken(ctx context.Context, identity identity.Identity, userStore *store.UserDataStore, activeSym string) error {
pfxDb := toPrefixDb(userStore, identity.SessionId)
// TODO: the activeSym input should instead be newline separated list? // TODO: the activeSym input should instead be newline separated list?
tokenData, err := store.GetVoucherData(ctx, pfxDb, activeSym) tokenData, err := store.GetVoucherData(ctx, userStore, identity.SessionId, activeSym)
if err != nil { if err != nil {
return err return err
} }

View File

@ -103,8 +103,7 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
ls.DbRs.AddLocalFunc("confirm_pin_change", appHandlers.ConfirmPinChange) ls.DbRs.AddLocalFunc("confirm_pin_change", appHandlers.ConfirmPinChange)
ls.DbRs.AddLocalFunc("quit_with_help", appHandlers.QuitWithHelp) ls.DbRs.AddLocalFunc("quit_with_help", appHandlers.QuitWithHelp)
ls.DbRs.AddLocalFunc("fetch_community_balance", appHandlers.FetchCommunityBalance) ls.DbRs.AddLocalFunc("fetch_community_balance", appHandlers.FetchCommunityBalance)
ls.DbRs.AddLocalFunc("set_default_voucher", appHandlers.SetDefaultVoucher) ls.DbRs.AddLocalFunc("manage_vouchers", appHandlers.ManageVouchers)
ls.DbRs.AddLocalFunc("check_vouchers", appHandlers.CheckVouchers)
ls.DbRs.AddLocalFunc("get_vouchers", appHandlers.GetVoucherList) ls.DbRs.AddLocalFunc("get_vouchers", appHandlers.GetVoucherList)
ls.DbRs.AddLocalFunc("view_voucher", appHandlers.ViewVoucher) ls.DbRs.AddLocalFunc("view_voucher", appHandlers.ViewVoucher)
ls.DbRs.AddLocalFunc("set_voucher", appHandlers.SetVoucher) ls.DbRs.AddLocalFunc("set_voucher", appHandlers.SetVoucher)
@ -124,6 +123,12 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
ls.DbRs.AddLocalFunc("set_back", appHandlers.SetBack) ls.DbRs.AddLocalFunc("set_back", appHandlers.SetBack)
ls.DbRs.AddLocalFunc("show_blocked_account", appHandlers.ShowBlockedAccount) ls.DbRs.AddLocalFunc("show_blocked_account", appHandlers.ShowBlockedAccount)
ls.DbRs.AddLocalFunc("clear_temporary_value", appHandlers.ClearTemporaryValue) ls.DbRs.AddLocalFunc("clear_temporary_value", appHandlers.ClearTemporaryValue)
ls.DbRs.AddLocalFunc("reset_invalid_pin", appHandlers.ResetInvalidPIN)
ls.DbRs.AddLocalFunc("request_custom_alias", appHandlers.RequestCustomAlias)
ls.DbRs.AddLocalFunc("get_suggested_alias", appHandlers.GetSuggestedAlias)
ls.DbRs.AddLocalFunc("confirm_new_alias", appHandlers.ConfirmNewAlias)
ls.DbRs.AddLocalFunc("check_account_created", appHandlers.CheckAccountCreated)
ls.first = appHandlers.Init ls.first = appHandlers.Init
return appHandlers, nil return appHandlers, nil

View File

@ -71,7 +71,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "5", "input": "5",
@ -108,11 +108,11 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "", "input": "",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "2", "input": "2",
@ -149,7 +149,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "5", "input": "5",
@ -173,7 +173,7 @@
}, },
{ {
"input": "0", "input": "0",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "0", "input": "0",
@ -190,7 +190,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "5", "input": "5",
@ -239,7 +239,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "5", "input": "5",
@ -264,7 +264,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "3", "input": "3",
@ -284,7 +284,7 @@
}, },
{ {
"input": "1234", "input": "1234",
"expectedContent": "Balance: {balance}\n\n0:Back\n9:Quit" "expectedContent": "{balance}\n\n0:Back\n9:Quit"
}, },
{ {
"input": "0", "input": "0",
@ -292,7 +292,7 @@
}, },
{ {
"input": "0", "input": "0",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "0", "input": "0",
@ -309,7 +309,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "3", "input": "3",
@ -337,7 +337,7 @@
}, },
{ {
"input": "0", "input": "0",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "0", "input": "0",
@ -354,7 +354,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -411,7 +411,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -448,7 +448,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -489,7 +489,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -526,7 +526,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -563,7 +563,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -600,7 +600,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",
@ -633,7 +633,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -9,7 +9,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "1", "input": "1",

View File

@ -116,7 +116,7 @@
}, },
{ {
"input": "3", "input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back" "expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n7:My Alias\n0:Back"
}, },
{ {
"input": "6", "input": "6",

View File

@ -1,5 +1,5 @@
LOAD reset_transaction_amount 0 LOAD reset_transaction_amount 0
LOAD max_amount 10 LOAD max_amount 40
RELOAD max_amount RELOAD max_amount
MAP max_amount MAP max_amount
MOUT back 0 MOUT back 0

View File

@ -0,0 +1,2 @@
Your full alias will be: {{.get_suggested_alias}}
Please enter your PIN to confirm:

View File

@ -0,0 +1,12 @@
LOAD reset_invalid_pin 6
RELOAD reset_invalid_pin
LOAD get_suggested_alias 0
RELOAD get_suggested_alias
MAP get_suggested_alias
MOUT back 0
HALT
INCMP _ 0
RELOAD authorize_account
CATCH incorrect_pin flag_incorrect_pin 1
CATCH invalid_pin flag_invalid_pin 1
CATCH update_alias flag_allow_update 1

View File

@ -0,0 +1,2 @@
Lakabu yako kamili itakuwa: {{.get_suggested_alias}}
Tafadhali weka PIN yako ili kuthibitisha:

View File

@ -1 +1 @@
The PIN you entered is invalid.The PIN must be different from your current PIN.For help call +254757628885 The PIN you entered is invalid.The PIN must be a 4 digit number.

View File

@ -1,3 +1,8 @@
MOUT back 0 LOAD reset_invalid_pin 6
RELOAD reset_invalid_pin
MOUT retry 1
MOUT quit 9
HALT HALT
INCMP _ 0 INCMP _ 1
INCMP quit 9
INCMP . *

View File

@ -1 +1 @@
PIN mpya na udhibitisho wa PIN mpya hazilingani.Tafadhali jaribu tena.Kwa usaidizi piga simu +254757628885. PIN uliyoweka si sahihi. PIN lazima iwe nambari 4.

View File

@ -30,3 +30,7 @@ msgstr "Salio la Kikundi: 0.00"
msgid "Symbol: %s\nBalance: %s" msgid "Symbol: %s\nBalance: %s"
msgstr "Sarafu: %s\nSalio: %s" msgstr "Sarafu: %s\nSalio: %s"
msgid "%s balance: %s\n"
msgstr "%s salio: %s\n"

View File

@ -1,9 +1,7 @@
LOAD clear_temporary_value 2 LOAD clear_temporary_value 2
RELOAD clear_temporary_value RELOAD clear_temporary_value
LOAD set_default_voucher 8 LOAD manage_vouchers 160
RELOAD set_default_voucher RELOAD manage_vouchers
LOAD check_vouchers 10
RELOAD check_vouchers
LOAD check_balance 128 LOAD check_balance 128
RELOAD check_balance RELOAD check_balance
CATCH api_failure flag_api_call_error 1 CATCH api_failure flag_api_call_error 1

View File

@ -1,3 +1,4 @@
LOAD authorize_account 16
LOAD reset_allow_update 0 LOAD reset_allow_update 0
MOUT profile 1 MOUT profile 1
MOUT change_language 2 MOUT change_language 2
@ -5,6 +6,7 @@ MOUT check_balance 3
MOUT check_statement 4 MOUT check_statement 4
MOUT pin_options 5 MOUT pin_options 5
MOUT my_address 6 MOUT my_address 6
MOUT my_account_alias 7
MOUT back 0 MOUT back 0
HALT HALT
INCMP main 0 INCMP main 0
@ -14,4 +16,5 @@ INCMP balances 3
INCMP check_statement 4 INCMP check_statement 4
INCMP pin_management 5 INCMP pin_management 5
INCMP address 6 INCMP address 6
INCMP my_account_alias 7
INCMP . * INCMP . *

View File

@ -0,0 +1,2 @@
Current alias: {{.get_current_profile_info}}
Enter your preferred alias:

View File

@ -0,0 +1,8 @@
LOAD get_current_profile_info 0
MAP get_current_profile_info
MOUT back 0
HALT
INCMP _ 0
LOAD request_custom_alias 0
RELOAD request_custom_alias
INCMP confirm_new_alias *

View File

@ -0,0 +1 @@
My Alias

View File

@ -0,0 +1 @@
Lakabu yangu

View File

@ -0,0 +1,2 @@
Lakabu ya sasa: {{.get_current_profile_info}}
Weka lakabu unalopendelea:

View File

@ -1,8 +1,8 @@
RELOAD reset_allow_update RELOAD reset_incorrect
MOUT back 0 MOUT back 0
HALT HALT
INCMP _ 0 INCMP _ 0
RELOAD authorize_account RELOAD authorize_account
CATCH incorrect_pin flag_incorrect_pin 1 CATCH incorrect_pin flag_incorrect_pin 1
CATCH _ flag_allow_update 0 CATCH invalid_pin flag_invalid_pin 1
INCMP new_pin * INCMP new_pin *

View File

@ -1,9 +1,10 @@
LOAD set_back 6 LOAD set_back 6
LOAD authorize_account 5 LOAD authorize_account 16
LOAD reset_allow_update 4 LOAD reset_allow_update 4
LOAD verify_new_pin 2 LOAD verify_new_pin 2
LOAD save_temporary_pin 1 LOAD save_temporary_pin 1
LOAD reset_incorrect 0 LOAD reset_incorrect 0
LOAD reset_invalid_pin 6
MOUT change_pin 1 MOUT change_pin 1
MOUT reset_pin 2 MOUT reset_pin 2
MOUT back 0 MOUT back 0

View File

@ -29,4 +29,5 @@ flag,flag_location_set,35,this is set when the location of the profile is set
flag,flag_offerings_set,36,this is set when the offerings of the profile is set flag,flag_offerings_set,36,this is set when the offerings of the profile is set
flag,flag_back_set,37,this is set when it is a back navigation flag,flag_back_set,37,this is set when it is a back navigation
flag,flag_account_blocked,38,this is set when an account has been blocked after the allowed incorrect PIN attempts have been exceeded flag,flag_account_blocked,38,this is set when an account has been blocked after the allowed incorrect PIN attempts have been exceeded
flag,flag_invalid_pin,39,this is set when the given PIN is invalid(is less than or more than 4 digits)
flag,flag_alias_set,40,this is set when an account alias has been assigned to a user

1 flag flag_language_set 8 checks whether the user has set their prefered language
29 flag flag_offerings_set 36 this is set when the offerings of the profile is set
30 flag flag_back_set 37 this is set when it is a back navigation
31 flag flag_account_blocked 38 this is set when an account has been blocked after the allowed incorrect PIN attempts have been exceeded
32 flag flag_invalid_pin 39 this is set when the given PIN is invalid(is less than or more than 4 digits)
33 flag flag_alias_set 40 this is set when an account alias has been assigned to a user

View File

@ -1,5 +1,7 @@
LOAD check_blocked_status 1 LOAD check_blocked_status 1
RELOAD check_blocked_status RELOAD check_blocked_status
LOAD check_account_created 2
RELOAD check_account_created
CATCH blocked_account flag_account_blocked 1 CATCH blocked_account flag_account_blocked 1
CATCH select_language flag_language_set 0 CATCH select_language flag_language_set 0
CATCH terms flag_account_created 0 CATCH terms flag_account_created 0

View File

@ -0,0 +1 @@
Your alias has been updated successfully

View File

@ -0,0 +1,7 @@
LOAD confirm_new_alias 0
RELOAD confirm_new_alias
MOUT back 0
MOUT quit 9
HALT
INCMP ^ 0
INCMP quit 9

View File

@ -0,0 +1 @@
Ombi lako la kubadilisha lakabu limefanikiwa.

View File

@ -14,6 +14,6 @@ import (
func New(ctx context.Context, storageService storage.StorageService) remote.AccountService { func New(ctx context.Context, storageService storage.StorageService) remote.AccountService {
return &httpremote.HTTPAccountService{ return &httpremote.HTTPAccountService{
SS: storageService, SS: storageService,
UseApi: false, UseApi: true,
} }
} }

View File

@ -63,6 +63,8 @@ const (
DATA_INITIAL_LANGUAGE_CODE DATA_INITIAL_LANGUAGE_CODE
//Fully qualified account alias string //Fully qualified account alias string
DATA_ACCOUNT_ALIAS DATA_ACCOUNT_ALIAS
//currently suggested alias by the api awaiting user's confirmation as accepted account alias
DATA_SUGGESTED_ALIAS
) )
const ( const (
@ -130,7 +132,8 @@ func StringToDataTyp(str string) (DataTyp, error) {
return DATA_GENDER, nil return DATA_GENDER, nil
case "DATA_OFFERINGS": case "DATA_OFFERINGS":
return DATA_OFFERINGS, nil return DATA_OFFERINGS, nil
case "DATA_ACCOUNT_ALIAS":
return DATA_ACCOUNT_ALIAS, nil
default: default:
return 0, errors.New("invalid DataTyp string") return 0, errors.New("invalid DataTyp string")
} }

View File

@ -33,11 +33,14 @@ func (s *SubPrefixDb) toKey(k []byte) []byte {
func (s *SubPrefixDb) Get(ctx context.Context, key []byte) ([]byte, error) { func (s *SubPrefixDb) Get(ctx context.Context, key []byte) ([]byte, error) {
s.store.SetPrefix(db.DATATYPE_USERDATA) s.store.SetPrefix(db.DATATYPE_USERDATA)
key = s.toKey(key) key = s.toKey(key)
logg.InfoCtxf(ctx, "SubPrefixDb Get log", "key", string(key))
return s.store.Get(ctx, key) return s.store.Get(ctx, key)
} }
func (s *SubPrefixDb) Put(ctx context.Context, key []byte, val []byte) error { func (s *SubPrefixDb) Put(ctx context.Context, key []byte, val []byte) error {
s.store.SetPrefix(db.DATATYPE_USERDATA) s.store.SetPrefix(db.DATATYPE_USERDATA)
key = s.toKey(key) key = s.toKey(key)
logg.InfoCtxf(ctx, "SubPrefixDb Put log", "key", string(key))
return s.store.Put(ctx, key, val) return s.store.Put(ctx, key, val)
} }

View File

@ -68,7 +68,7 @@ func ScaleDownBalance(balance, decimals string) string {
} }
// GetVoucherData retrieves and matches voucher data // GetVoucherData retrieves and matches voucher data
func GetVoucherData(ctx context.Context, db storedb.PrefixDb, input string) (*dataserviceapi.TokenHoldings, error) { func GetVoucherData(ctx context.Context, store DataStore, sessionId string, input string) (*dataserviceapi.TokenHoldings, error) {
keys := []storedb.DataTyp{ keys := []storedb.DataTyp{
storedb.DATA_VOUCHER_SYMBOLS, storedb.DATA_VOUCHER_SYMBOLS,
storedb.DATA_VOUCHER_BALANCES, storedb.DATA_VOUCHER_BALANCES,
@ -78,9 +78,9 @@ func GetVoucherData(ctx context.Context, db storedb.PrefixDb, input string) (*da
data := make(map[storedb.DataTyp]string) data := make(map[storedb.DataTyp]string)
for _, key := range keys { for _, key := range keys {
value, err := db.Get(ctx, storedb.ToBytes(key)) value, err := store.ReadEntry(ctx, sessionId, key)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to get prefix key %x: %v", storedb.ToBytes(key), err) return nil, fmt.Errorf("failed to get data key %x: %v", key, err)
} }
data[key] = string(value) data[key] = string(value)
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/alecthomas/assert/v2" "github.com/alecthomas/assert/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
visedb "git.defalsify.org/vise.git/db"
memdb "git.defalsify.org/vise.git/db/mem" memdb "git.defalsify.org/vise.git/db/mem"
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db" storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api" dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
@ -77,16 +76,8 @@ func TestProcessVouchers(t *testing.T) {
} }
func TestGetVoucherData(t *testing.T) { func TestGetVoucherData(t *testing.T) {
ctx := context.Background() ctx, store := InitializeTestDb(t)
sessionId := "session123"
db := memdb.NewMemDb()
err := db.Connect(ctx, "")
if err != nil {
t.Fatal(err)
}
prefix := storedb.ToBytes(visedb.DATATYPE_USERDATA)
spdb := storedb.NewSubPrefixDb(db, prefix)
// Test voucher data // Test voucher data
mockData := map[storedb.DataTyp][]byte{ mockData := map[storedb.DataTyp][]byte{
@ -98,13 +89,13 @@ func TestGetVoucherData(t *testing.T) {
// Put the data // Put the data
for key, value := range mockData { for key, value := range mockData {
err = spdb.Put(ctx, []byte(storedb.ToBytes(key)), []byte(value)) err := store.WriteEntry(ctx, sessionId, key, []byte(value))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} }
result, err := GetVoucherData(ctx, spdb, "1") result, err := GetVoucherData(ctx, store, sessionId, "1")
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "SRF", result.TokenSymbol) assert.Equal(t, "SRF", result.TokenSymbol)