Compare commits
No commits in common. "master" and "handle-error-codes" have entirely different histories.
master
...
handle-err
14
.env.example
14
.env.example
@ -29,17 +29,3 @@ DEFAULT_POOL_CONTRACT_ADDRESS=0x48a953cA5cf5298bc6f6Af3C608351f537AAcb9e
|
|||||||
DEFAULT_LIMITER_ADDRESS=
|
DEFAULT_LIMITER_ADDRESS=
|
||||||
DEFAULT_VOUCHER_REGISTRY=
|
DEFAULT_VOUCHER_REGISTRY=
|
||||||
INCLUDE_STABLES_PARAM=false
|
INCLUDE_STABLES_PARAM=false
|
||||||
|
|
||||||
#Mpesa
|
|
||||||
DEFAULT_MPESA_ADDRESS=0x48a953cA5cf5298bc6f6Af3C608351f537AAcb9e
|
|
||||||
MIN_MPESA_SEND_AMOUNT=100
|
|
||||||
MAX_MPESA_SEND_AMOUNT=250000
|
|
||||||
MIN_MPESA_WITHDRAW_AMOUNT=20
|
|
||||||
DEFAULT_MPESA_ASSET=cUSD
|
|
||||||
MPESA_BEARER_TOKEN=eyJeSIsInRcCI6IkpXVCJ.yJwdWJsaWNLZXkiOiIwrrrrrr
|
|
||||||
MPESA_ONRAMP_BASE=https://pretium.v1.grassecon.net
|
|
||||||
|
|
||||||
# Known stable voucher addresses (USDm, USD₮)
|
|
||||||
STABLE_VOUCHER_ADDRESSES=0x765DE816845861e75A25fCA122bb6898B8B1282a,0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e
|
|
||||||
DEFAULT_STABLE_VOUCHER_ADDRESS=0x765DE816845861e75A25fCA122bb6898B8B1282a
|
|
||||||
DEFAULT_STABLE_VOUCHER_DECIMALS=18
|
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,4 +8,3 @@ id_*
|
|||||||
*.gdbm
|
*.gdbm
|
||||||
*.log
|
*.log
|
||||||
user-data
|
user-data
|
||||||
**/*/vise-asm
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.24-bookworm AS build
|
FROM golang:1.23.4-bookworm AS build
|
||||||
|
|
||||||
ENV CGO_ENABLED=1
|
ENV CGO_ENABLED=1
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||||||
libgdbm-dev \
|
libgdbm-dev \
|
||||||
git \
|
git \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
RUN git clone https://github.com/nolash/go-vise go-vise
|
RUN git clone https://git.defalsify.org/vise.git go-vise
|
||||||
COPY . ./sarafu-vise
|
COPY . ./sarafu-vise
|
||||||
|
|
||||||
WORKDIR /build/sarafu-vise/services/registration
|
WORKDIR /build/sarafu-vise/services/registration
|
||||||
|
|||||||
@ -79,12 +79,11 @@ func main() {
|
|||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
|
|
||||||
cfg := engine.Config{
|
cfg := engine.Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
ResetOnEmptyInput: true,
|
ResetOnEmptyInput: true,
|
||||||
ResetRoot: true, // clear the cache once a user quits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if engineDebug {
|
if engineDebug {
|
||||||
|
|||||||
@ -94,12 +94,11 @@ func main() {
|
|||||||
pfp := path.Join(scriptDir, "pp.csv")
|
pfp := path.Join(scriptDir, "pp.csv")
|
||||||
|
|
||||||
cfg := engine.Config{
|
cfg := engine.Config{
|
||||||
Root: "root",
|
Root: "root",
|
||||||
OutputSize: uint32(size),
|
OutputSize: uint32(size),
|
||||||
FlagCount: uint32(128),
|
FlagCount: uint32(128),
|
||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
ResetOnEmptyInput: true,
|
ResetOnEmptyInput: true,
|
||||||
ResetRoot: true, // clear the cache once a user quits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if engineDebug {
|
if engineDebug {
|
||||||
|
|||||||
@ -82,7 +82,6 @@ func main() {
|
|||||||
MenuSeparator: menuSeparator,
|
MenuSeparator: menuSeparator,
|
||||||
EngineDebug: engineDebug,
|
EngineDebug: engineDebug,
|
||||||
ResetOnEmptyInput: true,
|
ResetOnEmptyInput: true,
|
||||||
ResetRoot: true, // clear the cache once a user quits
|
|
||||||
}
|
}
|
||||||
|
|
||||||
menuStorageService := storage.NewMenuStorageService(conns)
|
menuStorageService := storage.NewMenuStorageService(conns)
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
apiconfig "git.grassecon.net/grassrootseconomics/sarafu-api/config"
|
apiconfig "git.grassecon.net/grassrootseconomics/sarafu-api/config"
|
||||||
@ -88,65 +87,3 @@ func DefaultPoolName() string {
|
|||||||
func DefaultPoolSymbol() string {
|
func DefaultPoolSymbol() string {
|
||||||
return env.GetEnv("DEFAULT_POOL_SYMBOL", "")
|
return env.GetEnv("DEFAULT_POOL_SYMBOL", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultMpesaAddress() string {
|
|
||||||
return env.GetEnv("DEFAULT_MPESA_ADDRESS", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func MinMpesaSendAmount() float64 {
|
|
||||||
v := env.GetEnv("MIN_MPESA_SEND_AMOUNT", "100")
|
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 100 // fallback
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func MinMpesaWithdrawAmount() float64 {
|
|
||||||
v := env.GetEnv("MIN_MPESA_WITHDRAW_AMOUNT", "20")
|
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 20 // fallback
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func MaxMpesaSendAmount() float64 {
|
|
||||||
v := env.GetEnv("MAX_MPESA_SEND_AMOUNT", "250000")
|
|
||||||
f, err := strconv.ParseFloat(v, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 250000 // fallback
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultMpesaAsset() string {
|
|
||||||
return env.GetEnv("DEFAULT_MPESA_ASSET", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func StableVoucherAddresses() []string {
|
|
||||||
var parsed []string
|
|
||||||
|
|
||||||
raw := env.GetEnv("STABLE_VOUCHER_ADDRESSES", "")
|
|
||||||
if raw == "" {
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
|
|
||||||
list := strings.Split(raw, ",")
|
|
||||||
for _, addr := range list {
|
|
||||||
clean := strings.TrimSpace(addr)
|
|
||||||
if clean != "" {
|
|
||||||
parsed = append(parsed, clean)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsed
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultStableVoucherAddress() string {
|
|
||||||
return env.GetEnv("DEFAULT_STABLE_VOUCHER_ADDRESS", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func DefaultStableVoucherDecimals() string {
|
|
||||||
return env.GetEnv("DEFAULT_STABLE_VOUCHER_DECIMALS", "")
|
|
||||||
}
|
|
||||||
|
|||||||
74
go.mod
74
go.mod
@ -1,66 +1,68 @@
|
|||||||
module git.grassecon.net/grassrootseconomics/sarafu-vise
|
module git.grassecon.net/grassrootseconomics/sarafu-vise
|
||||||
|
|
||||||
go 1.24.0
|
go 1.23.4
|
||||||
|
|
||||||
toolchain go1.24.10
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66
|
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66
|
||||||
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20251127132814-8ceadabbc215
|
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20250417111317-2953f4c2f32e
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20260207150752-71aa5ce7b537
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306
|
||||||
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
|
||||||
github.com/grassrootseconomics/ethutils v1.6.0
|
github.com/grassrootseconomics/ethutils v1.3.1
|
||||||
github.com/grassrootseconomics/ussd-data-service v1.10.1-beta
|
github.com/grassrootseconomics/ussd-data-service v1.6.0-beta
|
||||||
github.com/jackc/pgx/v5 v5.7.6
|
github.com/jackc/pgx/v5 v5.7.1
|
||||||
github.com/peteole/testdata-loader v0.3.0
|
github.com/peteole/testdata-loader v0.3.0
|
||||||
github.com/stretchr/testify v1.11.1
|
github.com/stretchr/testify v1.9.0
|
||||||
golang.org/x/crypto v0.45.0
|
golang.org/x/crypto v0.32.0
|
||||||
gopkg.in/leonelquinteros/gotext.v1 v1.3.1
|
gopkg.in/leonelquinteros/gotext.v1 v1.3.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251119083800-2aa1d4cc79d7 // indirect
|
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||||
github.com/alecthomas/participle/v2 v2.0.0 // indirect
|
github.com/alecthomas/participle/v2 v2.0.0 // indirect
|
||||||
github.com/alecthomas/repr v0.2.0 // indirect
|
github.com/alecthomas/repr v0.2.0 // indirect
|
||||||
github.com/barbashov/iso639-3 v1.0.0 // indirect
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c // indirect
|
||||||
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
github.com/bits-and-blooms/bitset v1.14.3 // indirect
|
||||||
github.com/consensys/gnark-crypto v0.19.2 // indirect
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect
|
github.com/consensys/bavard v0.1.13 // indirect
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect
|
github.com/consensys/gnark-crypto v0.12.1 // indirect
|
||||||
|
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect
|
||||||
|
github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/deckarep/golang-set/v2 v2.8.0 // indirect
|
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
|
||||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect
|
github.com/ethereum/c-kzg-4844 v1.0.0 // indirect
|
||||||
github.com/ethereum/go-ethereum v1.16.7 // indirect
|
github.com/ethereum/go-ethereum v1.14.9 // indirect
|
||||||
github.com/ethereum/go-verkle v0.2.2 // indirect
|
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.4.0 // indirect
|
||||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.3 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
github.com/grassrootseconomics/eth-custodial v1.12.0-rc // indirect
|
github.com/grassrootseconomics/eth-custodial v1.3.0-beta // indirect
|
||||||
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
|
github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 // indirect
|
||||||
github.com/hexops/gotextdiff v1.0.3 // indirect
|
github.com/hexops/gotextdiff v1.0.3 // indirect
|
||||||
github.com/holiman/uint256 v1.3.2 // indirect
|
github.com/holiman/uint256 v1.3.1 // indirect
|
||||||
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
|
||||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||||
github.com/joho/godotenv v1.5.1 // indirect
|
github.com/joho/godotenv v1.5.1 // indirect
|
||||||
github.com/lmittmann/w3 v0.20.5 // indirect
|
github.com/lmittmann/w3 v0.17.1 // indirect
|
||||||
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a // indirect
|
||||||
|
github.com/mmcloughlin/addchain v0.4.0 // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible // indirect
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
|
||||||
github.com/stretchr/objx v0.5.3 // indirect
|
github.com/stretchr/objx v0.5.2 // indirect
|
||||||
github.com/supranational/blst v0.3.16 // indirect
|
github.com/supranational/blst v0.3.11 // indirect
|
||||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||||
golang.org/x/sync v0.18.0 // indirect
|
golang.org/x/sync v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.38.0 // indirect
|
golang.org/x/sys v0.29.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
golang.org/x/text v0.21.0 // indirect
|
||||||
golang.org/x/time v0.14.0 // indirect
|
golang.org/x/time v0.7.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
rsc.io/tmplfunc v0.0.3 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
262
go.sum
262
go.sum
@ -1,169 +1,227 @@
|
|||||||
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66 h1:hmtb2Q3lHxq+SXqG+Gn43pKhTRYx+sw5j1LpgBfXN1o=
|
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66 h1:hmtb2Q3lHxq+SXqG+Gn43pKhTRYx+sw5j1LpgBfXN1o=
|
||||||
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
git.defalsify.org/vise.git v0.3.2-0.20250528124150-03bf7bfc1b66/go.mod h1:jyBMe1qTYUz3mmuoC9JQ/TvFeW0vTanCUcPu3H8p4Ck=
|
||||||
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20251127132814-8ceadabbc215 h1:cxWmd3WG3iVEqP6qG8ZeQRa7Ujno3rSKz3YXjZnmTEY=
|
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20250417111317-2953f4c2f32e h1:DcC9qkNl9ny3hxQmsMK6W81+5R/j4ZwYUbvewMI/rlc=
|
||||||
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20251127132814-8ceadabbc215/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60=
|
git.grassecon.net/grassrootseconomics/common v0.9.0-beta.1.0.20250417111317-2953f4c2f32e/go.mod h1:wgQJZGIS6QuNLHqDhcsvehsbn5PvgV7aziRebMnJi60=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251128071248-bfdeef125576 h1:Ov4zENfEnzuU4ZpsNGbFjog9NUM0h1A7RYwWkmHRJWo=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623063234-c1797e7a32b5 h1:VnRe01kHkZUBK/QjE7iV6gElSqSwQnAkWV3yCHtuYrI=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251128071248-bfdeef125576/go.mod h1:h/y/lJNJAVTcIzAxCMXXw8Dh2aoLxBFZ6F1nTB8C0nU=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623063234-c1797e7a32b5/go.mod h1:H97hR+VOnZvR5BiGVb0ScCPwH/IoKBOlKM+yrQNVpq0=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251202085112-45469d4ba326 h1:qH4QulgncvAD7b/YeHGPxcDJTBIychPeoZJACefYryI=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623070026-d945964b0b46 h1:0+XkSRe7XSHa9WHXKpGPuC0myDszjchr4syH006lQ28=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251202085112-45469d4ba326/go.mod h1:h/y/lJNJAVTcIzAxCMXXw8Dh2aoLxBFZ6F1nTB8C0nU=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623070026-d945964b0b46/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20260207150752-71aa5ce7b537 h1:2AoOHiRTN3SXX4qnc2wOaF2ktVXLlFAa3X/n9DLu8/s=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623075057-7b42d509e6d4 h1:W+8CC7x5eCPylkGy2TEoOpfJuiIlqzEzyYTzCLlY/u8=
|
||||||
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20260207150752-71aa5ce7b537/go.mod h1:h/y/lJNJAVTcIzAxCMXXw8Dh2aoLxBFZ6F1nTB8C0nU=
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250623075057-7b42d509e6d4/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624074830-5aa032400c12 h1:vD8biQmN36eouuE+TdxgXQjKisRf5cTGu/tMPv3afs0=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624074830-5aa032400c12/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624090744-339ba854c997 h1:8bCKyYoV4YiVBvCZlRclc3aQlBYpWhgtM35mvniDFD8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250624090744-339ba854c997/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250626065419-57ee409f9629 h1:ew3vCFrLS/7/8uULTTPCbsHzFntQ6X68SScnBEy3pl0=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250626065419-57ee409f9629/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213135-50ee455e7069 h1:re+hdr5NAC6JqhyvjMCkgX17fFi0u3Mawc6RBnBJW8I=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213135-50ee455e7069/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-12940bb5f284 h1:2zMU9jPd6xEO6oY9oxr84sdT9G3d09eyAkjVBAz9eco=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630213606-12940bb5f284/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a h1:KuhJ/WY4RCGmrXUA680ciaponM4vM5zBOJfnCpUo2fc=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20250630214912-814bef2b209a/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251021120522-6f7802b58cf5 h1:bQglHVxMilciZ9M2PGuLgA+Wkvqo8OqQh6TFYwjtuSE=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251021120522-6f7802b58cf5/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63 h1:yznaUXeAy+qiZb2nCxosYXE5HyCPpynIoplEuYV/zQM=
|
||||||
|
git.grassecon.net/grassrootseconomics/sarafu-api v0.9.0-beta.1.0.20251022084613-532547899f63/go.mod h1:y/vsN8UO0wSxZk3gv0y5df4RPKMJI6TIxjVcVCPF8T8=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306 h1:Jo+yWysWw/N5BJQtAyEMN8ePVvAyPHv+JG4lQti+1N4=
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306 h1:Jo+yWysWw/N5BJQtAyEMN8ePVvAyPHv+JG4lQti+1N4=
|
||||||
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306/go.mod h1:FdLwYtzsjOIcDiW4uDgDYnB4Wdzq12uJUe0QHSSPbSo=
|
git.grassecon.net/grassrootseconomics/visedriver v0.9.0-beta.2.0.20250408094335-e2d1f65bb306/go.mod h1:FdLwYtzsjOIcDiW4uDgDYnB4Wdzq12uJUe0QHSSPbSo=
|
||||||
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/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ=
|
||||||
|
github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251119083800-2aa1d4cc79d7 h1:uups37roJCTtR/BrJa0WoMrxt3rzgV+Qrj+TxYyJoAo=
|
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251119083800-2aa1d4cc79d7/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
|
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||||
github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0=
|
github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI=
|
||||||
github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=
|
github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI=
|
||||||
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
|
github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk=
|
||||||
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
|
||||||
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
github.com/alecthomas/participle/v2 v2.0.0 h1:Fgrq+MbuSsJwIkw3fEj9h75vDP0Er5JzepJ0/HNHv0g=
|
||||||
github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
|
github.com/alecthomas/participle/v2 v2.0.0/go.mod h1:rAKZdJldHu8084ojcWevWAL8KmEU+AT+Olodb+WoN2Y=
|
||||||
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
|
||||||
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
github.com/barbashov/iso639-3 v1.0.0 h1:qCp1hUzZT8C8yHcdDo4sZQg2jHEaX6LF5H/dF9ba0qs=
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c h1:H9Nm+I7Cg/YVPpEV1RzU3Wq2pjamPc/UtHDgItcb7lE=
|
||||||
github.com/barbashov/iso639-3 v1.0.0/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
|
github.com/barbashov/iso639-3 v0.0.0-20211020172741-1f4ffb2d8d1c/go.mod h1:rGod7o6KPeJ+hyBpHfhi4v7blx9sf+QsHsA7KAsdN6U=
|
||||||
github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/bits-and-blooms/bitset v1.14.3 h1:Gd2c8lSNf9pKXom5JtD7AaKO8o7fGQ2LtFj1436qilA=
|
||||||
|
github.com/bits-and-blooms/bitset v1.14.3/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
|
||||||
|
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80=
|
github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I=
|
||||||
github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0=
|
github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8=
|
||||||
github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg=
|
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4=
|
||||||
github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI=
|
github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M=
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg=
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE=
|
||||||
github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM=
|
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs=
|
||||||
|
github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA=
|
||||||
|
github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU=
|
||||||
|
github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30=
|
||||||
|
github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg=
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
|
||||||
|
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
|
||||||
|
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
|
||||||
|
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
|
||||||
|
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
|
||||||
|
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
|
||||||
|
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I=
|
||||||
|
github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs=
|
||||||
|
github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI=
|
||||||
|
github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ=
|
github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM=
|
||||||
github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0=
|
||||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc=
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs=
|
||||||
github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A=
|
github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA=
|
||||||
github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
|
github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0=
|
||||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=
|
github.com/ethereum/go-ethereum v1.14.9 h1:J7iwXDrtUyE9FUjUYbd4c9tyzwMh6dTJsKzo9i6SrwA=
|
||||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs=
|
github.com/ethereum/go-ethereum v1.14.9/go.mod h1:QeW+MtTpRdBEm2pUFoonByee8zfHv7kGp0wK0odvU1I=
|
||||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=
|
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A=
|
||||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=
|
github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
|
||||||
github.com/ethereum/go-ethereum v1.16.7 h1:qeM4TvbrWK0UC0tgkZ7NiRsmBGwsjqc64BHo20U59UQ=
|
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88=
|
||||||
github.com/ethereum/go-ethereum v1.16.7/go.mod h1:Fs6QebQbavneQTYcA39PEKv2+zIjX7rPUZ14DER46wk=
|
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
|
||||||
github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8=
|
github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps=
|
||||||
github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk=
|
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
|
||||||
github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY=
|
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||||
github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
|
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
|
||||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
|
||||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||||
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
|
||||||
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/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||||
|
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk=
|
||||||
|
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/grassrootseconomics/eth-custodial v1.12.0-rc h1:INkXMfNUISkQ1bgnw3LwfFJn/eCdBawFU8Hx+S7mM/c=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/grassrootseconomics/eth-custodial v1.12.0-rc/go.mod h1:s/vacSWFiVO7FDv76EID8sQvdT1vq+3GcWZUgU6N618=
|
github.com/grassrootseconomics/eth-custodial v1.3.0-beta h1:twrMBhl89GqDUL9PlkzQxMP/6OST1BByrNDj+rqXDmU=
|
||||||
github.com/grassrootseconomics/ethutils v1.6.0 h1:Zx7Nqi9ACxkpsHLmWWj8AHGCGeBmjP8Qf79+YMTGLTY=
|
github.com/grassrootseconomics/eth-custodial v1.3.0-beta/go.mod h1:7uhRcdnJplX4t6GKCEFkbeDhhjlcaGJeJqevbcvGLZo=
|
||||||
github.com/grassrootseconomics/ethutils v1.6.0/go.mod h1:7RCNwDj1wfgWt8CV4p7cQuZWPPI5fjwl/piq7NthaWg=
|
github.com/grassrootseconomics/ethutils v1.3.1 h1:LlQO90HjJkl7ejC8fv6jP7RJUrAm1j4VMMCYfsoIrhU=
|
||||||
github.com/grassrootseconomics/ussd-data-service v1.10.1-beta h1:ZrRn7gv4MVSg67hmSdiii/Y86PUIvhxtqc2luAjlA7o=
|
github.com/grassrootseconomics/ethutils v1.3.1/go.mod h1:Wuv1VEZrkLIXqTSEYI3Nh9HG/ZHOUQ+U+xvWJ8QtjgQ=
|
||||||
github.com/grassrootseconomics/ussd-data-service v1.10.1-beta/go.mod h1:Uigrnnwj0vaTz2az3VwHmAG7xpJgQWYTcLudLh6Zc1I=
|
github.com/grassrootseconomics/ussd-data-service v1.5.0-beta h1:BSSQL/yPEvTVku9ja/ENZyZdwZkEaiTzzOUfg72bTy4=
|
||||||
|
github.com/grassrootseconomics/ussd-data-service v1.5.0-beta/go.mod h1:9sGnorpKaK76FmOGXoh/xv7x5siSFNYdXxQo9BKW4DI=
|
||||||
|
github.com/grassrootseconomics/ussd-data-service v1.6.0-beta h1:pY6zns6ifXyClRxP+JJaWrged3oRE7tTS2xaftF9clA=
|
||||||
|
github.com/grassrootseconomics/ussd-data-service v1.6.0-beta/go.mod h1:9sGnorpKaK76FmOGXoh/xv7x5siSFNYdXxQo9BKW4DI=
|
||||||
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=
|
||||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||||
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
|
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
|
||||||
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
|
github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA=
|
||||||
github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA=
|
github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs=
|
||||||
github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
||||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||||
github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk=
|
github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
|
||||||
github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
|
||||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4=
|
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||||
github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c=
|
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||||
github.com/lmittmann/w3 v0.20.5 h1:JN9eUaVifhnnEP5cdYpIvhvC6x2hUn9+LcWyPKLl8DI=
|
github.com/lmittmann/w3 v0.17.1 h1:zdXIimmNmYfqOFur+Jqc9Yqwtq6jwnsQufbTOnSAtW4=
|
||||||
github.com/lmittmann/w3 v0.20.5/go.mod h1:N/QfdxE9A8PpdX37AVJ4NjCdG9L5ZSuhqrru01ieRpM=
|
github.com/lmittmann/w3 v0.17.1/go.mod h1:WVUGMbL83WYBu4Sge3SVlW3qIG4VaHe+S8+UUnwz9Eg=
|
||||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||||
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a h1:0Q3H0YXzMHiciXtRcM+j0jiCe8WKPQHoRgQiRTnfcLY=
|
||||||
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
|
github.com/mattn/kinako v0.0.0-20170717041458-332c0a7e205a/go.mod h1:CdTTBOYzS5E4mWS1N8NWP6AHI19MP0A2B18n3hLzRMk=
|
||||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||||
|
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
||||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||||
github.com/pashagolub/pgxmock/v4 v4.7.0 h1:de2ORuFYyjwOQR7NBm57+321RnZxpYiuUjsmqRiqgh8=
|
github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s=
|
||||||
github.com/pashagolub/pgxmock/v4 v4.7.0/go.mod h1:9L57pC193h2aKRHVyiiE817avasIPZnPwPlw3JczWvM=
|
github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A=
|
||||||
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
|
github.com/peteole/testdata-loader v0.3.0 h1:8jckE9KcyNHgyv/VPoaljvKZE0Rqr8+dPVYH6rfNr9I=
|
||||||
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
|
github.com/peteole/testdata-loader v0.3.0/go.mod h1:Mt0ZbRtb56u8SLJpNP+BnQbENljMorYBpqlvt3cS83U=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg=
|
||||||
|
github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||||
|
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y=
|
||||||
|
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||||
|
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
|
||||||
|
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||||
|
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||||
|
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE=
|
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
|
||||||
github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
|
||||||
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
|
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||||
|
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||||
|
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ=
|
||||||
|
golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
|
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||||
|
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
@ -174,3 +232,5 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
|
||||||
|
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||||
|
|||||||
@ -3,13 +3,11 @@ package application
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||||
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"
|
|
||||||
"gopkg.in/leonelquinteros/gotext.v1"
|
"gopkg.in/leonelquinteros/gotext.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,7 +52,6 @@ func (h *MenuHandlers) CheckBalance(ctx context.Context, sym string, input []byt
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
content, err = loadUserContent(ctx, string(activeSym), string(activeBal), string(accAlias))
|
content, err = loadUserContent(ctx, string(activeSym), string(activeBal), string(accAlias))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return res, err
|
return res, err
|
||||||
@ -65,7 +62,7 @@ func (h *MenuHandlers) CheckBalance(ctx context.Context, sym string, input []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// loadUserContent loads the main user content in the main menu: the alias, balance and active symbol associated with active voucher
|
// loadUserContent loads the main user content in the main menu: the alias, balance and active symbol associated with active voucher
|
||||||
func loadUserContent(ctx context.Context, activeSym, balance, alias string) (string, error) {
|
func loadUserContent(ctx context.Context, activeSym string, balance string, alias string) (string, error) {
|
||||||
var content string
|
var content string
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
code := codeFromCtx(ctx)
|
||||||
@ -78,9 +75,8 @@ func loadUserContent(ctx context.Context, activeSym, balance, alias string) (str
|
|||||||
formattedAmount = "0.00"
|
formattedAmount = "0.00"
|
||||||
}
|
}
|
||||||
|
|
||||||
// format the final outputs
|
// format the final output
|
||||||
balStr := fmt.Sprintf("%s %s", formattedAmount, activeSym)
|
balStr := fmt.Sprintf("%s %s", formattedAmount, activeSym)
|
||||||
|
|
||||||
if alias != "" {
|
if alias != "" {
|
||||||
content = l.Get("%s\nBalance: %s\n", alias, balStr)
|
content = l.Get("%s\nBalance: %s\n", alias, balStr)
|
||||||
} else {
|
} else {
|
||||||
@ -102,144 +98,3 @@ func (h *MenuHandlers) FetchCommunityBalance(ctx context.Context, sym string, in
|
|||||||
res.Content = l.Get("Community Balance: 0.00")
|
res.Content = l.Get("Community Balance: 0.00")
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalculateCreditAndDebt calls the API to get the credit and debt
|
|
||||||
// uses the pretium rates to convert the value to Ksh
|
|
||||||
func (h *MenuHandlers) CalculateCreditAndDebt(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, activeBal, activeSym, activeAddress, publicKey, activeDecimal, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_api_call_error)
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch swappable vouchers (pool view)
|
|
||||||
swappableVouchers, err := h.accountService.GetPoolSwappableFromVouchers(ctx, string(activePoolAddress), string(publicKey))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetPoolSwappableFromVouchers", "error", err)
|
|
||||||
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(swappableVouchers) == 0 {
|
|
||||||
res.Content = l.Get("Credit: %s KSH\nDebt: %s %s\n", "0", "0", string(activeSym))
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch ALL wallet vouchers (voucher holdings view)
|
|
||||||
allVouchers, err := h.accountService.FetchVouchers(ctx, string(publicKey))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on FetchVouchers", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CREDIT calculation
|
|
||||||
// Rule:
|
|
||||||
// 1. Swap quote of active voucher → first stable in pool from GetPoolSwappableFromVouchers
|
|
||||||
// 2. PLUS all stable balances from FetchVouchers
|
|
||||||
|
|
||||||
scaledCredit := "0"
|
|
||||||
|
|
||||||
// 1. Find first stable voucher in POOL (for swap target)
|
|
||||||
var firstPoolStable *dataserviceapi.TokenHoldings
|
|
||||||
for i := range swappableVouchers {
|
|
||||||
if isStableVoucher(swappableVouchers[i].TokenAddress) {
|
|
||||||
firstPoolStable = &swappableVouchers[i]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. If pool has a stable, get swap quote
|
|
||||||
if firstPoolStable != nil {
|
|
||||||
finalAmountStr, err := store.ParseAndScaleAmount(
|
|
||||||
string(activeBal),
|
|
||||||
string(activeDecimal),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// swap active -> FIRST stable from pool list
|
|
||||||
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, string(publicKey), string(activeAddress), string(activePoolAddress), firstPoolStable.TokenAddress)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// scale using REAL stable decimals
|
|
||||||
finalQuote := store.ScaleDownBalance(r.OutValue, firstPoolStable.TokenDecimals)
|
|
||||||
|
|
||||||
scaledCredit = store.AddDecimalStrings(scaledCredit, finalQuote)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Add ALL wallet stable balances (from FetchVouchers)
|
|
||||||
for _, v := range allVouchers {
|
|
||||||
if isStableVoucher(v.TokenAddress) {
|
|
||||||
scaled := store.ScaleDownBalance(v.Balance, v.TokenDecimals)
|
|
||||||
scaledCredit = store.AddDecimalStrings(scaledCredit, scaled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// DEBT calculation
|
|
||||||
// Rule:
|
|
||||||
// - Default = 0
|
|
||||||
// - If active is stable → remain 0
|
|
||||||
// - If active is non-stable and exists in pool → use pool balance
|
|
||||||
|
|
||||||
scaledDebt := "0"
|
|
||||||
|
|
||||||
if !isStableVoucher(string(activeAddress)) {
|
|
||||||
for _, v := range swappableVouchers {
|
|
||||||
if v.TokenSymbol == string(activeSym) {
|
|
||||||
scaledDebt = store.ScaleDownBalance(v.Balance, v.TokenDecimals)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
formattedDebt, _ := store.TruncateDecimalString(scaledDebt, 2)
|
|
||||||
|
|
||||||
// Fetch MPESA rates
|
|
||||||
rates, err := h.accountService.GetMpesaOnrampRates(ctx)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetMpesaOnrampRates", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
creditFloat, _ := strconv.ParseFloat(scaledCredit, 64)
|
|
||||||
creditKsh := fmt.Sprintf("%f", creditFloat*rates.Buy)
|
|
||||||
kshFormattedCredit, _ := store.TruncateDecimalString(creditKsh, 0)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Credit: %s KSH\nDebt: %s %s\n",
|
|
||||||
kshFormattedCredit,
|
|
||||||
formattedDebt,
|
|
||||||
string(activeSym),
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -52,7 +52,7 @@ func TestCheckBalance(t *testing.T) {
|
|||||||
alias: "user72",
|
alias: "user72",
|
||||||
activeSym: "SRF",
|
activeSym: "SRF",
|
||||||
activeBal: "10.967",
|
activeBal: "10.967",
|
||||||
expectedResult: resource.Result{Content: "user72\nBalance: 10.96 SRF\n"},
|
expectedResult: resource.Result{Content: "user72 balance: 10.96 SRF\n"},
|
||||||
expectError: false,
|
expectError: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,678 +0,0 @@
|
|||||||
package application
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.grassecon.net/grassrootseconomics/common/hex"
|
|
||||||
"git.grassecon.net/grassrootseconomics/common/phone"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
dataserviceapi "github.com/grassrootseconomics/ussd-data-service/pkg/api"
|
|
||||||
"gopkg.in/leonelquinteros/gotext.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetMpesaMaxLimit returns the max FROM token
|
|
||||||
// check if max/tokenDecimals > 0.1 for UX purposes and to prevent swapping of dust values
|
|
||||||
func (h *MenuHandlers) GetMpesaMaxLimit(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_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
flag_low_swap_amount, _ := h.flagManager.GetFlag("flag_low_swap_amount")
|
|
||||||
flag_incorrect_pool, _ := h.flagManager.GetFlag("flag_incorrect_pool")
|
|
||||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
metadata, err := store.GetOrderedVoucherData(ctx, userStore, sessionId, inputStr)
|
|
||||||
if err != nil {
|
|
||||||
return res, fmt.Errorf("failed to retrieve swap to voucher data: %v", err)
|
|
||||||
}
|
|
||||||
if metadata == nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_incorrect_voucher)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the active transaction voucher data (from token)
|
|
||||||
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, _, _, _, publicKey, _, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the mpesa rates API to get the rates
|
|
||||||
rates, err := h.accountService.GetMpesaOnrampRates(ctx)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetMpesaOnrampRates", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
txType := "swap"
|
|
||||||
mpesaAddress := config.DefaultMpesaAddress()
|
|
||||||
|
|
||||||
// Normalize the mpesa address to fetch the phone number
|
|
||||||
publicKeyNormalized, err := hex.NormalizeHex(mpesaAddress)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to normalize alias address", "address", mpesaAddress, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the recipient's phone number from the address
|
|
||||||
recipientPhoneNumber, err := userStore.ReadEntry(ctx, publicKeyNormalized, storedb.DATA_PUBLIC_KEY_REVERSE)
|
|
||||||
if err != nil || len(recipientPhoneNumber) == 0 {
|
|
||||||
logg.WarnCtxf(ctx, "Alias address not registered, switching to normal transaction", "address", mpesaAddress)
|
|
||||||
recipientPhoneNumber = nil
|
|
||||||
}
|
|
||||||
// store it for future reference (TODO)
|
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_RECIPIENT_PHONE_NUMBER, recipientPhoneNumber); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to write recipient phone number", "value", string(recipientPhoneNumber), "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetch data for verification (to_voucher data)
|
|
||||||
recipientActiveSym, recipientActiveAddress, recipientActiveDecimal, err := h.getRecipientData(ctx, string(recipientPhoneNumber))
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch min withdrawal amount from config/env
|
|
||||||
minksh := fmt.Sprintf("%f", config.MinMpesaWithdrawAmount())
|
|
||||||
minKshFormatted, _ := store.TruncateDecimalString(minksh, 0)
|
|
||||||
|
|
||||||
// If SAT is the same as RAT, return early with KSH format
|
|
||||||
if string(metadata.TokenAddress) == string(recipientActiveAddress) {
|
|
||||||
txType = "normal"
|
|
||||||
// Save the transaction type
|
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to write transaction type", "type", txType, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
activeFloat, _ := strconv.ParseFloat(string(metadata.Balance), 64)
|
|
||||||
ksh := fmt.Sprintf("%f", activeFloat*rates.Buy)
|
|
||||||
|
|
||||||
maxKshFormatted, _ := store.TruncateDecimalString(ksh, 0)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n",
|
|
||||||
minKshFormatted,
|
|
||||||
maxKshFormatted,
|
|
||||||
)
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool address
|
|
||||||
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if selected token is swappable
|
|
||||||
canSwap, err := h.accountService.CheckTokenInPool(ctx, string(activePoolAddress), string(metadata.TokenAddress))
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
logg.ErrorCtxf(ctx, "failed on CheckTokenInPool", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !canSwap.CanSwapFrom { // pool issue (CATCH on .vis)
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_incorrect_pool)
|
|
||||||
res.Content = "0"
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve the max credit send amounts
|
|
||||||
_, maxRAT, err := h.calculateSendCreditLimits(ctx, activePoolAddress, []byte(metadata.TokenAddress), recipientActiveAddress, publicKey, []byte(metadata.TokenDecimals), recipientActiveDecimal)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = "0"
|
|
||||||
logg.ErrorCtxf(ctx, "failed on calculateSendCreditLimits", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_api_call_error)
|
|
||||||
|
|
||||||
// Fallback if below minimum
|
|
||||||
maxFloat, _ := strconv.ParseFloat(maxRAT, 64)
|
|
||||||
if maxFloat < 0.1 {
|
|
||||||
formatted, _ := store.TruncateDecimalString(maxRAT, 2)
|
|
||||||
res.Content = formatted
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_low_swap_amount)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount)
|
|
||||||
|
|
||||||
// Save max RAT amount to be used in validating the user's input
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, []byte(maxRAT))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write swap max amount (maxRAT)", "value", maxRAT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the transaction type
|
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE, []byte(txType)); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to write transaction type", "type", txType, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// save swap related data for the swap preview (the swap to)
|
|
||||||
swapMetadata := &dataserviceapi.TokenHoldings{
|
|
||||||
TokenAddress: string(recipientActiveAddress),
|
|
||||||
TokenSymbol: string(recipientActiveSym),
|
|
||||||
TokenDecimals: string(recipientActiveDecimal),
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the active swap_to data
|
|
||||||
if err := store.UpdateSwapToVoucherData(ctx, userStore, sessionId, swapMetadata); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on UpdateSwapToVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
maxKsh := maxFloat * rates.Buy
|
|
||||||
kshStr := fmt.Sprintf("%f", maxKsh)
|
|
||||||
maxKshFormatted, _ := store.TruncateDecimalString(kshStr, 0)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n",
|
|
||||||
minKshFormatted,
|
|
||||||
maxKshFormatted,
|
|
||||||
)
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error, flag_incorrect_voucher, flag_incorrect_pool)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMpesaPreview displays the get mpesa preview and estimates
|
|
||||||
func (h *MenuHandlers) GetMpesaPreview(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
// INPUT IN RAT Ksh
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "9" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// call the mpesa rates API to get the rates
|
|
||||||
rates, err := h.accountService.GetMpesaOnrampRates(ctx)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetMpesaOnrampRates", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input in Ksh
|
|
||||||
kshAmount, err := strconv.ParseFloat(inputStr, 64)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
min := config.MinMpesaWithdrawAmount()
|
|
||||||
|
|
||||||
if kshAmount < min {
|
|
||||||
// if the input is below the minimum
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// divide by the buy rate
|
|
||||||
inputAmount := kshAmount / rates.Buy
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
transactionType, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the selected voucher
|
|
||||||
mpesaWithdrawalVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(transactionType) == "normal" {
|
|
||||||
// get the max based on the selected voucher balance
|
|
||||||
maxValue, err := strconv.ParseFloat(mpesaWithdrawalVoucher.Balance, 64)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to convert the stored balance string to a float", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
if inputAmount > maxValue {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the input amount to 2 decimal places
|
|
||||||
inputAmountStr := fmt.Sprintf("%f", inputAmount)
|
|
||||||
qouteInputAmount, _ := store.TruncateDecimalString(inputAmountStr, 2)
|
|
||||||
|
|
||||||
// store the inputAmountStr as the final amount (that will be sent)
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(inputAmountStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write send amount value entry with", "key", storedb.DATA_AMOUNT, "value", inputAmountStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"You are sending %s %s in order to receive ~ %s ksh",
|
|
||||||
qouteInputAmount, mpesaWithdrawalVoucher.TokenSymbol, inputStr,
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
swapToVoucher, err := store.ReadSwapToVoucher(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapMaxAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read swapMaxAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// use the stored max RAT
|
|
||||||
maxRATValue, err := strconv.ParseFloat(string(swapMaxAmount), 64)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to convert the swapMaxAmount to a float", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if inputAmount > maxRATValue {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the amount to 2 decimal places
|
|
||||||
formattedAmount, err := store.TruncateDecimalString(fmt.Sprintf("%f", inputAmount), 2)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
finalAmountStr, err := store.ParseAndScaleAmount(formattedAmount, swapToVoucher.TokenDecimals)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the credit send API to get the reverse quote
|
|
||||||
r, err := h.accountService.GetCreditSendReverseQuote(ctx, string(activePoolAddress), mpesaWithdrawalVoucher.TokenAddress, swapToVoucher.TokenAddress, finalAmountStr)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed GetCreditSendReverseQuote poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
sendInputAmount := r.InputAmount // amount of SAT
|
|
||||||
sendOutputAmount := r.OutputAmount // amount of RAT
|
|
||||||
|
|
||||||
// store the sendOutputAmount as the final amount (that will be sent)
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(sendOutputAmount))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write output amount value entry with", "key", storedb.DATA_AMOUNT, "value", sendOutputAmount, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// store the sendInputAmount as the swap amount
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT, []byte(sendInputAmount))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write swap amount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "value", sendInputAmount, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// covert for display
|
|
||||||
quoteInputStr := store.ScaleDownBalance(sendInputAmount, mpesaWithdrawalVoucher.TokenDecimals)
|
|
||||||
// Format the quoteInputStr amount to 2 decimal places
|
|
||||||
qouteInputAmount, _ := store.TruncateDecimalString(quoteInputStr, 2)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"You are sending %s %s in order to receive ~ %s ksh",
|
|
||||||
qouteInputAmount, mpesaWithdrawalVoucher.TokenSymbol, inputStr,
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiateGetMpesa calls the poolSwap, followed by the transfer and returns a confirmation based on the result.
|
|
||||||
func (h *MenuHandlers) InitiateGetMpesa(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
var err error
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
|
||||||
if !ok {
|
|
||||||
return res, fmt.Errorf("missing session")
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
mpesaAddress := config.DefaultMpesaAddress()
|
|
||||||
|
|
||||||
transactionType, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_SEND_TRANSACTION_TYPE)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the selected voucher
|
|
||||||
mpesaWithdrawalVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(transactionType) == "normal" {
|
|
||||||
// Call TokenTransfer for the normal transaction
|
|
||||||
data, err := store.ReadTransactionData(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
finalAmountStr, err := store.ParseAndScaleAmount(data.Amount, mpesaWithdrawalVoucher.TokenDecimals)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tokenTransfer, err := h.accountService.TokenTransfer(ctx, finalAmountStr, data.PublicKey, mpesaAddress, mpesaWithdrawalVoucher.TokenAddress)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on TokenTransfer", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logg.InfoCtxf(ctx, "TokenTransfer normal", "trackingId", tokenTransfer.TrackingId)
|
|
||||||
|
|
||||||
res.Content = l.Get("Your request has been sent. Please await confirmation")
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_authorized)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapToVoucher, err := store.ReadSwapToVoucher(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapAmountStr := string(swapAmount)
|
|
||||||
|
|
||||||
// Call the poolSwap API
|
|
||||||
poolSwap, err := h.accountService.PoolSwap(ctx, swapAmountStr, string(publicKey), mpesaWithdrawalVoucher.TokenAddress, string(activePoolAddress), swapToVoucher.TokenAddress)
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logg.InfoCtxf(ctx, "mpesa poolSwap before transfer", "swapTrackingId", poolSwap.TrackingId)
|
|
||||||
|
|
||||||
// TODO: remove this temporary time delay and replace with a swap and send endpoint
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
|
|
||||||
amount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initiate a send to mpesa after the swap
|
|
||||||
tokenTransfer, err := h.accountService.TokenTransfer(ctx, string(amount), string(publicKey), mpesaAddress, swapToVoucher.TokenAddress)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on TokenTransfer after swap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logg.InfoCtxf(ctx, "final TokenTransfer after swap", "trackingId", tokenTransfer.TrackingId)
|
|
||||||
|
|
||||||
res.Content = l.Get("Your request has been sent. Please await confirmation")
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_authorized)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMpesaMinLimit returns the min amount from the config
|
|
||||||
func (h *MenuHandlers) SendMpesaMinLimit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "9" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch min amount from config/env
|
|
||||||
min := config.MinMpesaSendAmount()
|
|
||||||
|
|
||||||
// Convert to string
|
|
||||||
ksh := fmt.Sprintf("%f", min)
|
|
||||||
|
|
||||||
// Format (e.g., 100.0 -> 100)
|
|
||||||
kshFormatted, _ := store.TruncateDecimalString(ksh, 0)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Enter the amount of credit to deposit: (Minimum %s Ksh)\n",
|
|
||||||
kshFormatted,
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SendMpesaPreview displays the send mpesa preview and estimates
|
|
||||||
func (h *MenuHandlers) SendMpesaPreview(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
// INPUT IN Ksh
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "9" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// call the mpesa rates API to get the rates
|
|
||||||
rates, err := h.accountService.GetMpesaOnrampRates(ctx)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetMpesaOnrampRates", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Input in Ksh
|
|
||||||
kshAmount, err := strconv.ParseFloat(inputStr, 64)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
min := config.MinMpesaSendAmount()
|
|
||||||
max := config.MaxMpesaSendAmount()
|
|
||||||
|
|
||||||
if kshAmount > max || kshAmount < min {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_invalid_amount)
|
|
||||||
|
|
||||||
// store the user's raw input amount
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(inputStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write amount inputStr entry with", "key", storedb.DATA_AMOUNT, "value", inputStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
estimateValue := kshAmount / rates.Sell
|
|
||||||
estimateStr := fmt.Sprintf("%f", estimateValue)
|
|
||||||
estimateFormatted, _ := store.TruncateDecimalString(estimateStr, 2)
|
|
||||||
|
|
||||||
defaultAsset := config.DefaultMpesaAsset()
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"You will get a prompt for your Mpesa PIN shortly to send %s ksh and receive ~ %s %s",
|
|
||||||
inputStr, estimateFormatted, defaultAsset,
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiateSendMpesa calls the trigger-onram API to initiate the purchase
|
|
||||||
func (h *MenuHandlers) InitiateSendMpesa(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
var err error
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
|
||||||
if !ok {
|
|
||||||
return res, fmt.Errorf("missing session")
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
phoneNumber, err := phone.FormatToLocalPhoneNumber(sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on FormatToLocalPhoneNumber", "session-id", sessionId, "error", err)
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultAsset := config.DefaultMpesaAsset()
|
|
||||||
|
|
||||||
amount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read amount entry", "key", storedb.DATA_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
amountInt, err := strconv.Atoi(string(amount))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to convert amount to int", "amount", string(amount), "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the trigger onramp API
|
|
||||||
triggerOnramp, err := h.accountService.MpesaTriggerOnramp(ctx, string(publicKey), phoneNumber, defaultAsset, amountInt)
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on MpesaTriggerOnramp", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
logg.InfoCtxf(ctx, "MpesaTriggerOnramp", "transactionCode", triggerOnramp.TransactionCode)
|
|
||||||
|
|
||||||
res.Content = l.Get("Your request has been sent. Thank you for using Sarafu")
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_authorized)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
@ -1,329 +0,0 @@
|
|||||||
package application
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/resource"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
|
||||||
storedb "git.grassecon.net/grassrootseconomics/sarafu-vise/store/db"
|
|
||||||
"gopkg.in/leonelquinteros/gotext.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CalculateMaxPayDebt calculates the max debt removal based on the selected voucher
|
|
||||||
func (h *MenuHandlers) CalculateMaxPayDebt(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_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
flag_low_swap_amount, _ := h.flagManager.GetFlag("flag_low_swap_amount")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, _, activeSym, activeAddress, publicKey, activeDecimal, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the voucher data based on the input
|
|
||||||
metadata, err := store.GetVoucherData(ctx, userStore, sessionId, inputStr)
|
|
||||||
if err != nil {
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error)
|
|
||||||
return res, fmt.Errorf("failed to retrieve swap to voucher data: %v", err)
|
|
||||||
}
|
|
||||||
if metadata == nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the max swap limit with the selected voucher
|
|
||||||
r, err := h.accountService.GetSwapFromTokenMaxLimit(ctx, string(activePoolAddress), metadata.TokenAddress, string(activeAddress), string(publicKey))
|
|
||||||
if err != nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = "0"
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetSwapFromTokenMaxLimit", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
maxLimit := r.Max
|
|
||||||
|
|
||||||
metadata.Balance = maxLimit
|
|
||||||
|
|
||||||
// Store the active swap from data
|
|
||||||
if err := store.UpdateSwapFromVoucherData(ctx, userStore, sessionId, metadata); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on UpdateSwapFromVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale down the amount
|
|
||||||
maxAmountStr := store.ScaleDownBalance(maxLimit, metadata.TokenDecimals)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
maxAmountFloat, err := strconv.ParseFloat(maxAmountStr, 64)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to parse maxAmountStr as float", "value", maxAmountStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format to 2 decimal places
|
|
||||||
maxStr, _ := store.TruncateDecimalString(string(maxAmountStr), 2)
|
|
||||||
|
|
||||||
if maxAmountFloat < 0.1 {
|
|
||||||
// return with low amount flag
|
|
||||||
res.Content = maxStr
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_low_swap_amount)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, []byte(maxStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write swap max amount entry with", "key", storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, "value", maxStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do a pool quote to get the max AT that can be removed (gotten)
|
|
||||||
// if we swapped the max of the FT
|
|
||||||
|
|
||||||
// call the API to get the quote
|
|
||||||
qoute, err := h.accountService.GetPoolSwapQuote(ctx, maxLimit, string(publicKey), metadata.TokenAddress, string(activePoolAddress), string(activeAddress))
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale down the quoted amount
|
|
||||||
quoteAmountStr := store.ScaleDownBalance(qoute.OutValue, string(activeDecimal))
|
|
||||||
|
|
||||||
// Format to 2 decimal places
|
|
||||||
quoteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"You can remove a max of %s %s from '%s' pool\nEnter amount of %s:(Max: %s)",
|
|
||||||
quoteStr,
|
|
||||||
string(activeSym),
|
|
||||||
string(activePoolSymbol),
|
|
||||||
metadata.TokenSymbol,
|
|
||||||
maxStr,
|
|
||||||
)
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_low_swap_amount, flag_api_call_error)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfirmDebtRemoval displays the debt preview for a confirmation
|
|
||||||
func (h *MenuHandlers) ConfirmDebtRemoval(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, _, activeSym, activeAddress, publicKey, activeDecimal, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
payDebtVoucher, err := store.ReadSwapFromVoucher(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, _, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapMaxAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read swapMaxAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_MAX_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
maxValue, err := strconv.ParseFloat(string(swapMaxAmount), 64)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to convert the swapMaxAmount to a float", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
inputAmount, err := strconv.ParseFloat(inputStr, 64)
|
|
||||||
if err != nil || inputAmount > maxValue || inputAmount < 0.1 {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var finalAmountStr string
|
|
||||||
if inputStr == string(swapMaxAmount) {
|
|
||||||
finalAmountStr = string(payDebtVoucher.Balance)
|
|
||||||
} else {
|
|
||||||
finalAmountStr, err = store.ParseAndScaleAmount(inputStr, payDebtVoucher.TokenDecimals)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT, []byte(finalAmountStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write swap amount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "value", finalAmountStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// call the API to get the quote
|
|
||||||
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, string(publicKey), payDebtVoucher.TokenAddress, string(activePoolAddress), string(activeAddress))
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale down the quoted amount (for the AT)
|
|
||||||
quoteAmountStr := store.ScaleDownBalance(r.OutValue, string(activeDecimal))
|
|
||||||
|
|
||||||
// Format to 2 decimal places
|
|
||||||
qouteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2)
|
|
||||||
|
|
||||||
// store the quote in the temporary value key
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(qouteStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write swap max amount entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", qouteStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Please confirm that you will use %s %s to remove your debt of %s %s\nEnter your PIN:",
|
|
||||||
inputStr, payDebtVoucher.TokenSymbol, qouteStr, string(activeSym),
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiatePayDebt calls the poolSwap to swap the token for the active voucher.
|
|
||||||
func (h *MenuHandlers) InitiatePayDebt(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
var err error
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
|
||||||
if !ok {
|
|
||||||
return res, fmt.Errorf("missing session")
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, _, activeSym, activeAddress, publicKey, _, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
payDebtVoucher, err := store.ReadSwapFromVoucher(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on ReadSwapFromVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SWAP_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read swapAmount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
debtQuotedAmount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read debtQuotedAmount entry with", "key", storedb.DATA_TEMPORARY_VALUE, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
swapAmountStr := string(swapAmount)
|
|
||||||
|
|
||||||
// Call the poolSwap API
|
|
||||||
r, err := h.accountService.PoolSwap(ctx, swapAmountStr, string(publicKey), payDebtVoucher.TokenAddress, string(activePoolAddress), string(activeAddress))
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
trackingId := r.TrackingId
|
|
||||||
logg.InfoCtxf(ctx, "poolSwap", "trackingId", trackingId)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Your request has been sent. You will receive an SMS when your debt of %s %s has been removed from %s.",
|
|
||||||
string(debtQuotedAmount),
|
|
||||||
string(activeSym),
|
|
||||||
activePoolSymbol,
|
|
||||||
)
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_authorized)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isStableVoucher(tokenAddress string) bool {
|
|
||||||
addr := strings.TrimSpace(tokenAddress)
|
|
||||||
for _, stable := range config.StableVoucherAddresses() {
|
|
||||||
if addr == stable {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
@ -1,231 +0,0 @@
|
|||||||
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"
|
|
||||||
"gopkg.in/leonelquinteros/gotext.v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// GetOrderedVouchers returns a list of ordered vouchers with stables at the top
|
|
||||||
func (h *MenuHandlers) GetOrderedVouchers(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// Read ordered vouchers from the store
|
|
||||||
voucherData, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ORDERED_VOUCHER_SYMBOLS)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read stable voucherData entires with", "key", storedb.DATA_ORDERED_VOUCHER_SYMBOLS, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(voucherData) == 0 {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
voucherBalances, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ORDERED_VOUCHER_BALANCES)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read stable voucherData entires with", "key", storedb.DATA_ORDERED_VOUCHER_BALANCES, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
formattedVoucherList := store.FormatVoucherList(ctx, string(voucherData), string(voucherBalances))
|
|
||||||
finalOutput := strings.Join(formattedVoucherList, "\n")
|
|
||||||
|
|
||||||
res.Content = l.Get("Select number or symbol from your vouchers:\n%s", finalOutput)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PoolDepositMaxAmount returns the balance of the selected voucher
|
|
||||||
func (h *MenuHandlers) PoolDepositMaxAmount(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher)
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
metadata, err := store.GetOrderedVoucherData(ctx, userStore, sessionId, inputStr)
|
|
||||||
if err != nil {
|
|
||||||
return res, fmt.Errorf("failed to retrieve swap to voucher data: %v", err)
|
|
||||||
}
|
|
||||||
if metadata == nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_incorrect_voucher)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the pool deposit voucher data
|
|
||||||
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format the balance amount to 2 decimal places
|
|
||||||
formattedBalance, _ := store.TruncateDecimalString(string(metadata.Balance), 2)
|
|
||||||
|
|
||||||
res.Content = l.Get("Maximum amount: %s %s\nEnter amount:", formattedBalance, metadata.TokenSymbol)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfirmPoolDeposit displays the pool deposit preview for a PIN confirmation
|
|
||||||
func (h *MenuHandlers) ConfirmPoolDeposit(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_invalid_amount, _ := h.flagManager.GetFlag("flag_invalid_amount")
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_invalid_amount)
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
poolDepositVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
maxValue, err := strconv.ParseFloat(poolDepositVoucher.Balance, 64)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to convert the swapMaxAmount to a float", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
inputAmount, err := strconv.ParseFloat(inputStr, 64)
|
|
||||||
if err != nil || inputAmount > maxValue || inputAmount < 0.1 {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_invalid_amount)
|
|
||||||
res.Content = inputStr
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_AMOUNT, []byte(inputStr))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write pool deposit amount entry with", "key", storedb.DATA_AMOUNT, "value", inputStr, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
_, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"You will deposit %s %s into %s\n",
|
|
||||||
inputStr, poolDepositVoucher.TokenSymbol, activePoolSymbol,
|
|
||||||
)
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// InitiatePoolDeposit calls the pool deposit API
|
|
||||||
func (h *MenuHandlers) InitiatePoolDeposit(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
|
||||||
var res resource.Result
|
|
||||||
var err error
|
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
|
||||||
if !ok {
|
|
||||||
return res, fmt.Errorf("missing session")
|
|
||||||
}
|
|
||||||
|
|
||||||
flag_account_authorized, _ := h.flagManager.GetFlag("flag_account_authorized")
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
|
|
||||||
// Resolve active pool
|
|
||||||
activePoolAddress, activePoolSymbol, err := h.resolveActivePoolDetails(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on resolveActivePoolDetails", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
poolDepositVoucher, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read publicKey entry", "key", storedb.DATA_PUBLIC_KEY, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
amount, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_AMOUNT)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to read amount entry", "key", storedb.DATA_AMOUNT, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
finalAmountStr, err := store.ParseAndScaleAmount(string(amount), poolDepositVoucher.TokenDecimals)
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on ParseAndScaleAmount", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call pool deposit API
|
|
||||||
r, err := h.accountService.PoolDeposit(ctx, finalAmountStr, string(publicKey), string(activePoolAddress), poolDepositVoucher.TokenAddress)
|
|
||||||
if err != nil {
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
|
||||||
logg.ErrorCtxf(ctx, "failed on pool deposit", "error", err)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
trackingId := r.TrackingId
|
|
||||||
logg.InfoCtxf(ctx, "Pool deposit", "trackingId", trackingId)
|
|
||||||
|
|
||||||
res.Content = l.Get(
|
|
||||||
"Your request has been sent. You will receive an SMS when %s %s has been deposited into %s.",
|
|
||||||
string(amount),
|
|
||||||
poolDepositVoucher.TokenSymbol,
|
|
||||||
activePoolSymbol,
|
|
||||||
)
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_account_authorized)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
@ -3,7 +3,6 @@ package application
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
@ -23,12 +22,12 @@ func (h *MenuHandlers) GetPools(ctx context.Context, sym string, input []byte) (
|
|||||||
}
|
}
|
||||||
userStore := h.userdataStore
|
userStore := h.userdataStore
|
||||||
|
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_error")
|
||||||
|
|
||||||
// call the api to get a list of top 5 pools sorted by swaps
|
// call the api to get a list of top 5 pools sorted by swaps
|
||||||
topPools, err := h.accountService.FetchTopPools(ctx)
|
topPools, err := h.accountService.FetchTopPools(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -105,7 +104,6 @@ func (h *MenuHandlers) GetDefaultPool(ctx context.Context, sym string, input []b
|
|||||||
|
|
||||||
// ViewPool retrieves the pool details from the user store
|
// ViewPool retrieves the pool details from the user store
|
||||||
// and displays it to the user for them to select it.
|
// and displays it to the user for them to select it.
|
||||||
// if the data does not exist, it calls the API to get the pool details
|
|
||||||
func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
var res resource.Result
|
var res resource.Result
|
||||||
sessionId, ok := ctx.Value("SessionId").(string)
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
@ -131,15 +129,12 @@ func (h *MenuHandlers) ViewPool(ctx context.Context, sym string, input []byte) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if poolData == nil {
|
if poolData == nil {
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
||||||
|
|
||||||
// convert to uppercase before the call
|
|
||||||
poolSymbol := strings.ToUpper(inputStr)
|
|
||||||
|
|
||||||
// no match found. Call the API using the inputStr as the symbol
|
// no match found. Call the API using the inputStr as the symbol
|
||||||
poolResp, err := h.accountService.RetrievePoolDetails(ctx, poolSymbol)
|
poolResp, err := h.accountService.RetrievePoolDetails(ctx, inputStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,7 @@ func (h *MenuHandlers) LoadSwapToList(ctx context.Context, sym string, input []b
|
|||||||
l.AddDomain("default")
|
l.AddDomain("default")
|
||||||
|
|
||||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_error")
|
||||||
|
|
||||||
inputStr := string(input)
|
inputStr := string(input)
|
||||||
if inputStr == "0" {
|
if inputStr == "0" {
|
||||||
@ -88,7 +88,7 @@ func (h *MenuHandlers) LoadSwapToList(ctx context.Context, sym string, input []b
|
|||||||
// call the api using the ActivePoolAddress and ActiveVoucherAddress to check if it is part of the pool
|
// call the api using the ActivePoolAddress and ActiveVoucherAddress to check if it is part of the pool
|
||||||
r, err := h.accountService.CheckTokenInPool(ctx, string(activePoolAddress), string(activeAddress))
|
r, err := h.accountService.CheckTokenInPool(ctx, string(activePoolAddress), string(activeAddress))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
logg.ErrorCtxf(ctx, "failed on CheckTokenInPool", "error", err)
|
logg.ErrorCtxf(ctx, "failed on CheckTokenInPool", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ func (h *MenuHandlers) LoadSwapToList(ctx context.Context, sym string, input []b
|
|||||||
// call the api using the activePoolAddress to get a list of SwapToSymbolsData
|
// call the api using the activePoolAddress to get a list of SwapToSymbolsData
|
||||||
swapToList, err := h.accountService.GetPoolSwappableVouchers(ctx, string(activePoolAddress))
|
swapToList, err := h.accountService.GetPoolSwappableVouchers(ctx, string(activePoolAddress))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_error")
|
||||||
flag_low_swap_amount, _ := h.flagManager.GetFlag("flag_low_swap_amount")
|
flag_low_swap_amount, _ := h.flagManager.GetFlag("flag_low_swap_amount")
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher, flag_low_swap_amount)
|
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher, flag_low_swap_amount)
|
||||||
@ -175,10 +175,6 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
userStore := h.userdataStore
|
||||||
metadata, err := store.GetSwapToVoucherData(ctx, userStore, sessionId, inputStr)
|
metadata, err := store.GetSwapToVoucherData(ctx, userStore, sessionId, inputStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -206,9 +202,9 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
|
|||||||
logg.InfoCtxf(ctx, "Call GetSwapFromTokenMaxLimit with:", "ActivePoolAddress", swapData.ActivePoolAddress, "ActiveSwapFromAddress", swapData.ActiveSwapFromAddress, "ActiveSwapToAddress", swapData.ActiveSwapToAddress, "publicKey", swapData.PublicKey)
|
logg.InfoCtxf(ctx, "Call GetSwapFromTokenMaxLimit with:", "ActivePoolAddress", swapData.ActivePoolAddress, "ActiveSwapFromAddress", swapData.ActiveSwapFromAddress, "ActiveSwapToAddress", swapData.ActiveSwapToAddress, "publicKey", swapData.PublicKey)
|
||||||
r, err := h.accountService.GetSwapFromTokenMaxLimit(ctx, swapData.ActivePoolAddress, swapData.ActiveSwapFromAddress, swapData.ActiveSwapToAddress, swapData.PublicKey)
|
r, err := h.accountService.GetSwapFromTokenMaxLimit(ctx, swapData.ActivePoolAddress, swapData.ActiveSwapFromAddress, swapData.ActiveSwapToAddress, swapData.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
logg.ErrorCtxf(ctx, "failed on GetSwapFromTokenMaxLimit", "error", err)
|
logg.ErrorCtxf(ctx, "failed on GetSwapFromTokenMaxLimit", "error", err)
|
||||||
return res, nil
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale down the amount
|
// Scale down the amount
|
||||||
@ -224,7 +220,7 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format to 2 decimal places
|
// Format to 2 decimal places
|
||||||
maxStr, _ := store.TruncateDecimalString(string(maxAmountStr), 2)
|
maxStr := fmt.Sprintf("%.2f", maxAmountFloat)
|
||||||
|
|
||||||
if maxAmountFloat < 0.1 {
|
if maxAmountFloat < 0.1 {
|
||||||
// return with low amount flag
|
// return with low amount flag
|
||||||
@ -239,9 +235,9 @@ func (h *MenuHandlers) SwapMaxLimit(ctx context.Context, sym string, input []byt
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res.Content = l.Get(
|
res.Content = fmt.Sprintf(
|
||||||
"Maximum: %s %s\n\nEnter amount of %s to swap for %s:",
|
"Maximum: %s\n\nEnter amount of %s to swap for %s:",
|
||||||
maxStr, swapData.ActiveSwapFromSym, swapData.ActiveSwapFromSym, swapData.ActiveSwapToSym,
|
maxStr, swapData.ActiveSwapFromSym, swapData.ActiveSwapToSym,
|
||||||
)
|
)
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -307,15 +303,15 @@ func (h *MenuHandlers) SwapPreview(ctx context.Context, sym string, input []byte
|
|||||||
// store the user's input amount in the temporary value
|
// store the user's input amount in the temporary value
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(inputStr))
|
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TEMPORARY_VALUE, []byte(inputStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed to write inputStr amount entry with", "key", storedb.DATA_TEMPORARY_VALUE, "value", inputStr, "error", err)
|
logg.ErrorCtxf(ctx, "failed to write swap amount entry with", "key", storedb.DATA_ACTIVE_SWAP_AMOUNT, "value", finalAmountStr, "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// call the API to get the quote
|
// call the API to get the quote
|
||||||
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, swapData.PublicKey, swapData.ActiveSwapFromAddress, swapData.ActivePoolAddress, swapData.ActiveSwapToAddress)
|
r, err := h.accountService.GetPoolSwapQuote(ctx, finalAmountStr, swapData.PublicKey, swapData.ActiveSwapFromAddress, swapData.ActivePoolAddress, swapData.ActiveSwapToAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
res.Content = l.Get("Your request failed. Please try again later.")
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
||||||
return res, nil
|
return res, nil
|
||||||
@ -323,12 +319,17 @@ func (h *MenuHandlers) SwapPreview(ctx context.Context, sym string, input []byte
|
|||||||
|
|
||||||
// Scale down the quoted amount
|
// Scale down the quoted amount
|
||||||
quoteAmountStr := store.ScaleDownBalance(r.OutValue, swapData.ActiveSwapToDecimal)
|
quoteAmountStr := store.ScaleDownBalance(r.OutValue, swapData.ActiveSwapToDecimal)
|
||||||
|
qouteAmount, err := strconv.ParseFloat(quoteAmountStr, 64)
|
||||||
|
if err != nil {
|
||||||
|
logg.ErrorCtxf(ctx, "failed to parse quoteAmountStr as float", "value", quoteAmountStr, "error", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
// Format to 2 decimal places
|
// Format to 2 decimal places
|
||||||
qouteStr, _ := store.TruncateDecimalString(string(quoteAmountStr), 2)
|
qouteStr := fmt.Sprintf("%.2f", qouteAmount)
|
||||||
|
|
||||||
res.Content = l.Get(
|
res.Content = fmt.Sprintf(
|
||||||
"You will swap %s %s for %s %s:",
|
"You will swap:\n%s %s for %s %s:",
|
||||||
inputStr, swapData.ActiveSwapFromSym, qouteStr, swapData.ActiveSwapToSym,
|
inputStr, swapData.ActiveSwapFromSym, qouteStr, swapData.ActiveSwapToSym,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -368,8 +369,8 @@ func (h *MenuHandlers) InitiateSwap(ctx context.Context, sym string, input []byt
|
|||||||
// Call the poolSwap API
|
// Call the poolSwap API
|
||||||
r, err := h.accountService.PoolSwap(ctx, swapAmountStr, swapData.PublicKey, swapData.ActiveSwapFromAddress, swapData.ActivePoolAddress, swapData.ActiveSwapToAddress)
|
r, err := h.accountService.PoolSwap(ctx, swapAmountStr, swapData.PublicKey, swapData.ActiveSwapFromAddress, swapData.ActivePoolAddress, swapData.ActiveSwapToAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
res.Content = l.Get("Your request failed. Please try again later.")
|
res.Content = l.Get("Your request failed. Please try again later.")
|
||||||
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
logg.ErrorCtxf(ctx, "failed on poolSwap", "error", err)
|
||||||
return res, nil
|
return res, nil
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -277,7 +277,7 @@ func TestMaxAmount(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.MaxAmount(ctx, "send_max_amount", []byte(""))
|
res, err := h.MaxAmount(ctx, "max_amount", []byte(""))
|
||||||
|
|
||||||
if tt.expectedError {
|
if tt.expectedError {
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
@ -452,7 +452,7 @@ func TestGetAmount(t *testing.T) {
|
|||||||
assert.Equal(t, formattedAmount, res.Content)
|
assert.Equal(t, formattedAmount, res.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitiateNormalTransaction(t *testing.T) {
|
func TestInitiateTransaction(t *testing.T) {
|
||||||
sessionId := "254712345678"
|
sessionId := "254712345678"
|
||||||
ctx, store := InitializeTestStore(t)
|
ctx, store := InitializeTestStore(t)
|
||||||
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
ctx = context.WithValue(ctx, "SessionId", sessionId)
|
||||||
@ -538,7 +538,7 @@ func TestInitiateNormalTransaction(t *testing.T) {
|
|||||||
mockAccountService.On("TokenTransfer").Return(tt.TransferResponse, nil)
|
mockAccountService.On("TokenTransfer").Return(tt.TransferResponse, nil)
|
||||||
|
|
||||||
// Call the method under test
|
// Call the method under test
|
||||||
res, _ := h.InitiateNormalTransaction(ctx, "transaction_reset_amount", []byte(""))
|
res, _ := h.InitiateTransaction(ctx, "transaction_reset_amount", []byte(""))
|
||||||
|
|
||||||
// Assert that no errors occurred
|
// Assert that no errors occurred
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|||||||
@ -20,7 +20,7 @@ func (h *MenuHandlers) CheckTransactions(ctx context.Context, sym string, input
|
|||||||
}
|
}
|
||||||
|
|
||||||
flag_no_transfers, _ := h.flagManager.GetFlag("flag_no_transfers")
|
flag_no_transfers, _ := h.flagManager.GetFlag("flag_no_transfers")
|
||||||
flag_api_call_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_error")
|
||||||
|
|
||||||
userStore := h.userdataStore
|
userStore := h.userdataStore
|
||||||
logdb := h.logDb
|
logdb := h.logDb
|
||||||
@ -33,11 +33,11 @@ func (h *MenuHandlers) CheckTransactions(ctx context.Context, sym string, input
|
|||||||
// Fetch transactions from the API using the public key
|
// Fetch transactions from the API using the public key
|
||||||
transactionsResp, err := h.accountService.FetchTransactions(ctx, string(publicKey))
|
transactionsResp, err := h.accountService.FetchTransactions(ctx, string(publicKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
res.FlagSet = append(res.FlagSet, flag_api_call_error)
|
res.FlagSet = append(res.FlagSet, flag_api_error)
|
||||||
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
logg.ErrorCtxf(ctx, "failed on FetchTransactions", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
res.FlagReset = append(res.FlagReset, flag_api_call_error)
|
res.FlagReset = append(res.FlagReset, flag_api_error)
|
||||||
|
|
||||||
// Return if there are no transactions
|
// Return if there are no transactions
|
||||||
if len(transactionsResp) == 0 {
|
if len(transactionsResp) == 0 {
|
||||||
|
|||||||
@ -3,12 +3,10 @@ package application
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.defalsify.org/vise.git/db"
|
"git.defalsify.org/vise.git/db"
|
||||||
"git.defalsify.org/vise.git/resource"
|
"git.defalsify.org/vise.git/resource"
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/config"
|
|
||||||
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
"git.grassecon.net/grassrootseconomics/sarafu-vise/store"
|
||||||
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"
|
||||||
@ -17,9 +15,8 @@ import (
|
|||||||
|
|
||||||
// ManageVouchers retrieves the token holdings from the API using the "PublicKey" and
|
// ManageVouchers retrieves the token holdings from the API using the "PublicKey" and
|
||||||
// 1. 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.
|
||||||
// 2. Stores list of filtered ordered vouchers (exclude the active voucher)
|
// 2. Stores list of vouchers
|
||||||
// 3. Stores list of ordered vouchers (all vouchers)
|
// 3. updates the balance of the active voucher
|
||||||
// 4. updates the balance of the active voucher
|
|
||||||
func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []byte) (resource.Result, error) {
|
||||||
var res resource.Result
|
var res resource.Result
|
||||||
userStore := h.userdataStore
|
userStore := h.userdataStore
|
||||||
@ -32,7 +29,6 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
|
|
||||||
flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher")
|
flag_no_active_voucher, _ := h.flagManager.GetFlag("flag_no_active_voucher")
|
||||||
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
flag_api_error, _ := h.flagManager.GetFlag("flag_api_call_error")
|
||||||
flag_multiple_voucher, _ := h.flagManager.GetFlag("flag_multiple_voucher")
|
|
||||||
|
|
||||||
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
publicKey, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_PUBLIC_KEY)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -49,37 +45,10 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
res.FlagReset = append(res.FlagReset, flag_api_error)
|
res.FlagReset = append(res.FlagReset, flag_api_error)
|
||||||
|
|
||||||
if len(vouchersResp) == 0 {
|
if len(vouchersResp) == 0 {
|
||||||
// clear the current active voucher data if it exists
|
|
||||||
_, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_ACTIVE_SYM)
|
|
||||||
if err == nil {
|
|
||||||
firstVoucherMap := map[storedb.DataTyp]string{
|
|
||||||
storedb.DATA_ACTIVE_SYM: "",
|
|
||||||
storedb.DATA_ACTIVE_BAL: "",
|
|
||||||
storedb.DATA_ACTIVE_DECIMAL: "",
|
|
||||||
storedb.DATA_ACTIVE_ADDRESS: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
for key, value := range firstVoucherMap {
|
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to reset active voucher data", "key", key, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logg.InfoCtxf(ctx, "Default voucher reset")
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
|
res.FlagSet = append(res.FlagSet, flag_no_active_voucher)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// only set the flag if the user has a single voucher
|
|
||||||
if len(vouchersResp) == 1 {
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_multiple_voucher)
|
|
||||||
} else {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_multiple_voucher)
|
|
||||||
}
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_no_active_voucher)
|
res.FlagReset = append(res.FlagReset, flag_no_active_voucher)
|
||||||
|
|
||||||
// add a variable to filter out the active voucher
|
// add a variable to filter out the active voucher
|
||||||
@ -155,36 +124,7 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build stable voucher priority (lower index = higher priority)
|
// Filter out the active voucher from vouchersResp
|
||||||
stablePriority := make(map[string]int)
|
|
||||||
stableAddresses := config.StableVoucherAddresses()
|
|
||||||
for i, addr := range stableAddresses {
|
|
||||||
stablePriority[addr] = i
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper: order vouchers (stable first, priority-based)
|
|
||||||
orderVouchers := func(vouchers []dataserviceapi.TokenHoldings) []dataserviceapi.TokenHoldings {
|
|
||||||
stable := make([]dataserviceapi.TokenHoldings, 0)
|
|
||||||
nonStable := make([]dataserviceapi.TokenHoldings, 0)
|
|
||||||
|
|
||||||
for _, v := range vouchers {
|
|
||||||
if isStableVoucher(v.TokenAddress) {
|
|
||||||
stable = append(stable, v)
|
|
||||||
} else {
|
|
||||||
nonStable = append(nonStable, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.SliceStable(stable, func(i, j int) bool {
|
|
||||||
ai := stablePriority[stable[i].TokenAddress]
|
|
||||||
aj := stablePriority[stable[j].TokenAddress]
|
|
||||||
return ai < aj
|
|
||||||
})
|
|
||||||
|
|
||||||
return append(stable, nonStable...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove active voucher
|
|
||||||
filteredVouchers := make([]dataserviceapi.TokenHoldings, 0, len(vouchersResp))
|
filteredVouchers := make([]dataserviceapi.TokenHoldings, 0, len(vouchersResp))
|
||||||
for _, v := range vouchersResp {
|
for _, v := range vouchersResp {
|
||||||
if v.TokenSymbol != activeSymStr {
|
if v.TokenSymbol != activeSymStr {
|
||||||
@ -192,11 +132,8 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order remaining vouchers
|
// Store all voucher data (excluding the current active voucher)
|
||||||
orderedFilteredVouchers := orderVouchers(filteredVouchers)
|
data := store.ProcessVouchers(filteredVouchers)
|
||||||
|
|
||||||
// Process & store
|
|
||||||
data := store.ProcessVouchers(orderedFilteredVouchers)
|
|
||||||
|
|
||||||
dataMap := map[storedb.DataTyp]string{
|
dataMap := map[storedb.DataTyp]string{
|
||||||
storedb.DATA_VOUCHER_SYMBOLS: data.Symbols,
|
storedb.DATA_VOUCHER_SYMBOLS: data.Symbols,
|
||||||
@ -207,26 +144,6 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
|
|
||||||
// Write data entries
|
// Write data entries
|
||||||
for key, value := range dataMap {
|
for key, value := range dataMap {
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "Failed to write data entry for sessionId: %s", sessionId, "key", key, "error", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Order all vouchers
|
|
||||||
orderedVouchers := orderVouchers(vouchersResp)
|
|
||||||
|
|
||||||
// Process ALL vouchers (stable first)
|
|
||||||
orderedVoucherData := store.ProcessVouchers(orderedVouchers)
|
|
||||||
|
|
||||||
orderedVoucherDataMap := map[storedb.DataTyp]string{
|
|
||||||
storedb.DATA_ORDERED_VOUCHER_SYMBOLS: orderedVoucherData.Symbols,
|
|
||||||
storedb.DATA_ORDERED_VOUCHER_BALANCES: orderedVoucherData.Balances,
|
|
||||||
storedb.DATA_ORDERED_VOUCHER_DECIMALS: orderedVoucherData.Decimals,
|
|
||||||
storedb.DATA_ORDERED_VOUCHER_ADDRESSES: orderedVoucherData.Addresses,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write data entries
|
|
||||||
for key, value := range orderedVoucherDataMap {
|
|
||||||
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
|
if err := userStore.WriteEntry(ctx, sessionId, key, []byte(value)); err != nil {
|
||||||
logg.ErrorCtxf(ctx, "Failed to write data entry for sessionId: %s", sessionId, "key", key, "error", err)
|
logg.ErrorCtxf(ctx, "Failed to write data entry for sessionId: %s", sessionId, "key", key, "error", err)
|
||||||
continue
|
continue
|
||||||
@ -237,7 +154,6 @@ func (h *MenuHandlers) ManageVouchers(ctx context.Context, sym string, input []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetVoucherList fetches the list of vouchers from the store and formats them.
|
// GetVoucherList fetches the list of vouchers from the store and formats them.
|
||||||
// does not include the active voucher and is used in select_voucher and pay_debt
|
|
||||||
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)
|
sessionId, ok := ctx.Value("SessionId").(string)
|
||||||
@ -245,18 +161,8 @@ func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []b
|
|||||||
return res, fmt.Errorf("missing session")
|
return res, fmt.Errorf("missing session")
|
||||||
}
|
}
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
userStore := h.userdataStore
|
||||||
|
|
||||||
// Fetch session data
|
|
||||||
_, _, activeSym, _, _, _, err := h.getSessionData(ctx, sessionId)
|
|
||||||
if err != nil {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read vouchers from the store
|
// Read vouchers from the store
|
||||||
voucherData, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_SYMBOLS)
|
voucherData, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_SYMBOLS)
|
||||||
logg.InfoCtxf(ctx, "reading voucherData in GetVoucherList", "sessionId", sessionId, "key", storedb.DATA_VOUCHER_SYMBOLS, "voucherData", voucherData)
|
logg.InfoCtxf(ctx, "reading voucherData in GetVoucherList", "sessionId", sessionId, "key", storedb.DATA_VOUCHER_SYMBOLS, "voucherData", voucherData)
|
||||||
@ -265,16 +171,6 @@ func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []b
|
|||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(voucherData) == 0 {
|
|
||||||
if sym == "get_paydebt_voucher_list" {
|
|
||||||
res.Content = l.Get("You need another voucher to proceed. Only found %s.", string(activeSym))
|
|
||||||
} else {
|
|
||||||
res.Content = l.Get("Your active voucher %s is already set", string(activeSym))
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
voucherBalances, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_BALANCES)
|
voucherBalances, err := userStore.ReadEntry(ctx, sessionId, storedb.DATA_VOUCHER_BALANCES)
|
||||||
logg.InfoCtxf(ctx, "reading voucherBalances in GetVoucherList", "sessionId", sessionId, "key", storedb.DATA_VOUCHER_BALANCES, "voucherBalances", voucherBalances)
|
logg.InfoCtxf(ctx, "reading voucherBalances in GetVoucherList", "sessionId", sessionId, "key", storedb.DATA_VOUCHER_BALANCES, "voucherBalances", voucherBalances)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -287,7 +183,7 @@ func (h *MenuHandlers) GetVoucherList(ctx context.Context, sym string, input []b
|
|||||||
|
|
||||||
logg.InfoCtxf(ctx, "final output for GetVoucherList", "sessionId", sessionId, "finalOutput", finalOutput)
|
logg.InfoCtxf(ctx, "final output for GetVoucherList", "sessionId", sessionId, "finalOutput", finalOutput)
|
||||||
|
|
||||||
res.Content = l.Get("Select number or symbol from your vouchers:\n%s", finalOutput)
|
res.Content = finalOutput
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
@ -323,8 +219,8 @@ func (h *MenuHandlers) ViewVoucher(ctx context.Context, sym string, input []byte
|
|||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
|
if err := store.StoreTemporaryVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err)
|
logg.ErrorCtxf(ctx, "failed on StoreTemporaryVoucher", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,9 +248,9 @@ func (h *MenuHandlers) SetVoucher(ctx context.Context, sym string, input []byte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get temporary data
|
// Get temporary data
|
||||||
tempData, err := store.GetTransactionVoucherData(ctx, h.userdataStore, sessionId)
|
tempData, err := store.GetTemporaryVoucherData(ctx, h.userdataStore, sessionId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logg.ErrorCtxf(ctx, "failed on GetTransactionVoucherData", "error", err)
|
logg.ErrorCtxf(ctx, "failed on GetTemporaryVoucherData", "error", err)
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,50 +298,3 @@ func (h *MenuHandlers) GetVoucherDetails(ctx context.Context, sym string, input
|
|||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateCreditVoucher sets the selected voucher as the active transaction voucher
|
|
||||||
func (h *MenuHandlers) ValidateCreditVoucher(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")
|
|
||||||
}
|
|
||||||
|
|
||||||
code := codeFromCtx(ctx)
|
|
||||||
l := gotext.NewLocale(translationDir, code)
|
|
||||||
l.AddDomain("default")
|
|
||||||
|
|
||||||
flag_incorrect_voucher, _ := h.flagManager.GetFlag("flag_incorrect_voucher")
|
|
||||||
|
|
||||||
res.FlagReset = append(res.FlagReset, flag_incorrect_voucher)
|
|
||||||
|
|
||||||
inputStr := string(input)
|
|
||||||
if inputStr == "0" || inputStr == "99" || inputStr == "88" || inputStr == "98" {
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
userStore := h.userdataStore
|
|
||||||
metadata, err := store.GetOrderedVoucherData(ctx, userStore, sessionId, inputStr)
|
|
||||||
if err != nil {
|
|
||||||
return res, fmt.Errorf("failed to retrieve swap to voucher data: %v", err)
|
|
||||||
}
|
|
||||||
if metadata == nil {
|
|
||||||
res.FlagSet = append(res.FlagSet, flag_incorrect_voucher)
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the transaction voucher data
|
|
||||||
if err := store.StoreTransactionVoucher(ctx, h.userdataStore, sessionId, metadata); err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed on StoreTransactionVoucher", "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the state of the custom transaction voucher
|
|
||||||
err = userStore.WriteEntry(ctx, sessionId, storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE, []byte("1"))
|
|
||||||
if err != nil {
|
|
||||||
logg.ErrorCtxf(ctx, "failed to write custom transaction voucher", "key", storedb.DATA_TRANSACTION_CUSTOM_VOUCHER_STATE, "error", err)
|
|
||||||
return res, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@ -81,13 +81,11 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
|
|||||||
ls.DbRs.AddLocalFunc("check_account_status", appHandlers.CheckAccountStatus)
|
ls.DbRs.AddLocalFunc("check_account_status", appHandlers.CheckAccountStatus)
|
||||||
ls.DbRs.AddLocalFunc("authorize_account", appHandlers.Authorize)
|
ls.DbRs.AddLocalFunc("authorize_account", appHandlers.Authorize)
|
||||||
ls.DbRs.AddLocalFunc("quit", appHandlers.Quit)
|
ls.DbRs.AddLocalFunc("quit", appHandlers.Quit)
|
||||||
ls.DbRs.AddLocalFunc("calc_credit_debt", appHandlers.CalculateCreditAndDebt)
|
|
||||||
ls.DbRs.AddLocalFunc("check_balance", appHandlers.CheckBalance)
|
ls.DbRs.AddLocalFunc("check_balance", appHandlers.CheckBalance)
|
||||||
ls.DbRs.AddLocalFunc("validate_recipient", appHandlers.ValidateRecipient)
|
ls.DbRs.AddLocalFunc("validate_recipient", appHandlers.ValidateRecipient)
|
||||||
ls.DbRs.AddLocalFunc("transaction_reset", appHandlers.TransactionReset)
|
ls.DbRs.AddLocalFunc("transaction_reset", appHandlers.TransactionReset)
|
||||||
ls.DbRs.AddLocalFunc("invite_valid_recipient", appHandlers.InviteValidRecipient)
|
ls.DbRs.AddLocalFunc("invite_valid_recipient", appHandlers.InviteValidRecipient)
|
||||||
ls.DbRs.AddLocalFunc("send_max_amount", appHandlers.MaxAmount)
|
ls.DbRs.AddLocalFunc("max_amount", appHandlers.MaxAmount)
|
||||||
ls.DbRs.AddLocalFunc("credit_max_amount", appHandlers.MaxAmount)
|
|
||||||
ls.DbRs.AddLocalFunc("validate_amount", appHandlers.ValidateAmount)
|
ls.DbRs.AddLocalFunc("validate_amount", appHandlers.ValidateAmount)
|
||||||
ls.DbRs.AddLocalFunc("reset_transaction_amount", appHandlers.ResetTransactionAmount)
|
ls.DbRs.AddLocalFunc("reset_transaction_amount", appHandlers.ResetTransactionAmount)
|
||||||
ls.DbRs.AddLocalFunc("get_recipient", appHandlers.GetRecipient)
|
ls.DbRs.AddLocalFunc("get_recipient", appHandlers.GetRecipient)
|
||||||
@ -105,14 +103,12 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
|
|||||||
ls.DbRs.AddLocalFunc("get_profile_info", appHandlers.GetProfileInfo)
|
ls.DbRs.AddLocalFunc("get_profile_info", appHandlers.GetProfileInfo)
|
||||||
ls.DbRs.AddLocalFunc("verify_yob", appHandlers.VerifyYob)
|
ls.DbRs.AddLocalFunc("verify_yob", appHandlers.VerifyYob)
|
||||||
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", appHandlers.ResetIncorrectYob)
|
ls.DbRs.AddLocalFunc("reset_incorrect_date_format", appHandlers.ResetIncorrectYob)
|
||||||
ls.DbRs.AddLocalFunc("normal_transaction_preview", appHandlers.NormalTransactionPreview)
|
ls.DbRs.AddLocalFunc("initiate_transaction", appHandlers.InitiateTransaction)
|
||||||
ls.DbRs.AddLocalFunc("initiate_normal_transaction", appHandlers.InitiateNormalTransaction)
|
|
||||||
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("manage_vouchers", appHandlers.ManageVouchers)
|
ls.DbRs.AddLocalFunc("manage_vouchers", appHandlers.ManageVouchers)
|
||||||
ls.DbRs.AddLocalFunc("get_voucher_list", appHandlers.GetVoucherList)
|
ls.DbRs.AddLocalFunc("get_vouchers", appHandlers.GetVoucherList)
|
||||||
ls.DbRs.AddLocalFunc("get_paydebt_voucher_list", 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)
|
||||||
ls.DbRs.AddLocalFunc("get_voucher_details", appHandlers.GetVoucherDetails)
|
ls.DbRs.AddLocalFunc("get_voucher_details", appHandlers.GetVoucherDetails)
|
||||||
@ -140,24 +136,6 @@ func (ls *LocalHandlerService) GetHandler(accountService remote.AccountService)
|
|||||||
ls.DbRs.AddLocalFunc("swap_max_limit", appHandlers.SwapMaxLimit)
|
ls.DbRs.AddLocalFunc("swap_max_limit", appHandlers.SwapMaxLimit)
|
||||||
ls.DbRs.AddLocalFunc("swap_preview", appHandlers.SwapPreview)
|
ls.DbRs.AddLocalFunc("swap_preview", appHandlers.SwapPreview)
|
||||||
ls.DbRs.AddLocalFunc("initiate_swap", appHandlers.InitiateSwap)
|
ls.DbRs.AddLocalFunc("initiate_swap", appHandlers.InitiateSwap)
|
||||||
ls.DbRs.AddLocalFunc("transaction_swap_preview", appHandlers.TransactionSwapPreview)
|
|
||||||
ls.DbRs.AddLocalFunc("transaction_initiate_swap", appHandlers.TransactionInitiateSwap)
|
|
||||||
ls.DbRs.AddLocalFunc("clear_trans_type_flag", appHandlers.ClearTransactionTypeFlag)
|
|
||||||
ls.DbRs.AddLocalFunc("get_mpesa_max_limit", appHandlers.GetMpesaMaxLimit)
|
|
||||||
ls.DbRs.AddLocalFunc("get_mpesa_preview", appHandlers.GetMpesaPreview)
|
|
||||||
ls.DbRs.AddLocalFunc("initiate_get_mpesa", appHandlers.InitiateGetMpesa)
|
|
||||||
ls.DbRs.AddLocalFunc("send_mpesa_min_limit", appHandlers.SendMpesaMinLimit)
|
|
||||||
ls.DbRs.AddLocalFunc("send_mpesa_preview", appHandlers.SendMpesaPreview)
|
|
||||||
ls.DbRs.AddLocalFunc("initiate_send_mpesa", appHandlers.InitiateSendMpesa)
|
|
||||||
ls.DbRs.AddLocalFunc("calculate_max_pay_debt", appHandlers.CalculateMaxPayDebt)
|
|
||||||
ls.DbRs.AddLocalFunc("confirm_debt_removal", appHandlers.ConfirmDebtRemoval)
|
|
||||||
ls.DbRs.AddLocalFunc("initiate_pay_debt", appHandlers.InitiatePayDebt)
|
|
||||||
ls.DbRs.AddLocalFunc("get_ordered_vouchers", appHandlers.GetOrderedVouchers)
|
|
||||||
ls.DbRs.AddLocalFunc("pool_deposit_max_amount", appHandlers.PoolDepositMaxAmount)
|
|
||||||
ls.DbRs.AddLocalFunc("confirm_pool_deposit", appHandlers.ConfirmPoolDeposit)
|
|
||||||
ls.DbRs.AddLocalFunc("initiate_pool_deposit", appHandlers.InitiatePoolDeposit)
|
|
||||||
ls.DbRs.AddLocalFunc("validate_credit_voucher", appHandlers.ValidateCreditVoucher)
|
|
||||||
|
|
||||||
ls.first = appHandlers.Init
|
ls.first = appHandlers.Init
|
||||||
|
|
||||||
return appHandlers, nil
|
return appHandlers, nil
|
||||||
|
|||||||
@ -5,19 +5,19 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "3",
|
"input": "2",
|
||||||
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
"expectedContent": "Select number or symbol from your vouchers:\n1:SRF\n0:Back\n99:Quit"
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "Select number or symbol from your vouchers:\n1:SRF\n0:Back\n99:Quit"
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -38,15 +38,15 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "3",
|
"input": "2",
|
||||||
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
"expectedContent": "Select number or symbol from your vouchers:\n1:SRF\n0:Back\n99:Quit"
|
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "SRF",
|
"input": "SRF",
|
||||||
@ -58,7 +58,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -67,10 +67,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -95,7 +95,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -104,10 +104,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -136,7 +136,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -145,10 +145,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -177,7 +177,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -186,10 +186,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -210,7 +210,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -219,10 +219,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -235,7 +235,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -244,10 +244,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -280,7 +280,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -289,10 +289,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -325,7 +325,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -334,10 +334,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -382,7 +382,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -391,10 +391,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -419,7 +419,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -428,10 +428,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -460,7 +460,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -469,10 +469,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -497,7 +497,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -506,10 +506,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -534,7 +534,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -543,10 +543,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -571,7 +571,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -580,10 +580,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -604,7 +604,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -613,10 +613,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -49,7 +49,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -53,7 +53,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -45,7 +45,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -37,7 +37,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -41,7 +41,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -61,7 +61,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "0",
|
"input": "0",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "1",
|
"input": "1",
|
||||||
@ -86,10 +86,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "6",
|
"input": "4",
|
||||||
"expectedContent": "For more help,please call: 0757628885"
|
"expectedContent": "For more help,please call: 0757628885"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -99,7 +99,7 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "9",
|
"input": "9",
|
||||||
@ -112,10 +112,10 @@
|
|||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"input": "",
|
"input": "",
|
||||||
"expectedContent": "{balance}\n\n1:Send\n2:Swap\n3:My Vouchers\n4:Select pool\n5:My Account\n6:Help\n9:Quit"
|
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"input": "5",
|
"input": "3",
|
||||||
"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"
|
"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"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
{{.send_max_amount}}
|
Maximum amount: {{.max_amount}}
|
||||||
|
Enter amount:
|
||||||
@ -1,8 +1,7 @@
|
|||||||
LOAD reset_transaction_amount 10
|
LOAD reset_transaction_amount 0
|
||||||
RELOAD reset_transaction_amount
|
LOAD max_amount 40
|
||||||
LOAD send_max_amount 0
|
RELOAD max_amount
|
||||||
RELOAD send_max_amount
|
MAP max_amount
|
||||||
MAP send_max_amount
|
|
||||||
MOUT back 0
|
MOUT back 0
|
||||||
HALT
|
HALT
|
||||||
LOAD validate_amount 64
|
LOAD validate_amount 64
|
||||||
@ -10,7 +9,7 @@ RELOAD validate_amount
|
|||||||
CATCH api_failure flag_api_call_error 1
|
CATCH api_failure flag_api_call_error 1
|
||||||
CATCH invalid_amount flag_invalid_amount 1
|
CATCH invalid_amount flag_invalid_amount 1
|
||||||
INCMP _ 0
|
INCMP _ 0
|
||||||
LOAD get_recipient 100
|
LOAD get_recipient 0
|
||||||
LOAD get_sender 64
|
LOAD get_sender 64
|
||||||
LOAD get_amount 32
|
LOAD get_amount 32
|
||||||
INCMP transaction_pin *
|
INCMP transaction_pin *
|
||||||
|
|||||||
@ -1 +1,2 @@
|
|||||||
{{.send_max_amount}}
|
Kiwango cha juu: {{.max_amount}}
|
||||||
|
Weka kiwango:
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.calculate_max_pay_debt}}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
LOAD reset_transaction_amount 10
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MAP calculate_max_pay_debt
|
|
||||||
MOUT back 0
|
|
||||||
HALT
|
|
||||||
LOAD confirm_debt_removal 140
|
|
||||||
RELOAD confirm_debt_removal
|
|
||||||
CATCH invalid_pay_debt_amount flag_invalid_amount 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP confirm_debt_removal *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.confirm_debt_removal}}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
MAP confirm_debt_removal
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
LOAD authorize_account 6
|
|
||||||
RELOAD authorize_account
|
|
||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
INCMP initiate_pay_debt *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.credit_max_amount}}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
LOAD reset_transaction_amount 10
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
LOAD credit_max_amount 160
|
|
||||||
RELOAD credit_max_amount
|
|
||||||
CATCH api_failure flag_api_call_error 1
|
|
||||||
MAP credit_max_amount
|
|
||||||
MOUT back 0
|
|
||||||
HALT
|
|
||||||
LOAD clear_trans_type_flag 6
|
|
||||||
RELOAD clear_trans_type_flag
|
|
||||||
CATCH transaction_swap flag_swap_transaction 1
|
|
||||||
LOAD validate_amount 64
|
|
||||||
RELOAD validate_amount
|
|
||||||
CATCH invalid_amount flag_invalid_amount 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP transaction_pin *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.credit_max_amount}}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Weka nambari ya simu/anwani/lakabu:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.get_ordered_vouchers}}
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
LOAD get_ordered_vouchers 0
|
|
||||||
MAP get_ordered_vouchers
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 99
|
|
||||||
MNEXT next 88
|
|
||||||
MPREV prev 98
|
|
||||||
HALT
|
|
||||||
INCMP > 88
|
|
||||||
INCMP < 98
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 99
|
|
||||||
LOAD validate_credit_voucher 67
|
|
||||||
RELOAD validate_credit_voucher
|
|
||||||
CATCH . flag_incorrect_voucher 1
|
|
||||||
INCMP credit_amount *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Pool deposit
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Weka kwa bwawa
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.get_ordered_vouchers}}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
CATCH no_voucher flag_no_active_voucher 1
|
|
||||||
LOAD get_ordered_vouchers 0
|
|
||||||
MAP get_ordered_vouchers
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 99
|
|
||||||
MNEXT next 88
|
|
||||||
MPREV prev 98
|
|
||||||
HALT
|
|
||||||
INCMP > 88
|
|
||||||
INCMP < 98
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 99
|
|
||||||
LOAD get_mpesa_max_limit 89
|
|
||||||
RELOAD get_mpesa_max_limit
|
|
||||||
CATCH . flag_incorrect_voucher 1
|
|
||||||
CATCH low_withdraw_mpesa_amount flag_incorrect_pool 1
|
|
||||||
CATCH low_withdraw_mpesa_amount flag_low_swap_amount 1
|
|
||||||
CATCH low_withdraw_mpesa_amount flag_api_call_error 1
|
|
||||||
INCMP mpesa_max_limit *
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
{{.get_mpesa_preview}}
|
|
||||||
|
|
||||||
Please enter your PIN to confirm. You will get an SMS shortly:
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
MAP get_mpesa_preview
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
LOAD authorize_account 6
|
|
||||||
RELOAD authorize_account
|
|
||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
INCMP initiate_get_mpesa *
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
{{.get_mpesa_preview}}
|
|
||||||
|
|
||||||
Tafadhali weka PIN yako kudhibitisha. Utapokea ujumbe wa SMS:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Withdraw
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Pokea M-Pesa
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
LOAD reset_incorrect_pin 6
|
|
||||||
CATCH _ flag_account_authorized 0
|
|
||||||
LOAD initiate_get_mpesa 0
|
|
||||||
HALT
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
LOAD reset_incorrect_pin 6
|
|
||||||
CATCH _ flag_account_authorized 0
|
|
||||||
LOAD initiate_pay_debt 0
|
|
||||||
HALT
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
LOAD reset_incorrect_pin 6
|
|
||||||
CATCH _ flag_account_authorized 0
|
|
||||||
LOAD initiate_send_mpesa 0
|
|
||||||
HALT
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Amount {{.transaction_swap_preview}} is invalid, please try again:
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
MAP transaction_swap_preview
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MOUT retry 1
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP ^ 1
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiwango {{.transaction_swap_preview}} sio sahihi, tafadhali weka tena:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Amount {{.get_mpesa_preview}} is invalid, please try again:
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
MAP get_mpesa_preview
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MOUT retry 1
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 1
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiwango {{.get_mpesa_preview}} sio sahihi, tafadhali weka tena:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Amount {{.confirm_debt_removal}} is invalid, please try again:
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
MAP confirm_debt_removal
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MOUT retry 1
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 1
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiwango {{.confirm_debt_removal}} sio sahihi, tafadhali weka tena:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Amount {{.confirm_pool_deposit}} is invalid, please try again:
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
MAP confirm_pool_deposit
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MOUT retry 1
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 1
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiwango {{.confirm_pool_deposit}} sio sahihi, tafadhali weka tena:
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Amount {{.send_mpesa_preview}} is invalid, please try again:
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
MAP send_mpesa_preview
|
|
||||||
MOUT retry 1
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP ^ 1
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiwango {{.send_mpesa_preview}} sio sahihi, tafadhali weka tena:
|
|
||||||
@ -32,7 +32,7 @@ msgid "Symbol: %s\nBalance: %s"
|
|||||||
msgstr "Sarafu: %s\nSalio: %s"
|
msgstr "Sarafu: %s\nSalio: %s"
|
||||||
|
|
||||||
msgid "Your request has been sent. You will receive an SMS when your %s %s has been swapped for %s."
|
msgid "Your request has been sent. You will receive an SMS when your %s %s has been swapped for %s."
|
||||||
msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati %s %s yako itakapobadilishwa kuwa %s."
|
msgstr "Ombi lako limetumwa. Utapokea SMS wakati %s %s yako itakapobadilishwa kuwa %s."
|
||||||
|
|
||||||
msgid "%s balance: %s\n"
|
msgid "%s balance: %s\n"
|
||||||
msgstr "%s salio: %s\n"
|
msgstr "%s salio: %s\n"
|
||||||
@ -45,69 +45,3 @@ msgstr "Jina: %s\nSarafu: %s"
|
|||||||
|
|
||||||
msgid "Only USD vouchers are allowed to mpesa.sarafu.eth."
|
msgid "Only USD vouchers are allowed to mpesa.sarafu.eth."
|
||||||
msgstr "Ni sarafu za USD pekee zinazoruhusiwa kwa mpesa.sarafu.eth."
|
msgstr "Ni sarafu za USD pekee zinazoruhusiwa kwa mpesa.sarafu.eth."
|
||||||
|
|
||||||
msgid "Maximum amount: %s %s\nEnter amount:"
|
|
||||||
msgstr "Kiwango cha juu: %s %s\nWeka kiwango:"
|
|
||||||
|
|
||||||
msgid "Credit Available: %s %s\n(You can swap up to %s %s -> %s %s).\nEnter %s amount:"
|
|
||||||
msgstr "Kiwango kinachopatikana: %s %s\n(Unaweza kubadilisha hadi %s %s -> %s %s)\nWeka kiwango cha %s:"
|
|
||||||
|
|
||||||
msgid "%s will receive %s %s"
|
|
||||||
msgstr "%s atapokea %s %s"
|
|
||||||
|
|
||||||
msgid "Enter the amount of M-Pesa to get: (Max %s Ksh)\n"
|
|
||||||
msgstr "Weka kiasi cha M-Pesa cha kupata: (Kikomo %s Ksh)\n"
|
|
||||||
|
|
||||||
msgid "You are sending %s %s in order to receive ~ %s ksh"
|
|
||||||
msgstr "Unatuma ~ %s %s ili upokee %s ksh"
|
|
||||||
|
|
||||||
msgid "Your request has been sent. Please await confirmation"
|
|
||||||
msgstr "Ombi lako limetumwa. Tafadhali subiri"
|
|
||||||
|
|
||||||
msgid "Enter the amount of M-Pesa to send: (Minimum %s Ksh)\n"
|
|
||||||
msgstr "Weka kiasi cha M-Pesa cha kutuma: (Kima cha chini %s Ksh)\n"
|
|
||||||
|
|
||||||
msgid "You will get a prompt for your Mpesa PIN shortly to send %s ksh and receive ~ %s %s"
|
|
||||||
msgstr "Utapokea kidokezo cha PIN yako ya Mpesa hivi karibuni kutuma %s ksh na kupokea ~ %s %s"
|
|
||||||
|
|
||||||
msgid "Your request has been sent. Thank you for using Sarafu"
|
|
||||||
msgstr "Ombi lako limetumwa. Asante kwa kutumia huduma ya Sarafu"
|
|
||||||
|
|
||||||
msgid "You can remove a max of %s %s from '%s' pool\nEnter amount of %s:(Max: %s)"
|
|
||||||
msgstr "Unaweza kuondoa kiwango cha juu cha %s %s kutoka kwenye '%s'\n\nWeka kiwango cha %s:(Kikomo: %s)"
|
|
||||||
|
|
||||||
msgid "Please confirm that you will use %s %s to remove your debt of %s %s\nEnter your PIN:"
|
|
||||||
msgstr "Tafadhali thibitisha kwamba utatumia %s %s kulipa deni lako la %s %s.\nWeka PIN yako:"
|
|
||||||
|
|
||||||
msgid "Your active voucher %s is already set"
|
|
||||||
msgstr "Sarafu yako %s ishachaguliwa"
|
|
||||||
|
|
||||||
msgid "Select number or symbol from your vouchers:\n%s"
|
|
||||||
msgstr "Chagua nambari au ishara kutoka kwa sarafu zako:\n%s"
|
|
||||||
|
|
||||||
msgid "You will deposit %s %s into %s\n"
|
|
||||||
msgstr "Utaweka %s %s kwenye %s\n"
|
|
||||||
|
|
||||||
msgid "Your request has been sent. You will receive an SMS when %s %s has been deposited into %s."
|
|
||||||
msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati %s %s itawekwa kwenye %s."
|
|
||||||
|
|
||||||
msgid "%s will receive %s %s from %s"
|
|
||||||
msgstr %s atapokea %s %s kutoka kwa %s"
|
|
||||||
|
|
||||||
msgid "You need another voucher to proceed. Only found %s."
|
|
||||||
msgstr "Unahitaji kua na sarafu nyingine. Tumepata tu %s."
|
|
||||||
|
|
||||||
msgid "Maximum: %s %s\n\nEnter amount of %s to swap for %s:"
|
|
||||||
msgstr "Kikimo: %s %s\n\nWeka kiasi cha %s kitakacho badilishwa kua %s:"
|
|
||||||
|
|
||||||
msgid "You will swap %s %s for %s %s:"
|
|
||||||
msgstr "Utabadilisha %s %s kua %s %s:"
|
|
||||||
|
|
||||||
msgid "Your request has been sent. You will receive an SMS when your debt of %s %s has been removed from %s."
|
|
||||||
msgstr "Ombi lako limetumwa. Utapokea ujumbe wakati deni lako la %s %s litatolewa kwa %s."
|
|
||||||
|
|
||||||
msgid "Enter the amount of Mpesa to withdraw: (Min: Ksh %s, Max %s Ksh)\n"
|
|
||||||
msgstr "Weka kiasi cha Mpesa utakacho toa: (Min: Ksh %s, Max %s Ksh)\n"
|
|
||||||
|
|
||||||
msgid "Enter the amount of credit to deposit: (Minimum %s Ksh)\n"
|
|
||||||
msgstr "Weka kiasi utakacho weka (Kima cha chini: %s Ksh)\n"
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Available amount {{.calculate_max_pay_debt}} is too low, please choose a different voucher:
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
MAP calculate_max_pay_debt
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiasi kinachopatikana {{.calculate_max_pay_debt}} ni cha chini sana, tafadhali chagua sarafu tofauti:
|
|
||||||
@ -1 +1 @@
|
|||||||
Available amount {{.swap_max_limit}} is too low, please choose a different voucher:
|
Available amount {{.swap_max_limit}} is too low, please try again:
|
||||||
@ -1 +1 @@
|
|||||||
Kiasi kinachopatikana {{.swap_max_limit}} ni cha chini sana, tafadhali chagua sarafu tofauti:
|
Kiasi kinachopatikana {{.swap_max_limit}} ni cha chini sana, tafadhali jaribu tena:
|
||||||
@ -1 +0,0 @@
|
|||||||
Available amount {{.get_mpesa_max_limit}} is too low, please choose a different voucher:
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
MAP get_mpesa_max_limit
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Kiasi kinachopatikana {{.get_mpesa_max_limit}} ni cha chini sana, tafadhali chagua sarafu tofauti:
|
|
||||||
@ -3,24 +3,22 @@ RELOAD clear_temporary_value
|
|||||||
LOAD manage_vouchers 160
|
LOAD manage_vouchers 160
|
||||||
RELOAD manage_vouchers
|
RELOAD manage_vouchers
|
||||||
CATCH api_failure flag_api_call_error 1
|
CATCH api_failure flag_api_call_error 1
|
||||||
LOAD check_balance 148
|
LOAD check_balance 128
|
||||||
RELOAD check_balance
|
RELOAD check_balance
|
||||||
MAP check_balance
|
MAP check_balance
|
||||||
MOUT send 1
|
MOUT send 1
|
||||||
MOUT swap 2
|
MOUT swap 2
|
||||||
MOUT vouchers 3
|
MOUT vouchers 3
|
||||||
MOUT select_pool 4
|
MOUT select_pool 4
|
||||||
MOUT mpesa 5
|
MOUT account 5
|
||||||
MOUT account 6
|
MOUT help 6
|
||||||
MOUT help 7
|
|
||||||
MOUT quit 9
|
MOUT quit 9
|
||||||
HALT
|
HALT
|
||||||
INCMP credit_send 1
|
INCMP send 1
|
||||||
INCMP swap_to_list 2
|
INCMP swap_to_list 2
|
||||||
INCMP my_vouchers 3
|
INCMP my_vouchers 3
|
||||||
INCMP select_pool 4
|
INCMP select_pool 4
|
||||||
INCMP mpesa 5
|
INCMP my_account 5
|
||||||
INCMP my_account 6
|
INCMP help 6
|
||||||
INCMP help 7
|
|
||||||
INCMP quit 9
|
INCMP quit 9
|
||||||
INCMP . *
|
INCMP . *
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
{{.calc_credit_debt}}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
LOAD calc_credit_debt 150
|
|
||||||
RELOAD calc_credit_debt
|
|
||||||
CATCH api_failure flag_api_call_error 1
|
|
||||||
MAP calc_credit_debt
|
|
||||||
MOUT pay_debt 1
|
|
||||||
MOUT deposit 2
|
|
||||||
MOUT get_mpesa 3
|
|
||||||
MOUT send_mpesa 4
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP ^ 0
|
|
||||||
INCMP pay_debt 1
|
|
||||||
INCMP pool_deposit 2
|
|
||||||
INCMP get_mpesa 3
|
|
||||||
INCMP send_mpesa 4
|
|
||||||
INCMP quit 9
|
|
||||||
INCMP . *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.get_mpesa_max_limit}}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
LOAD reset_transaction_amount 10
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MAP get_mpesa_max_limit
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
LOAD get_mpesa_preview 90
|
|
||||||
RELOAD get_mpesa_preview
|
|
||||||
CATCH api_failure flag_api_call_error 1
|
|
||||||
CATCH invalid_get_mpesa_amount flag_invalid_amount 1
|
|
||||||
INCMP get_mpesa_confirmation *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
M-Pesa
|
|
||||||
@ -1 +0,0 @@
|
|||||||
No stable voucher found
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
INCMP ^ 0
|
|
||||||
INCMP quit 9
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Hakuna sarafu thabiti iliyopatikana
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.get_paydebt_voucher_list}}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
CATCH no_voucher flag_no_active_voucher 1
|
|
||||||
LOAD get_paydebt_voucher_list 0
|
|
||||||
MAP get_paydebt_voucher_list
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 99
|
|
||||||
MNEXT next 88
|
|
||||||
MPREV prev 98
|
|
||||||
HALT
|
|
||||||
INCMP > 88
|
|
||||||
INCMP < 98
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 99
|
|
||||||
LOAD calculate_max_pay_debt 0
|
|
||||||
RELOAD calculate_max_pay_debt
|
|
||||||
CATCH . flag_incorrect_voucher 1
|
|
||||||
CATCH low_pay_debt_amount flag_low_swap_amount 1
|
|
||||||
CATCH low_pay_debt_amount flag_api_call_error 1
|
|
||||||
INCMP calculate_max_pay_debt *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Pay debt
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Lipa deni
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.get_ordered_vouchers}}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
CATCH no_voucher flag_no_active_voucher 1
|
|
||||||
LOAD get_ordered_vouchers 0
|
|
||||||
MAP get_ordered_vouchers
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 99
|
|
||||||
MNEXT next 88
|
|
||||||
MPREV prev 98
|
|
||||||
HALT
|
|
||||||
INCMP > 88
|
|
||||||
INCMP < 98
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 99
|
|
||||||
LOAD pool_deposit_max_amount 120
|
|
||||||
RELOAD pool_deposit_max_amount
|
|
||||||
CATCH . flag_incorrect_voucher 1
|
|
||||||
INCMP pool_deposit_amount *
|
|
||||||
@ -1 +0,0 @@
|
|||||||
{{.pool_deposit_max_amount}}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
LOAD reset_transaction_amount 10
|
|
||||||
RELOAD reset_transaction_amount
|
|
||||||
MAP pool_deposit_max_amount
|
|
||||||
MOUT back 0
|
|
||||||
HALT
|
|
||||||
LOAD confirm_pool_deposit 140
|
|
||||||
RELOAD confirm_pool_deposit
|
|
||||||
CATCH invalid_pool_deposit_amount flag_invalid_amount 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP pool_deposit_confirmation *
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
{{.confirm_pool_deposit}}
|
|
||||||
Please enter your PIN to confirm:
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
MAP confirm_pool_deposit
|
|
||||||
MOUT back 0
|
|
||||||
MOUT quit 9
|
|
||||||
HALT
|
|
||||||
LOAD authorize_account 6
|
|
||||||
RELOAD authorize_account
|
|
||||||
CATCH incorrect_pin flag_incorrect_pin 1
|
|
||||||
INCMP _ 0
|
|
||||||
INCMP quit 9
|
|
||||||
INCMP pool_deposit_initiated *
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
{{.confirm_pool_deposit}}
|
|
||||||
Tafadhali weka PIN yako kudhibitisha:
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
LOAD reset_incorrect_pin 6
|
|
||||||
CATCH _ flag_account_authorized 0
|
|
||||||
LOAD initiate_pool_deposit 0
|
|
||||||
HALT
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user