[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-cashless2ecash] branch master updated: fix: taler conformant Amou
From: |
gnunet |
Subject: |
[taler-cashless2ecash] branch master updated: fix: taler conformant Amount format |
Date: |
Mon, 20 May 2024 12:00:14 +0200 |
This is an automated email from the git hooks/post-receive script.
joel-haeberli pushed a commit to branch master
in repository cashless2ecash.
The following commit(s) were added to refs/heads/master by this push:
new e6a4d68 fix: taler conformant Amount format
e6a4d68 is described below
commit e6a4d687e8290d15900c743af6538a67643b5130
Author: Joel-Haeberli <haebu@rubigen.ch>
AuthorDate: Mon May 20 12:00:07 2024 +0200
fix: taler conformant Amount format
---
cli/cli.go | 88 +++++++++++++-
cli/db.go | 1 +
cli/encoding.go | 127 +++++++++++++++++++++
cli/go.mod | 2 +
simulation/c2ec-simulation | Bin 8315978 -> 8315978
bytes
.../wallee_c2ec/client/taler/TerminalClientMock.kt | 2 +-
.../client/taler/model/TerminalsApiModel.kt | 8 +-
7 files changed, 220 insertions(+), 8 deletions(-)
diff --git a/cli/cli.go b/cli/cli.go
index fbb8ce3..e1cfc51 100644
--- a/cli/cli.go
+++ b/cli/cli.go
@@ -11,8 +11,10 @@ import (
"os"
"strconv"
"strings"
+ "time"
"github.com/jackc/pgx/v5"
+ "github.com/jackc/pgx/v5/pgxpool"
"golang.org/x/crypto/argon2"
)
@@ -22,6 +24,7 @@ const ACTION_REGISTER_PROVIDER = "rp"
const ACTION_REGISTER_TERMINAL = "rt"
const ACTION_DEACTIVATE_TERMINAL = "dt"
const ACTION_ACTIVATE_TERMINAL = "at"
+const ACTION_WITHDRAWAL_INFOMRATION = "w"
const ACTION_CONNECT_DB = "db"
const ACTION_QUIT = "q"
@@ -32,7 +35,7 @@ type WalleeCredentials struct {
ApplicationUserKey string `json:"application-user-key"`
}
-var DB *pgx.Conn
+var DB *pgxpool.Pool
// enter database credentials (host, port, database, username, password)
// register terminal -> read password, hash, save to database
@@ -235,6 +238,70 @@ func activateTerminal() error {
return nil
}
+func withdrawalInformation() error {
+
+ if DB == nil {
+ return errors.New("connect to the database first (cmd: db)")
+ }
+
+ wopid := read("WOPID (encoded): ")
+ wopidDecoded, err := decodeCrock(wopid)
+ if err != nil {
+ return err
+ }
+ rows, err := DB.Query(
+ context.Background(),
+ GET_WITHDRAWAL_BY_WOPID,
+ wopidDecoded,
+ )
+ if err != nil {
+ return err
+ }
+
+ type TalerAmountCurrency struct {
+ Val int64 `db:"val"`
+ Frac int32 `db:"frac"`
+ Curr string `db:"curr"`
+ }
+ type Withdrawal struct {
+ WithdrawalRowId uint64
`db:"withdrawal_row_id"`
+ RequestUid string `db:"request_uid"`
+ Wopid []byte `db:"wopid"`
+ ReservePubKey []byte
`db:"reserve_pub_key"`
+ RegistrationTs int64
`db:"registration_ts"`
+ Amount *TalerAmountCurrency `db:"amount"
scan:"follow"`
+ SuggestedAmount *TalerAmountCurrency
`db:"suggested_amount" scan:"follow"`
+ TerminalFees *TalerAmountCurrency `db:"terminal_fees"
scan:"follow"`
+ WithdrawalStatus string
`db:"withdrawal_status"`
+ TerminalId int `db:"terminal_id"`
+ ProviderTransactionId *string
`db:"provider_transaction_id"`
+ LastRetryTs *int64 `db:"last_retry_ts"`
+ RetryCounter int32 `db:"retry_counter"`
+ CompletionProof []byte
`db:"completion_proof"`
+ }
+
+ w, err := pgx.CollectOneRow(rows,
pgx.RowToAddrOfStructByName[Withdrawal])
+ if err != nil {
+ return err
+ }
+ rows.Close()
+
+ indent := " -"
+ fmt.Println("Withdrawal:")
+ fmt.Println(indent, "wopid :", encodeCrock(w.Wopid))
+ fmt.Println(indent, "status :", w.WithdrawalStatus)
+ fmt.Println(indent, "reserve public key:", encodeCrock(w.ReservePubKey))
+ fmt.Println(indent, "provider tid :", *w.ProviderTransactionId)
+ fmt.Println(indent, "amount :", w.Amount)
+ fmt.Println(indent, "terminal :", w.TerminalId)
+ fmt.Println(indent, "attest retries :", w.RetryCounter)
+ if w.LastRetryTs != nil {
+ fmt.Println(indent, "last retry :",
time.Unix(*w.LastRetryTs, 0).Format("yyyy-MM-dd hh:mm:ss"))
+ }
+
+ return nil
+}
+
func setupSimulation() error {
if DB == nil {
@@ -340,12 +407,13 @@ func connectDatabase() error {
}
func connectDbUsingString(connString string) error {
- dbCfg, err := pgx.ParseConfig(connString)
+ dbCfg, err := pgxpool.ParseConfig(connString)
if err != nil {
return err
}
- DB, err = pgx.ConnectConfig(context.Background(), dbCfg)
+ dbCfg.AfterConnect = registerCustomTypesHook
+ DB, err = pgxpool.NewWithConfig(context.Background(), dbCfg)
if err != nil {
return err
}
@@ -360,6 +428,7 @@ func showHelp() error {
fmt.Println("deactivate wallee terminal (", ACTION_DEACTIVATE_TERMINAL,
")")
fmt.Println("activate wallee terminal (", ACTION_ACTIVATE_TERMINAL, ")")
fmt.Println("setup simulation (", ACTION_SETUP_SIMULATION, ")")
+ fmt.Println("withdrawal information (", ACTION_WITHDRAWAL_INFOMRATION,
")")
fmt.Println("connect database (", ACTION_CONNECT_DB, ")")
fmt.Println("show help (", ACTION_HELP, ")")
fmt.Println("quit (", ACTION_QUIT, ")")
@@ -427,6 +496,8 @@ func dispatchCommand(cmd string) error {
err = deactivateTerminal()
case ACTION_ACTIVATE_TERMINAL:
err = activateTerminal()
+ case ACTION_WITHDRAWAL_INFOMRATION:
+ err = withdrawalInformation()
case ACTION_SETUP_SIMULATION:
err = setupSimulation()
default:
@@ -445,3 +516,14 @@ func read(prefix string) string {
}
return strings.Trim(inp, "\n")
}
+
+func registerCustomTypesHook(ctx context.Context, conn *pgx.Conn) error {
+
+ t, err := conn.LoadType(ctx, "c2ec.taler_amount_currency")
+ if err != nil {
+ return err
+ }
+
+ conn.TypeMap().RegisterType(t)
+ return nil
+}
diff --git a/cli/db.go b/cli/db.go
index 0297bfd..13d595f 100644
--- a/cli/db.go
+++ b/cli/db.go
@@ -6,6 +6,7 @@ const DEACTIVATE_TERMINAL = "UPDATE c2ec.terminal SET active =
false WHERE termi
const ACTIVATE_TERMINAL = "UPDATE c2ec.terminal SET active = true WHERE
terminal_id=$1"
const GET_PROVIDER_BY_NAME = "SELECT * FROM c2ec.provider WHERE name=$1"
const GET_LAST_INSERTED_TERMINAL = "SELECT * FROM c2ec.terminal WHERE
terminal_id = (SELECT MAX(terminal_id) FROM c2ec.terminal)"
+const GET_WITHDRAWAL_BY_WOPID = "SELECT * FROM c2ec.withdrawal WHERE wopid=$1"
type Provider struct {
ProviderId int64 `db:"provider_id"`
diff --git a/cli/encoding.go b/cli/encoding.go
new file mode 100644
index 0000000..9209deb
--- /dev/null
+++ b/cli/encoding.go
@@ -0,0 +1,127 @@
+package main
+
+import (
+ "errors"
+ "math"
+ "strings"
+)
+
+func talerBinaryEncode(byts []byte) string {
+
+ return encodeCrock(byts)
+}
+
+func talerBinaryDecode(str string) ([]byte, error) {
+
+ return decodeCrock(str)
+}
+
+func ParseWopid(wopid string) ([]byte, error) {
+
+ wopidBytes, err := talerBinaryDecode(wopid)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(wopidBytes) != 32 {
+ err = errors.New("invalid wopid")
+ return nil, err
+ }
+
+ return wopidBytes, nil
+}
+
+func FormatWopid(wopid []byte) string {
+
+ return talerBinaryEncode(wopid)
+}
+
+func decodeCrock(e string) ([]byte, error) {
+ size := len(e)
+ bitpos := 0
+ bitbuf := 0
+ readPosition := 0
+ outLen := int(math.Floor((float64(size) * 5.0) / 8.0))
+ out := make([]byte, outLen)
+ outPos := 0
+
+ getValue := func(c byte) (int, error) {
+ alphabet := "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
+ switch c {
+ case 'o', 'O':
+ return 0, nil
+ case 'i', 'I', 'l', 'L':
+ return 1, nil
+ case 'u', 'U':
+ return 27, nil
+ }
+
+ i := strings.IndexRune(alphabet, rune(c))
+ if i > -1 && i < 32 {
+ return i, nil
+ }
+
+ return -1, errors.New("encoding error")
+ }
+
+ for readPosition < size || bitpos > 0 {
+ if readPosition < size {
+ v, err := getValue(e[readPosition])
+ if err != nil {
+ return nil, err
+ }
+ readPosition++
+ bitbuf = bitbuf<<5 | v
+ bitpos += 5
+ }
+ for bitpos >= 8 {
+ d := byte(bitbuf >> (bitpos - 8) & 0xff)
+ out[outPos] = d
+ outPos++
+ bitpos -= 8
+ }
+ if readPosition == size && bitpos > 0 {
+ bitbuf = bitbuf << (8 - bitpos) & 0xff
+ if bitbuf == 0 {
+ bitpos = 0
+ } else {
+ bitpos = 8
+ }
+ }
+ }
+ return out, nil
+}
+
+func encodeCrock(data []byte) string {
+ out := ""
+ bitbuf := 0
+ bitpos := 0
+
+ encodeValue := func(value int) byte {
+ alphabet := "ABCDEFGHJKMNPQRSTVWXYZ"
+ switch {
+ case value >= 0 && value <= 9:
+ return byte('0' + value)
+ case value >= 10 && value <= 31:
+ return alphabet[value-10]
+ default:
+ panic("Invalid value for encoding")
+ }
+ }
+
+ for _, b := range data {
+ bitbuf = bitbuf<<8 | int(b&0xff)
+ bitpos += 8
+ for bitpos >= 5 {
+ value := bitbuf >> (bitpos - 5) & 0x1f
+ out += string(encodeValue(value))
+ bitpos -= 5
+ }
+ }
+ if bitpos > 0 {
+ bitbuf = bitbuf << (5 - bitpos)
+ value := bitbuf & 0x1f
+ out += string(encodeValue(value))
+ }
+ return out
+}
diff --git a/cli/go.mod b/cli/go.mod
index 2aa7410..c02aebc 100644
--- a/cli/go.mod
+++ b/cli/go.mod
@@ -10,6 +10,8 @@ require (
require (
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a //
indirect
+ github.com/jackc/puddle/v2 v2.2.1 // indirect
+ golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
)
diff --git a/simulation/c2ec-simulation b/simulation/c2ec-simulation
index 28b9ead..756fdf5 100755
Binary files a/simulation/c2ec-simulation and b/simulation/c2ec-simulation
differ
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
index 2c06600..a71e916 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientMock.kt
@@ -48,7 +48,7 @@ class TerminalClientMock: TerminalClient {
Optional.of(
BankWithdrawalOperationStatus(
WithdrawalOperationStatus.selected,
- Amount(10,0),
+ "CHF:10",
// Amount(10,0),
// Amount(0,0),
// Amount(0,0),
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
index dcb1dc2..007225a 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/model/TerminalsApiModel.kt
@@ -40,10 +40,10 @@ enum class WithdrawalOperationStatus(val value: String) {
data class BankWithdrawalOperationStatus(
@Json(name = "status") val status: WithdrawalOperationStatus,
- @Json(name = "amount") val amount: Amount,
-// @Json(name = "suggested_amount") val suggestedAmount: Amount,
-// @Json(name = "max_amount") val maxAmount: Amount,
-// @Json(name = "card_fees") val cardFees: Amount,
+ @Json(name = "amount") val amount: String,
+// @Json(name = "suggested_amount") val suggestedAmount: String,
+// @Json(name = "max_amount") val maxAmount: String,
+// @Json(name = "card_fees") val cardFees: String,
@Json(name = "sender_wire") val senderWire: String,
// @Json(name = "suggested_exchange") val suggestedExchange: String,
// @Json(name = "required_exchange") val requiredExchange: String,
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.