[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-cashless2ecash] branch master updated: save commit
From: |
gnunet |
Subject: |
[taler-cashless2ecash] branch master updated: save commit |
Date: |
Thu, 30 May 2024 17:30:32 +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 7dbdc36 save commit
7dbdc36 is described below
commit 7dbdc36af26aeb940ceb9badce3c6b4e9b287019
Author: Joel-Haeberli <haebu@rubigen.ch>
AuthorDate: Thu May 30 17:30:21 2024 +0200
save commit
---
c2ec/amount_test.go | 5 ++
c2ec/api-bank-integration.go | 31 ++++---
c2ec/api-terminals.go | 22 ++---
c2ec/c2ec-config.conf | 4 +
c2ec/c2ec-config.yaml | 1 +
c2ec/config.go | 7 ++
c2ec/main.go | 8 ++
c2ec/wallee-client.go | 2 +-
simulation/amount.go | 89 ++++++++++++++++-----
simulation/c2ec-simulation | Bin 8315986 -> 8327012
bytes
simulation/config.yaml | 1 +
simulation/main.go | 3 +-
simulation/sim-terminal.go | 2 +-
simulation/sim-wallet.go | 4 +
.../client/taler/TerminalClientImplementation.kt | 1 -
.../client/taler/model/TerminalsApiModel.kt | 9 ++-
.../withdrawal/ExchangeSelectionScreen.kt | 30 ++++---
.../wallee_c2ec/withdrawal/WithdrawalViewModel.kt | 43 ++++++++--
18 files changed, 197 insertions(+), 65 deletions(-)
diff --git a/c2ec/amount_test.go b/c2ec/amount_test.go
index b335316..cb53ef8 100644
--- a/c2ec/amount_test.go
+++ b/c2ec/amount_test.go
@@ -80,6 +80,10 @@ func TestParseValid(t *testing.T) {
"CHF:23.99",
"CHF:50.35",
"USD:109992332",
+ "CHF:0.0",
+ "EUR:00.0",
+ "USD:0.00",
+ "CHF:00.00",
}
for _, a := range amnts {
@@ -100,6 +104,7 @@ func TestParseInvalid(t *testing.T) {
"EUR:452:001",
"USD:1099928583593859583332",
"CHF:4564:005",
+ "CHF:.40",
}
for _, a := range amnts {
diff --git a/c2ec/api-bank-integration.go b/c2ec/api-bank-integration.go
index e06248c..67d3192 100644
--- a/c2ec/api-bank-integration.go
+++ b/c2ec/api-bank-integration.go
@@ -54,9 +54,13 @@ type BankWithdrawalOperationPostResponse struct {
type BankWithdrawalOperationStatus struct {
Status WithdrawalOperationStatus `json:"status"`
Amount string `json:"amount"`
+ CardFees string `json:"card_fees"`
SenderWire string `json:"sender_wire"`
WireTypes []string `json:"wire_types"`
ReservePubKey EddsaPublicKey `json:"selected_reserve_pub"`
+ Aborted bool `json:"aborted"`
+ SelectionDone bool `json:"selection_done"`
+ TransferDone bool `json:"transfer_done"`
}
func bankIntegrationConfig(res http.ResponseWriter, req *http.Request) {
@@ -370,17 +374,26 @@ func formatWithdrawalOrErrorStatus(w *Withdrawal)
([]byte, int) {
LogError("bank-integration-api", err)
return nil, HTTP_INTERNAL_SERVER_ERROR
} else {
- withdrawalStatusBytes, err :=
NewJsonCodec[BankWithdrawalOperationStatus]().EncodeToBytes(&BankWithdrawalOperationStatus{
- Status: w.WithdrawalStatus,
- Amount: FormatAmount(amount,
CONFIG.Server.CurrencyFractionDigits),
- SenderWire: fmt.Sprintf("payto://%s/%d",
operator.PaytoTargetType, w.ProviderTransactionId),
- WireTypes: []string{operator.PaytoTargetType},
- ReservePubKey:
EddsaPublicKey((encodeCrock(w.ReservePubKey))),
- })
- if err != nil {
+ if fees, err := ToAmount(w.TerminalFees); err != nil {
LogError("bank-integration-api", err)
return nil, HTTP_INTERNAL_SERVER_ERROR
+ } else {
+ withdrawalStatusBytes, err :=
NewJsonCodec[BankWithdrawalOperationStatus]().EncodeToBytes(&BankWithdrawalOperationStatus{
+ Status: w.WithdrawalStatus,
+ Amount: FormatAmount(amount,
CONFIG.Server.CurrencyFractionDigits),
+ CardFees: FormatAmount(fees,
CONFIG.Server.CurrencyFractionDigits),
+ SenderWire: fmt.Sprintf("payto://%s/%d",
operator.PaytoTargetType, w.ProviderTransactionId),
+ WireTypes:
[]string{operator.PaytoTargetType},
+ ReservePubKey:
EddsaPublicKey((encodeCrock(w.ReservePubKey))),
+ Aborted: w.WithdrawalStatus == ABORTED,
+ SelectionDone: w.WithdrawalStatus == SELECTED,
+ TransferDone: w.WithdrawalStatus == CONFIRMED,
+ })
+ if err != nil {
+ LogError("bank-integration-api", err)
+ return nil, HTTP_INTERNAL_SERVER_ERROR
+ }
+ return withdrawalStatusBytes, HTTP_OK
}
- return withdrawalStatusBytes, HTTP_OK
}
}
diff --git a/c2ec/api-terminals.go b/c2ec/api-terminals.go
index d0152a2..0d75977 100644
--- a/c2ec/api-terminals.go
+++ b/c2ec/api-terminals.go
@@ -13,11 +13,12 @@ const TERMINAL_API_CHECK_WITHDRAWAL =
"/withdrawals/{wopid}/check"
const TERMINAL_API_ABORT_WITHDRAWAL = "/withdrawals/{wopid}/abort"
type TerminalConfig struct {
- Name string `json:"name"`
- Version string `json:"version"`
- ProviderName string `json:"provider_name"`
- Currency string `json:"currency"`
- WireType string `json:"wire_type"`
+ Name string `json:"name"`
+ Version string `json:"version"`
+ ProviderName string `json:"provider_name"`
+ Currency string `json:"currency"`
+ WithdrawalFees string `json:"withdrawal_fees"`
+ WireType string `json:"wire_type"`
}
type TerminalWithdrawalSetup struct {
@@ -59,11 +60,12 @@ func handleTerminalConfig(res http.ResponseWriter, req
*http.Request) {
encoder := NewJsonCodec[TerminalConfig]()
cfg, err := encoder.EncodeToBytes(&TerminalConfig{
- Name: "taler-terminal",
- Version: "0:0:0",
- ProviderName: p.Name,
- Currency: CONFIG.Server.Currency,
- WireType: p.PaytoTargetType,
+ Name: "taler-terminal",
+ Version: "0:0:0",
+ ProviderName: p.Name,
+ Currency: CONFIG.Server.Currency,
+ WithdrawalFees: CONFIG.Server.WithdrawalFees,
+ WireType: p.PaytoTargetType,
})
if err != nil {
LogError("terminals-api", err)
diff --git a/c2ec/c2ec-config.conf b/c2ec/c2ec-config.conf
index 14d9988..9728d74 100644
--- a/c2ec/c2ec-config.conf
+++ b/c2ec/c2ec-config.conf
@@ -41,6 +41,10 @@ CURRENCY = CHF
# and 0 for JPY.
CURRENCY_FRACTION_DIGITS = 2
+# Fees which are to be added to each withdrawal of the
+# payment service providers. Default: none.
+WITHDRAWAL_FEES = CHF:0.0
+
# How many retries shall be triggered, when the confirmation
# of a transaction fails (when negative, the process tries forever)
MAX_RETRIES = -1
diff --git a/c2ec/c2ec-config.yaml b/c2ec/c2ec-config.yaml
index e3350f0..5494a86 100644
--- a/c2ec/c2ec-config.yaml
+++ b/c2ec/c2ec-config.yaml
@@ -9,6 +9,7 @@ c2ec:
credit-account: "payto://IBAN/CH50030202099498" # this account must be
specified at the providers backends as well
currency: "CHF"
currency-fraction-digits: 2
+ withdrawal-fees: "CHF:0.00"
max-retries: 100
retry-delay-ms: 1000
wire-gateway:
diff --git a/c2ec/config.go b/c2ec/config.go
index 1545ccf..af0cf38 100644
--- a/c2ec/config.go
+++ b/c2ec/config.go
@@ -26,6 +26,7 @@ type C2ECServerConfig struct {
CreditAccount string `yaml:"credit-account"`
Currency string `yaml:"currency"`
CurrencyFractionDigits int
`yaml:"currency-fraction-digits"`
+ WithdrawalFees string `yaml:"withdrawal-fees"`
MaxRetries int32 `yaml:"max-retries"`
RetryDelayMs int `yaml:"retry-delay-ms"`
WireGateway C2ECWireGatewayConfig `yaml:"wire-gateway"`
@@ -189,6 +190,12 @@ func ParseIni(content []byte) (*C2ECConfig, error) {
}
cfg.Server.CurrencyFractionDigits = num
+ value, err = s.GetKey("WITHDRAWAL_FEES")
+ if err != nil {
+ return nil, err
+ }
+ cfg.Server.WithdrawalFees = value.String()
+
value, err = s.GetKey("MAX_RETRIES")
if err != nil {
return nil, err
diff --git a/c2ec/main.go b/c2ec/main.go
index 860d247..5127ed7 100644
--- a/c2ec/main.go
+++ b/c2ec/main.go
@@ -8,6 +8,7 @@ import (
http "net/http"
"os"
"os/signal"
+ "strings"
"syscall"
"time"
)
@@ -74,6 +75,13 @@ func main() {
if cfg == nil {
panic("config is nil")
}
+ a, err := ParseAmount(cfg.Server.WithdrawalFees,
cfg.Server.CurrencyFractionDigits)
+ if err != nil {
+ panic("invalid withdrawal fees amount")
+ }
+ if !strings.EqualFold(a.Currency, cfg.Server.Currency) {
+ panic("withdrawal fees currency must be same as the specified
currency")
+ }
CONFIG = *cfg
DB, err = setupDatabase(&CONFIG.Database)
diff --git a/c2ec/wallee-client.go b/c2ec/wallee-client.go
index 2fa5e15..c30293b 100644
--- a/c2ec/wallee-client.go
+++ b/c2ec/wallee-client.go
@@ -261,7 +261,7 @@ func parseCredentials(raw string, cfg *C2ECProviderConfig)
(*WalleeCredentials,
}
if !ValidPassword(cfg.Key, creds.ApplicationUserKey) {
- return nil, errors.New("invalid application user key")
+ return nil, errors.New("invalid application user key in wallee
client configuration")
}
// correct application user key.
diff --git a/simulation/amount.go b/simulation/amount.go
index c77663b..bf38b0e 100644
--- a/simulation/amount.go
+++ b/simulation/amount.go
@@ -1,5 +1,6 @@
// This file is part of taler-go, the Taler Go implementation.
// Copyright (C) 2022 Martin Schanzenbach
+// Copyright (C) 2024 Joel Häberli
//
// Taler Go is free software: you can redistribute it and/or modify it
// under the terms of the GNU Affero General Public License as published
@@ -22,7 +23,6 @@ import (
"errors"
"fmt"
"math"
- "regexp"
"strconv"
"strings"
)
@@ -40,13 +40,22 @@ type Amount struct {
Fraction uint64 `json:"fraction"`
}
-func FormatAmount(amount *Amount) string {
+func FormatAmount(amount *Amount, fractionalDigits int) string {
if amount == nil {
return ""
}
- return fmt.Sprintf("%s:%d.%d", amount.Currency, amount.Value,
amount.Fraction)
+ if amount.Currency == "" && amount.Value == 0 && amount.Fraction == 0 {
+ return ""
+ }
+
+ if amount.Fraction <= 0 {
+ return fmt.Sprintf("%s:%d", amount.Currency, amount.Value)
+ }
+
+ fractionStr := toFractionStr(int(amount.Fraction), fractionalDigits)
+ return fmt.Sprintf("%s:%d.%s", amount.Currency, amount.Value,
fractionStr)
}
// The maximim length of a fraction (in digits)
@@ -67,6 +76,31 @@ func NewAmount(currency string, value uint64, fraction
uint64) Amount {
}
}
+func toFractionStr(frac int, fractionalDigits int) string {
+
+ if fractionalDigits > 8 {
+ return ""
+ }
+
+ leadingZerosStr := ""
+ strLengthTens := int(math.Pow10(fractionalDigits - 1))
+ strLength := int(math.Log10(float64(strLengthTens)))
+ leadingZeros := 0
+ if strLengthTens > frac {
+ for i := 0; i < strLength; i++ {
+ if strLengthTens > frac {
+ leadingZeros++
+ strLengthTens = strLengthTens / 10
+ }
+ }
+ for i := 0; i < leadingZeros; i++ {
+ leadingZerosStr += "0"
+ }
+ }
+
+ return leadingZerosStr + strconv.Itoa(frac)
+}
+
// Subtract the amount b from a and return the result.
// a and b must be of the same currency and a >= b
func (a *Amount) Sub(b Amount) (*Amount, error) {
@@ -116,31 +150,44 @@ func (a *Amount) Add(b Amount) (*Amount, error) {
}
// Parses an amount string in the format <currency>:<value>[.<fraction>]
-func ParseAmount(s string) (*Amount, error) {
- re, err :=
regexp.Compile(`^\s*([-_*A-Za-z0-9]+):([0-9]+)\.?([0-9]+)?\s*$`)
- parsed := re.FindStringSubmatch(s)
+func ParseAmount(s string, fractionDigits int) (*Amount, error) {
+
+ if s == "" {
+ return &Amount{"", 0, 0}, nil
+ }
- if nil != err {
+ if !strings.Contains(s, ":") {
return nil, fmt.Errorf("invalid amount: %s", s)
}
- tail := "0.0"
- if len(parsed) >= 4 {
- tail = "0." + parsed[3]
+
+ currencyAndAmount := strings.Split(s, ":")
+ if len(currencyAndAmount) != 2 {
+ return nil, fmt.Errorf("invalid amount: %s", s)
}
- if len(tail) > FractionalLength+1 {
- return nil, errors.New("fraction too long")
+
+ currency := currencyAndAmount[0]
+ valueAndFraction := strings.Split(currencyAndAmount[1], ".")
+ if len(valueAndFraction) < 1 && len(valueAndFraction) > 2 {
+ return nil, fmt.Errorf("invalid value and fraction part in
amount %s", s)
}
- value, err := strconv.ParseUint(parsed[2], 10, 64)
- if nil != err {
- return nil, fmt.Errorf("unable to parse value %s", parsed[2])
+ value, err := strconv.Atoi(valueAndFraction[0])
+ if err != nil {
+ return nil, fmt.Errorf("invalid value in amount %s", s)
}
- fractionF, err := strconv.ParseFloat(tail, 64)
- if nil != err {
- return nil, fmt.Errorf("unable to parse fraction %s", tail)
+
+ fraction := 0
+ if len(valueAndFraction) == 2 {
+ if len(valueAndFraction[1]) > fractionDigits {
+ return nil, fmt.Errorf("invalid amount: %s expected at
max %d fractional digits", s, fractionDigits)
+ }
+ fractionInt, err := strconv.Atoi(valueAndFraction[1])
+ if err != nil {
+ return nil, fmt.Errorf("invalid fraction in amount %s",
s)
+ }
+ fraction = fractionInt
}
- fraction := uint64(math.Round(fractionF * FractionalBase))
- currency := parsed[1]
- a := NewAmount(currency, value, fraction)
+
+ a := NewAmount(currency, uint64(value), uint64(fraction))
return &a, nil
}
diff --git a/simulation/c2ec-simulation b/simulation/c2ec-simulation
index 386f74b..608d4fe 100755
Binary files a/simulation/c2ec-simulation and b/simulation/c2ec-simulation
differ
diff --git a/simulation/config.yaml b/simulation/config.yaml
index 2e52cb2..2973906 100644
--- a/simulation/config.yaml
+++ b/simulation/config.yaml
@@ -3,6 +3,7 @@ c2ec-base-url: "http://localhost:8080"
parallel-withdrawals: 1
provider-backend-payment-delay: 1000
amount: "CHF:10.05"
+fees: "CHF:0.05"
terminal-accept-card-delay: 4000
terminal-provider: "Simulation"
terminal-id: "1"
diff --git a/simulation/main.go b/simulation/main.go
index e1d6bd1..de838a9 100644
--- a/simulation/main.go
+++ b/simulation/main.go
@@ -93,7 +93,8 @@ type SimulationConfig struct {
// simulates the terminal talking to its backend system and executing
the payment.
ProviderBackendPaymentDelay int `yaml:"provider-backend-payment-delay"`
// simulates the user presenting his card to the terminal
- Amount string `yaml:"amount"`
+ Amount string `yaml:"amount"`
+ Fees string `yaml:"fees"`
TerminalAcceptCardDelay int `yaml:"terminal-accept-card-delay"`
TerminalProvider string `yaml:"terminal-provider"`
TerminalId string `yaml:"terminal-id"`
diff --git a/simulation/sim-terminal.go b/simulation/sim-terminal.go
index bbfaf62..c462d60 100644
--- a/simulation/sim-terminal.go
+++ b/simulation/sim-terminal.go
@@ -53,7 +53,7 @@ func Terminal(in chan *SimulatedPhysicalInteraction, out chan
*SimulatedPhysical
Amount: CONFIG.Amount,
SuggestedAmount: "",
ProviderTransactionId: "",
- TerminalFees: "",
+ TerminalFees: CONFIG.Fees,
RequestUid: uuid.String(),
UserUuid: "",
Lock: "",
diff --git a/simulation/sim-wallet.go b/simulation/sim-wallet.go
index c8c0f87..45e24c9 100644
--- a/simulation/sim-wallet.go
+++ b/simulation/sim-wallet.go
@@ -170,7 +170,11 @@ type BankWithdrawalOperationPostResponse struct {
type BankWithdrawalOperationStatus struct {
Status WithdrawalOperationStatus `json:"status"`
Amount string `json:"amount"`
+ CardFees string `json:"card_fees"`
SenderWire string `json:"sender_wire"`
WireTypes []string `json:"wire_types"`
ReservePubKey EddsaPublicKey `json:"selected_reserve_pub"`
+ Aborted bool `json:"aborted"`
+ SelectionDone bool `json:"selection_done"`
+ TransferDone bool `json:"transfer_done"`
}
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
index c1c8471..cb3c0e7 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/client/taler/TerminalClientImplementation.kt
@@ -17,7 +17,6 @@ import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
-import okio.IOException
import java.util.Optional
import java.util.concurrent.Executors
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 887b60d..d8a40e7 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
@@ -8,6 +8,7 @@ data class TerminalApiConfig(
@Json(name = "version") val version: String,
@Json(name = "provider_name") val providerName: String,
@Json(name = "currency") val currency: String,
+ @Json(name = "withdrawal_fees") val exchangeFees: String,
@Json(name = "wire_type") val wireType: String
)
@@ -43,7 +44,7 @@ data class BankWithdrawalOperationStatus(
@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 = "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,
@@ -51,7 +52,7 @@ data class BankWithdrawalOperationStatus(
@Json(name = "wire_types") val wireTypes: Array<String>,
@Json(name = "selected_reserve_pub") val selectedReservePub: String,
// @Json(name = "selected_exchange_acount") val selectedExchangeAccount:
String,
-// @Json(name = "aborted") val aborted: Boolean,
-// @Json(name = "selection_done") val selectionDone: Boolean,
-// @Json(name = "transfer_done") val transferDone: Boolean
+ @Json(name = "aborted") val aborted: Boolean,
+ @Json(name = "selection_done") val selectionDone: Boolean,
+ @Json(name = "transfer_done") val transferDone: Boolean
)
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
index 0385086..17331d0 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/ExchangeSelectionScreen.kt
@@ -17,27 +17,35 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import ch.bfh.habej2.wallee_c2ec.client.taler.config.TalerTerminalConfig
-val exchanges = listOf(
+var exchanges = listOf(
+
TalerTerminalConfig(
- "KUDOS Exchange (BFH)",
- "http://taler-c2ec.ti.bfh.ch",
+ "BFH Taler (CHF)",
+ "http://exchange.chf.taler.net/terminals",
"Wallee-3",
"YHrpzeHUyybGT5gOY9VAiZ7QAV/icOXtHPRKZTXv2n8="
),
TalerTerminalConfig(
- "CHF Exchange (PostFinance)",
- "https://taler-c2ec.ti.bfh.ch",
- "Wallee-2",
- "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U="
+ "BFH Taler (CHF, https)",
+ "https://exchange.chf.taler.net/terminals",
+ "Wallee-3",
+ "YHrpzeHUyybGT5gOY9VAiZ7QAV/icOXtHPRKZTXv2n8="
),
TalerTerminalConfig(
- "EUR Exchange (UBS)",
+ "Test System Joel (CHF)",
"http://taler-c2ec.ti.bfh.ch",
- "Wallee-2",
- "1A92pgloFR8WIgr0LDA+s9hbkO4EgyJlHj+3dQ9IJ9U="
- )
+ "Wallee-3",
+ "YHrpzeHUyybGT5gOY9VAiZ7QAV/icOXtHPRKZTXv2n8="
+ ),
+
+ TalerTerminalConfig(
+ "Test System Joel (CHF, https)",
+ "https://taler-c2ec.ti.bfh.ch",
+ "Wallee-3",
+ "YHrpzeHUyybGT5gOY9VAiZ7QAV/icOXtHPRKZTXv2n8="
+ ),
)
@Composable
diff --git
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
index dac8f33..9ab347b 100644
---
a/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
+++
b/wallee-c2ec/app/src/main/java/ch/bfh/habej2/wallee_c2ec/withdrawal/WithdrawalViewModel.kt
@@ -56,7 +56,7 @@ object TalerConstants {
const val TALER_INTEGRATION_WITHDRAWAL_OPERATION = "/withdrawal-operation"
fun formatTalerUri(terminalsApiBasePath: String, encodedWopid: String) =
-
"taler://withdraw/$terminalsApiBasePath$TALER_INTEGRATION_WITHDRAWAL_OPERATION/$encodedWopid"
+
"taler://withdraw/$terminalsApiBasePath$TALER_INTEGRATION$TALER_INTEGRATION_WITHDRAWAL_OPERATION/$encodedWopid"
}
@Stable
@@ -68,6 +68,7 @@ interface WithdrawalOperationState {
val amountStr: String
val amountError: String
val currency: String
+ val withdrawalFees: Amount
val transactionState: TransactionState
val transaction: TransactionResponse?
val transactionCompletion: TransactionCompletionResponse?
@@ -92,6 +93,7 @@ private class MutableWithdrawalOperationState :
WithdrawalOperationState {
override var amountStr: String by mutableStateOf("")
override var amountError: String by mutableStateOf("")
override var currency: String by mutableStateOf("")
+ override var withdrawalFees: Amount by mutableStateOf(Amount(0,0,""))
override var transactionState: TransactionState by
mutableStateOf(TransactionState.AUTHORIZATION_PENDING)
override var transaction: TransactionResponse? by mutableStateOf(null)
override var transactionCompletion: TransactionCompletionResponse? by
mutableStateOf(null)
@@ -137,6 +139,9 @@ class WithdrawalViewModel(
_uiState.value.terminalsApiBasePath =
"${cfg.terminalApiBaseUrl}${TalerConstants.TALER_INTEGRATION}"
this@WithdrawalViewModel.updateCurrency(it.get().currency)
+ if
(!this@WithdrawalViewModel.updateWithdrawalFees(it.get().exchangeFees)) {
+ activity.finish()
+ }
}
}
exchangeSelected = true
@@ -186,6 +191,18 @@ class WithdrawalViewModel(
_uiState.value.currency = currency
}
+ private fun updateWithdrawalFees(exchangeFees: String): Boolean {
+
+ val optRes = this.parseAmount(exchangeFees)
+ if (!optRes.isPresent) {
+ return false
+ }
+
+ _uiState.value.withdrawalFees = optRes.get()
+
+ return true
+ }
+
fun setAuthorizing() {
_uiState.value.transactionState =
TransactionState.AUTHORIZATION_STARTED
}
@@ -321,18 +338,32 @@ class WithdrawalViewModel(
fun validAmount(inp: String) = Regex("\\d+(\\.\\d+)?").matches(inp)
/**
- * Format expected X[.X], X an integer
+ * Format expected [CURRENCY:]X[.X], X an integer
*/
private fun parseAmount(inp: String): Optional<Amount> {
- val points = inp.count { it == '.' }
+ var currency = ""
+ var valueFraction = ""
+ if (inp.contains(":")) {
+ val splitted = inp.split(":")
+ currency = splitted[0]
+ if (currency != uiState.value.currency) {
+ println("illegal currency $currency. expected
${uiState.value.currency}")
+ return Optional.empty()
+ }
+ valueFraction = splitted[1]
+ } else {
+ valueFraction = inp
+ }
+
+ val points = valueFraction.count { it == '.' }
if (points > 1) {
return Optional.empty()
}
if (points == 1) {
- val valueStr = inp.split(".")[0]
- val fracStr = inp.split(".")[1]
+ val valueStr = valueFraction.split(".")[0]
+ val fracStr = valueFraction.split(".")[1]
return try {
val value = valueStr.toInt()
var frac = 0
@@ -347,7 +378,7 @@ class WithdrawalViewModel(
}
return try {
- val value = inp.toInt()
+ val value = valueFraction.toInt()
Optional.of(Amount(value, 0, uiState.value.currency))
} catch (ex: NumberFormatException) {
println(ex.message)
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.