[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-cashless2ecash] branch master updated: db: database schema
From: |
gnunet |
Subject: |
[taler-cashless2ecash] branch master updated: db: database schema |
Date: |
Wed, 06 Mar 2024 21:16:35 +0100 |
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 82a397b db: database schema
82a397b is described below
commit 82a397b5ad89183b87394f16148bf143428ea853
Author: Joel-Haeberli <haebu@rubigen.ch>
AuthorDate: Wed Mar 6 21:16:23 2024 +0100
db: database schema
---
data/nonce2ecash_schema.sql | 5 +-
nonce2ecash/go.mod | 3 +
nonce2ecash/pkg/common/amount.go | 153 ++++++++++++++++++++++
nonce2ecash/pkg/common/amount_test.go | 69 ++++++++++
nonce2ecash/pkg/common/model.go | 16 +++
nonce2ecash/pkg/handler.go | 59 +++++++++
nonce2ecash/pkg/main.go | 16 +++
nonce2ecash/pkg/model.go | 21 +++
nonce2ecash/pkg/taler-bank-integration/client.go | 21 +++
nonce2ecash/pkg/taler-bank-integration/model.go | 31 +++++
nonce2ecash/pkg/taler-wirewatch-gateway/client.go | 1 +
nonce2ecash/pkg/taler-wirewatch-gateway/model.go | 1 +
specs/api-nonce2ecash.rst | 2 +-
13 files changed, 393 insertions(+), 5 deletions(-)
diff --git a/data/nonce2ecash_schema.sql b/data/nonce2ecash_schema.sql
index 932c41a..f34df8d 100644
--- a/data/nonce2ecash_schema.sql
+++ b/data/nonce2ecash_schema.sql
@@ -1,6 +1,3 @@
-
--- java -jar schemaspy-6.2.4.jar -t pgsql11 -dp ./ -hq -host localhost -port
5432 -db postgres -u local -p local -o ./nonce2ecash-erd
-
DROP TABLE IF EXISTS withdrawal;
DROP TABLE IF EXISTS terminal;
DROP TABLE IF EXISTS terminal_provider;
@@ -9,7 +6,7 @@ DROP TYPE WITHDRAWAL_OPERATION_STATUS;
CREATE TYPE WITHDRAWAL_OPERATION_STATUS AS ENUM (
'pending',
'selected',
- 'aborted',
+ 'aborted',
'confirmed'
);
diff --git a/nonce2ecash/go.mod b/nonce2ecash/go.mod
new file mode 100644
index 0000000..65d46d6
--- /dev/null
+++ b/nonce2ecash/go.mod
@@ -0,0 +1,3 @@
+module nonce2ecash
+
+go 1.22.0
diff --git a/nonce2ecash/pkg/common/amount.go b/nonce2ecash/pkg/common/amount.go
new file mode 100644
index 0000000..c9b6af5
--- /dev/null
+++ b/nonce2ecash/pkg/common/amount.go
@@ -0,0 +1,153 @@
+// This file is part of taler-go, the Taler Go implementation.
+// Copyright (C) 2022 Martin Schanzenbach
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// Taler Go is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: AGPL3.0-or-later
+
+package common
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "regexp"
+ "strconv"
+ "strings"
+)
+
+// The GNU Taler Amount object
+type Amount struct {
+
+ // The type of currency, e.g. EUR
+ Currency string
+
+ // The value (before the ".")
+ Value uint64
+
+ // The fraction (after the ".", optional)
+ Fraction uint64
+}
+
+// The maximim length of a fraction (in digits)
+const FractionalLength = 8
+
+// The base of the fraction.
+const FractionalBase = 1e8
+
+// The maximum value
+var MaxAmountValue = uint64(math.Pow(2, 52))
+
+// Create a new amount from value and fraction in a currency
+func NewAmount(currency string, value uint64, fraction uint64) Amount {
+ return Amount{
+ Currency: currency,
+ Value: value,
+ Fraction: fraction,
+ }
+}
+
+// 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) {
+ if a.Currency != b.Currency {
+ return nil, errors.New("Currency mismatch!")
+ }
+ v := a.Value
+ f := a.Fraction
+ if a.Fraction < b.Fraction {
+ v -= 1
+ f += FractionalBase
+ }
+ f -= b.Fraction
+ if v < b.Value {
+ return nil, errors.New("Amount Overflow!")
+ }
+ v -= b.Value
+ r := Amount{
+ Currency: a.Currency,
+ Value: v,
+ Fraction: f,
+ }
+ return &r, nil
+}
+
+// Add b to a and return the result.
+// Returns an error if the currencies do not match or the addition would
+// cause an overflow of the value
+func (a *Amount) Add(b Amount) (*Amount, error) {
+ if a.Currency != b.Currency {
+ return nil, errors.New("Currency mismatch!")
+ }
+ v := a.Value +
+ b.Value +
+
uint64(math.Floor((float64(a.Fraction)+float64(b.Fraction))/FractionalBase))
+
+ if v >= MaxAmountValue {
+ return nil, errors.New(fmt.Sprintf("Amount Overflow (%d >
%d)!", v, MaxAmountValue))
+ }
+ f := uint64((a.Fraction + b.Fraction) % FractionalBase)
+ r := Amount{
+ Currency: a.Currency,
+ Value: v,
+ Fraction: f,
+ }
+ return &r, nil
+}
+
+// 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)
+
+ if nil != err {
+ return nil, errors.New(fmt.Sprintf("invalid amount: %s", s))
+ }
+ tail := "0.0"
+ if len(parsed) >= 4 {
+ tail = "0." + parsed[3]
+ }
+ if len(tail) > FractionalLength+1 {
+ return nil, errors.New("fraction too long")
+ }
+ value, err := strconv.ParseUint(parsed[2], 10, 64)
+ if nil != err {
+ return nil, errors.New(fmt.Sprintf("Unable to parse value %s",
parsed[2]))
+ }
+ fractionF, err := strconv.ParseFloat(tail, 64)
+ if nil != err {
+ return nil, errors.New(fmt.Sprintf("Unable to parse fraction
%s", tail))
+ }
+ fraction := uint64(math.Round(fractionF * FractionalBase))
+ currency := parsed[1]
+ a := NewAmount(currency, value, fraction)
+ return &a, nil
+}
+
+// Check if this amount is zero
+func (a *Amount) IsZero() bool {
+ return (a.Value == 0) && (a.Fraction == 0)
+}
+
+// Returns the string representation of the amount:
<currency>:<value>[.<fraction>]
+// Omits trailing zeroes.
+func (a *Amount) String() string {
+ v := strconv.FormatUint(a.Value, 10)
+ if a.Fraction != 0 {
+ f := strconv.FormatUint(a.Fraction, 10)
+ f = strings.TrimRight(f, "0")
+ v = fmt.Sprintf("%s.%s", v, f)
+ }
+ return fmt.Sprintf("%s:%s", a.Currency, v)
+}
diff --git a/nonce2ecash/pkg/common/amount_test.go
b/nonce2ecash/pkg/common/amount_test.go
new file mode 100644
index 0000000..3a3d01a
--- /dev/null
+++ b/nonce2ecash/pkg/common/amount_test.go
@@ -0,0 +1,69 @@
+// This file is part of taler-go, the Taler Go implementation.
+// Copyright (C) 2022 Martin Schanzenbach
+//
+// 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
+// by the Free Software Foundation, either version 3 of the License,
+// or (at your option) any later version.
+//
+// Taler Go is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+//
+// SPDX-License-Identifier: AGPL3.0-or-later
+
+package common
+
+import (
+ "fmt"
+ "testing"
+)
+
+var a = Amount{
+ Currency: "EUR",
+ Value: 1,
+ Fraction: 50000000,
+}
+var b = Amount{
+ Currency: "EUR",
+ Value: 23,
+ Fraction: 70007000,
+}
+var c = Amount{
+ Currency: "EUR",
+ Value: 25,
+ Fraction: 20007000,
+}
+
+func TestAmountAdd(t *testing.T) {
+ d, err := a.Add(b)
+ if err != nil {
+ t.Errorf("Failed adding amount")
+ }
+ if c.String() != d.String() {
+ t.Errorf("Failed to add to correct amount")
+ }
+}
+
+func TestAmountSub(t *testing.T) {
+ d, err := c.Sub(b)
+ if err != nil {
+ t.Errorf("Failed substracting amount")
+ }
+ if a.String() != d.String() {
+ t.Errorf("Failed to substract to correct amount")
+ }
+}
+
+func TestAmountLarge(t *testing.T) {
+ x, err := ParseAmount("EUR:50")
+ _, err = x.Add(a)
+ if nil != err {
+ fmt.Println(err)
+ t.Errorf("Failed")
+ }
+}
diff --git a/nonce2ecash/pkg/common/model.go b/nonce2ecash/pkg/common/model.go
new file mode 100644
index 0000000..b8a67da
--- /dev/null
+++ b/nonce2ecash/pkg/common/model.go
@@ -0,0 +1,16 @@
+package common
+
+// https://docs.taler.net/core/api-common.html#hash-codes
+type WithdrawalIdentifier [32]byte
+
+// https://docs.taler.net/core/api-common.html#cryptographic-primitives
+type EddsaPublicKey [32]byte
+
+type WithdrawalOperationStatus int
+
+const (
+ PENDING WithdrawalOperationStatus = iota
+ SELECTED
+ ABORTED
+ CONFIRMED
+)
diff --git a/nonce2ecash/pkg/handler.go b/nonce2ecash/pkg/handler.go
new file mode 100644
index 0000000..ace62fc
--- /dev/null
+++ b/nonce2ecash/pkg/handler.go
@@ -0,0 +1,59 @@
+package main
+
+import (
+ "fmt"
+ http "net/http"
+ "strings"
+)
+
+const HTTP_OK = 200
+const HTTP_NO_CONTENT = 204
+const HTTP_METHOD_NOT_ALLOWED = 405
+
+func config(writer http.ResponseWriter, req *http.Request) {
+
+ if isGet(req) {
+
+ writer.Write([]byte("{\n\"\":\"\",\n\"\":\"\"\n}"))
+ writer.WriteHeader(HTTP_OK)
+ }
+
+ methodNotAllowed(writer)
+}
+
+func withdrawalOperationDispatcher(writer http.ResponseWriter, req
*http.Request) {
+
+ fmt.Printf("req.URL.Fragment: %v\n", req.URL.Fragment)
+ fmt.Printf("req.URL.RawPath: %v\n", req.URL.RawPath)
+ fmt.Printf("req.URL.Path: %v\n", req.URL.Path)
+
+ if strings.Compare("POST", strings.ToUpper(req.Method)) != 0 {
+
+ writer.WriteHeader(405)
+ return
+ }
+
+}
+
+func handleWithdrawalRegistration(writer http.ResponseWriter, req
*http.Request) {
+
+}
+
+func handlePaymentNotification(writer http.ResponseWriter, req *http.Request) {
+
+}
+
+func isGet(req *http.Request) bool {
+
+ return strings.EqualFold("GET", strings.ToUpper(req.Method))
+}
+
+func isPost(req *http.Request) bool {
+
+ return strings.EqualFold("POST", strings.ToUpper(req.Method))
+}
+
+func methodNotAllowed(writer http.ResponseWriter) {
+
+ writer.WriteHeader(405)
+}
diff --git a/nonce2ecash/pkg/main.go b/nonce2ecash/pkg/main.go
new file mode 100644
index 0000000..fc34825
--- /dev/null
+++ b/nonce2ecash/pkg/main.go
@@ -0,0 +1,16 @@
+package main
+
+import (
+ http "net/http"
+)
+
+const CONFIG_ENDPOINT = "/config"
+const WITHDRAWAL_OPERATION = "/withdrawal-operation"
+
+func main() {
+
+ http.HandleFunc(CONFIG_ENDPOINT, config)
+ http.HandleFunc(WITHDRAWAL_OPERATION, withdrawalOperationDispatcher)
+
+ http.ListenAndServe(":8080", nil)
+}
diff --git a/nonce2ecash/pkg/model.go b/nonce2ecash/pkg/model.go
new file mode 100644
index 0000000..de342ef
--- /dev/null
+++ b/nonce2ecash/pkg/model.go
@@ -0,0 +1,21 @@
+package main
+
+import "nonce2ecash/pkg/common"
+
+type Nonce2ecashConfig struct {
+ Name string `json:"name"`
+ Version string `json:"version"`
+}
+
+type WithdrawRegistration struct {
+ WithdrawalId common.WithdrawalIdentifier `json:"withdrawal_id"`
+ ReservePubKey common.EddsaPublicKey `json:"reserve_pub_key"`
+ Amount common.Amount `json:"amount"`
+ ProviderId uint64 `json:"provider_id"`
+}
+
+type PaymentNotification struct {
+ ProviderTransactionId string `json:"provider_transaction_id"`
+ Amount common.Amount `json:"amount"`
+ Fees common.Amount `json:"fees"`
+}
diff --git a/nonce2ecash/pkg/taler-bank-integration/client.go
b/nonce2ecash/pkg/taler-bank-integration/client.go
new file mode 100644
index 0000000..b329442
--- /dev/null
+++ b/nonce2ecash/pkg/taler-bank-integration/client.go
@@ -0,0 +1,21 @@
+package talerbankintegration
+
+import (
+ "errors"
+ "nonce2ecash/pkg/common"
+)
+
+// check status of withdrawal
+func withdrawalOperationStatus(id common.WithdrawalIdentifier)
(*BankWithdrawalOperationStatus, error) {
+ return nil, errors.New("not implemented yet")
+}
+
+// send parameters for reserve to exchange core.
+func withdrawalOperationCreate(reservePubKey common.EddsaPublicKey,
exchangeBaseUrl string) (*BankWithdrawalOperationPostResponse, error) {
+ return nil, errors.New("not implemented yet")
+}
+
+// abort withdrawal
+func withdrawalOperationAbort(id common.WithdrawalIdentifier) error {
+ return errors.New("not implemented yet")
+}
diff --git a/nonce2ecash/pkg/taler-bank-integration/model.go
b/nonce2ecash/pkg/taler-bank-integration/model.go
new file mode 100644
index 0000000..6e2f02b
--- /dev/null
+++ b/nonce2ecash/pkg/taler-bank-integration/model.go
@@ -0,0 +1,31 @@
+package talerbankintegration
+
+import "nonce2ecash/pkg/common"
+
+//
https://docs.taler.net/core/api-bank-integration.html#tsref-type-BankWithdrawalOperationPostRequest
+type BankWithdrawalOperationPostRequest struct {
+ ReservePub string `json:"reserve_pub"`
+ SelectedExchange string `json:"selected_exchange"`
+}
+
+//
https://docs.taler.net/core/api-bank-integration.html#tsref-type-BankWithdrawalOperationPostResponse
+type BankWithdrawalOperationPostResponse struct {
+ Status common.WithdrawalOperationStatus `json:"status"`
+ ConfirmTransferUrl string
`json:"confirm_transfer_url"`
+ TransferDone bool
`json:"transfer_done"`
+}
+
+//
https://docs.taler.net/core/api-bank-integration.html#tsref-type-BankWithdrawalOperationStatus
+type BankWithdrawalOperationStatus struct {
+ Status common.WithdrawalOperationStatus `json:"status"`
+ Amount common.Amount `json:"amount"`
+ SenderWire string
`json:"sender_wire"`
+ SuggestedExchange string
`json:"suggested_exchange"`
+ ConfirmTransferUrl string
`json:"confirm_transfer_url"`
+ WireTypes []string
`json:"wire_types"`
+ SelectedReservePub string
`json:"selected_reserve_pub"`
+ SelectedExchangeAccount string
`json:"selected_exchange_account"`
+ Aborted bool
`json:"aborted"`
+ SelectionDone bool
`json:"selection_done"`
+ TransferDone bool
`json:"transfer_done"`
+}
diff --git a/nonce2ecash/pkg/taler-wirewatch-gateway/client.go
b/nonce2ecash/pkg/taler-wirewatch-gateway/client.go
new file mode 100644
index 0000000..5c5861e
--- /dev/null
+++ b/nonce2ecash/pkg/taler-wirewatch-gateway/client.go
@@ -0,0 +1 @@
+package talerwirewatchgateway
diff --git a/nonce2ecash/pkg/taler-wirewatch-gateway/model.go
b/nonce2ecash/pkg/taler-wirewatch-gateway/model.go
new file mode 100644
index 0000000..5c5861e
--- /dev/null
+++ b/nonce2ecash/pkg/taler-wirewatch-gateway/model.go
@@ -0,0 +1 @@
+package talerwirewatchgateway
diff --git a/specs/api-nonce2ecash.rst b/specs/api-nonce2ecash.rst
index b12aa8a..f82fdf6 100644
--- a/specs/api-nonce2ecash.rst
+++ b/specs/api-nonce2ecash.rst
@@ -82,7 +82,7 @@ operation (the ``WITHDRAWAL_ID``) to interact with the
withdrawal operation and
amount?: Amount;
// Id of the provider requesting a withdrawal by nonce.
- providerId: SafeUint64;
+ provider_id: SafeUint64;
}
**Response:**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-cashless2ecash] branch master updated: db: database schema,
gnunet <=