gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taldir] 02/02: go fmt


From: gnunet
Subject: [taler-taldir] 02/02: go fmt
Date: Mon, 18 Jul 2022 12:55:24 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository taldir.

commit 194002465a2502bdf2ec815289d00b97757f9973
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Mon Jul 18 12:55:18 2022 +0200

    go fmt
---
 cmd/taldir-cli/main.go         |   75 ++-
 cmd/taldir-server/main.go      |   32 +-
 cmd/taldir-server/main_test.go |  428 +++++++-------
 pkg/rest/taldir.go             | 1224 ++++++++++++++++++++--------------------
 pkg/taler/merchant.go          |  233 ++++----
 pkg/util/helper.go             |   94 ++-
 6 files changed, 1033 insertions(+), 1053 deletions(-)

diff --git a/cmd/taldir-cli/main.go b/cmd/taldir-cli/main.go
index 3aa9c32..83ba368 100644
--- a/cmd/taldir-cli/main.go
+++ b/cmd/taldir-cli/main.go
@@ -16,52 +16,51 @@
 //
 // SPDX-License-Identifier: AGPL3.0-or-later
 
-
 package main
 
 import (
-  "os"
-  "fmt"
-  "flag"
-  "taler.net/taldir/pkg/rest"
-  "taler.net/taldir/pkg/util"
-  gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
-  "crypto/sha512"
+       "crypto/sha512"
+       "flag"
+       "fmt"
+       gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
+       "os"
+       "taler.net/taldir/pkg/rest"
+       "taler.net/taldir/pkg/util"
 )
 
 // Generates a link from a challenge and address
 func generateLink(host string, addr string, challenge string) string {
-  h := sha512.New()
-  h.Write([]byte(addr))
-  h_addr := gnunetutil.EncodeBinaryToString(h.Sum(nil))
-  return host + "/register/" + h_addr + "/" + challenge
+       h := sha512.New()
+       h.Write([]byte(addr))
+       h_addr := gnunetutil.EncodeBinaryToString(h.Sum(nil))
+       return host + "/register/" + h_addr + "/" + challenge
 }
 
 func main() {
-  var solveFlag = flag.Bool("s", false, "Provide a solution for the 
challenge/pubkey")
-  var linkFlag = flag.Bool("l", false, "Provide a link for activation")
-  var challengeFlag = flag.String("c", "", "Activation challenge")
-  var pubkeyFlag = flag.String("p", "", "Public key")
-  var addressFlag = flag.String("a", "", "Address")
-  flag.Parse()
-  cfgfile := "taldir.conf"
-  t := taldir.Taldir{}
-  t.Initialize(cfgfile)
-  host := t.Cfg.Section("taldir").Key("host").MustString("http://localhost";)
-  if *solveFlag {
-    if len(*challengeFlag) == 0 || len(*pubkeyFlag) == 0 {
-      fmt.Println("You need to provide an activation challenge and a public 
key to generate a solution")
-      os.Exit(1)
-    }
-    fmt.Println(util.GenerateSolution(*pubkeyFlag, *challengeFlag))
-    os.Exit(0)
-  }
-  if *linkFlag {
-    if len(*challengeFlag) == 0 || len(*addressFlag) == 0 {
-      fmt.Println("You need to provide an activation challenge and an address 
to generate a link")
-      os.Exit(1)
-    }
-    fmt.Println(generateLink(host, *addressFlag, *challengeFlag))
-    os.Exit(0)
-  }
+       var solveFlag = flag.Bool("s", false, "Provide a solution for the 
challenge/pubkey")
+       var linkFlag = flag.Bool("l", false, "Provide a link for activation")
+       var challengeFlag = flag.String("c", "", "Activation challenge")
+       var pubkeyFlag = flag.String("p", "", "Public key")
+       var addressFlag = flag.String("a", "", "Address")
+       flag.Parse()
+       cfgfile := "taldir.conf"
+       t := taldir.Taldir{}
+       t.Initialize(cfgfile)
+       host := 
t.Cfg.Section("taldir").Key("host").MustString("http://localhost";)
+       if *solveFlag {
+               if len(*challengeFlag) == 0 || len(*pubkeyFlag) == 0 {
+                       fmt.Println("You need to provide an activation 
challenge and a public key to generate a solution")
+                       os.Exit(1)
+               }
+               fmt.Println(util.GenerateSolution(*pubkeyFlag, *challengeFlag))
+               os.Exit(0)
+       }
+       if *linkFlag {
+               if len(*challengeFlag) == 0 || len(*addressFlag) == 0 {
+                       fmt.Println("You need to provide an activation 
challenge and an address to generate a link")
+                       os.Exit(1)
+               }
+               fmt.Println(generateLink(host, *addressFlag, *challengeFlag))
+               os.Exit(0)
+       }
 }
diff --git a/cmd/taldir-server/main.go b/cmd/taldir-server/main.go
index 6f0b400..9d1a1f6 100644
--- a/cmd/taldir-server/main.go
+++ b/cmd/taldir-server/main.go
@@ -16,7 +16,6 @@
 //
 // SPDX-License-Identifier: AGPL3.0-or-later
 
-
 package main
 
 /* TODO
@@ -28,27 +27,28 @@ package main
 */
 
 import (
-  "flag"
-  "net/http"
-  "log"
-  "taler.net/taldir/pkg/rest"
+       "flag"
+       "log"
+       "net/http"
+
+       taldir "taler.net/taldir/pkg/rest"
 )
 
 var t taldir.Taldir
 
 func handleRequests() {
-  
log.Fatal(http.ListenAndServe(t.Cfg.Section("taldir").Key("bind_to").MustString("localhost:11000"),
 t.Router))
+       
log.Fatal(http.ListenAndServe(t.Cfg.Section("taldir").Key("bind_to").MustString("localhost:11000"),
 t.Router))
 }
 
 func main() {
-  var cfgFlag = flag.String("c", "", "Configuration file to use")
-
-  flag.Parse()
-  cfgfile := "taldir.conf"
-  if len(*cfgFlag) != 0 {
-    cfgfile = *cfgFlag
-  }
-  t := taldir.Taldir{}
-  t.Initialize(cfgfile)
-  handleRequests()
+       var cfgFlag = flag.String("c", "", "Configuration file to use")
+
+       flag.Parse()
+       cfgfile := "taldir.conf"
+       if len(*cfgFlag) != 0 {
+               cfgfile = *cfgFlag
+       }
+       t := taldir.Taldir{}
+       t.Initialize(cfgfile)
+       handleRequests()
 }
diff --git a/cmd/taldir-server/main_test.go b/cmd/taldir-server/main_test.go
index a61e425..ec475c8 100644
--- a/cmd/taldir-server/main_test.go
+++ b/cmd/taldir-server/main_test.go
@@ -16,23 +16,22 @@
 //
 // SPDX-License-Identifier: AGPL3.0-or-later
 
-
 package main_test
 
 import (
-  "os"
-  "testing"
-  "net/http"
-  "net/http/httptest"
-  "crypto/sha512"
-  "bytes"
-  "strings"
-  "io/ioutil"
-  "taler.net/taldir/pkg/rest"
-  _ "taler.net/taldir/cmd/taldir-server"
-  gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
-  "github.com/jarcoal/httpmock"
-  "taler.net/taldir/pkg/util"
+       "bytes"
+       "crypto/sha512"
+       gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
+       "github.com/jarcoal/httpmock"
+       "io/ioutil"
+       "net/http"
+       "net/http/httptest"
+       "os"
+       "strings"
+       _ "taler.net/taldir/cmd/taldir-server"
+       "taler.net/taldir/pkg/rest"
+       "taler.net/taldir/pkg/util"
+       "testing"
 )
 
 var t taldir.Taldir
@@ -70,253 +69,248 @@ var newOrderStatusUnpaidMockResponse = `
   }
 `
 
-
-
-
 func TestMain(m *testing.M) {
-  t.Initialize("testdata/taldir-test.conf")
-  code := m.Run()
-  t.ClearDatabase()
-  os.Exit(code)
+       t.Initialize("testdata/taldir-test.conf")
+       code := m.Run()
+       t.ClearDatabase()
+       os.Exit(code)
 }
 
 func getHAddress(addr string) string {
-  h := sha512.New()
-  h.Write([]byte(addr))
-  return gnunetutil.EncodeBinaryToString(h.Sum(nil))
+       h := sha512.New()
+       h.Write([]byte(addr))
+       return gnunetutil.EncodeBinaryToString(h.Sum(nil))
 }
 
 func TestNoEntry(s *testing.T) {
-    t.ClearDatabase()
+       t.ClearDatabase()
 
-    h_addr := getHAddress("jdoe@example.com")
-    req, _ := http.NewRequest("GET", "/" + h_addr, nil)
-    response := executeRequest(req)
+       h_addr := getHAddress("jdoe@example.com")
+       req, _ := http.NewRequest("GET", "/"+h_addr, nil)
+       response := executeRequest(req)
 
-    if http.StatusNotFound != response.Code {
-      s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, 
response.Code)
-    }
+       if http.StatusNotFound != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusNotFound, response.Code)
+       }
 }
 
 func executeRequest(req *http.Request) *httptest.ResponseRecorder {
-  rr := httptest.NewRecorder()
-  t.Router.ServeHTTP(rr, req)
-  return rr
+       rr := httptest.NewRecorder()
+       t.Router.ServeHTTP(rr, req)
+       return rr
 }
 
 func TestRegisterRequest(s *testing.T) {
-  t.ClearDatabase()
-
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
-
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  file, err := os.Open("validation_code")
-  if err != nil {
-    s.Errorf("No validation code file found!\n")
-  }
-  code, err := ioutil.ReadAll(file)
-  if err != nil {
-    s.Errorf("Error reading validation code file contents!\n")
-  }
-  h_addr := getHAddress("abc@test")
-  trimCode := strings.Trim(string(code), " \r\n")
-  solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 trimCode)
-  solutionJSON := "{\"solution\": \"" + solution + "\"}"
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusNoContent != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, 
response.Code)
-  }
+       t.ClearDatabase()
+
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
+
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       file, err := os.Open("validation_code")
+       if err != nil {
+               s.Errorf("No validation code file found!\n")
+       }
+       code, err := ioutil.ReadAll(file)
+       if err != nil {
+               s.Errorf("Error reading validation code file contents!\n")
+       }
+       h_addr := getHAddress("abc@test")
+       trimCode := strings.Trim(string(code), " \r\n")
+       solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 trimCode)
+       solutionJSON := "{\"solution\": \"" + solution + "\"}"
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusNoContent != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusNoContent, response.Code)
+       }
 }
 
 func TestRegisterQRPageRequest(s *testing.T) {
-  t.ClearDatabase()
-
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
-
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  req, _ = http.NewRequest("GET", "/register/NonSenseAddr/NonSenseCode", nil)
-  response = executeRequest(req)
-  if http.StatusNotFound != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, 
response.Code)
-  }
-
-  file, err := os.Open("validation_code")
-  if err != nil {
-    s.Errorf("No validation code file found!\n")
-  }
-  code, err := ioutil.ReadAll(file)
-  if err != nil {
-    s.Errorf("Error reading validation code file contents!\n")
-  }
-  h_addr := getHAddress("abc@test")
-  trimCode := strings.Trim(string(code), " \r\n")
-  req, _ = http.NewRequest("GET", "/register/" + h_addr + "/" + trimCode, nil)
-  response = executeRequest(req)
-  if http.StatusOK != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, 
response.Code)
-  }
+       t.ClearDatabase()
+
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
+
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       req, _ = http.NewRequest("GET", "/register/NonSenseAddr/NonSenseCode", 
nil)
+       response = executeRequest(req)
+       if http.StatusNotFound != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusNotFound, response.Code)
+       }
+
+       file, err := os.Open("validation_code")
+       if err != nil {
+               s.Errorf("No validation code file found!\n")
+       }
+       code, err := ioutil.ReadAll(file)
+       if err != nil {
+               s.Errorf("Error reading validation code file contents!\n")
+       }
+       h_addr := getHAddress("abc@test")
+       trimCode := strings.Trim(string(code), " \r\n")
+       req, _ = http.NewRequest("GET", "/register/"+h_addr+"/"+trimCode, nil)
+       response = executeRequest(req)
+       if http.StatusOK != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, 
response.Code)
+       }
 }
 
-
 func TestReRegisterRequest(s *testing.T) {
-  t.ClearDatabase()
-
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
-
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  file, err := os.Open("validation_code")
-  if err != nil {
-    s.Errorf("No validation code file found!\n")
-  }
-  code, err := ioutil.ReadAll(file)
-  if err != nil {
-    s.Errorf("Error reading validation code file contents!\n")
-  }
-  h_addr := getHAddress("abc@test")
-  trimCode := strings.Trim(string(code), " \r\n")
-  solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 trimCode)
-  solutionJSON := "{\"solution\": \"" + solution + "\"}"
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusNoContent != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusNoContent, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequestUnmodified))
-  response = executeRequest(req)
-
-  if http.StatusOK != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, 
response.Code)
-  }
+       t.ClearDatabase()
+
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
+
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       file, err := os.Open("validation_code")
+       if err != nil {
+               s.Errorf("No validation code file found!\n")
+       }
+       code, err := ioutil.ReadAll(file)
+       if err != nil {
+               s.Errorf("Error reading validation code file contents!\n")
+       }
+       h_addr := getHAddress("abc@test")
+       trimCode := strings.Trim(string(code), " \r\n")
+       solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 trimCode)
+       solutionJSON := "{\"solution\": \"" + solution + "\"}"
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusNoContent != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusNoContent, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequestUnmodified))
+       response = executeRequest(req)
+
+       if http.StatusOK != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", http.StatusOK, 
response.Code)
+       }
 
 }
 
 func TestReRegisterRequestTooMany(s *testing.T) {
-  t.ClearDatabase()
+       t.ClearDatabase()
 
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
 
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response = executeRequest(req)
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response = executeRequest(req)
 
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response = executeRequest(req)
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response = executeRequest(req)
 
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response = executeRequest(req)
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response = executeRequest(req)
 
-  if http.StatusTooManyRequests != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", 
http.StatusTooManyRequests, response.Code)
-  }
+       if http.StatusTooManyRequests != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusTooManyRequests, response.Code)
+       }
 
 }
 
 func TestSolutionRequestTooMany(s *testing.T) {
-  t.ClearDatabase()
-
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
-
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  h_addr := getHAddress("abc@test")
-  solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 "wrongSolution")
-  solutionJSON := "{\"solution\": \"" + solution + "\"}"
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusForbidden != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusForbidden != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusForbidden != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, 
response.Code)
-  }
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusTooManyRequests != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", 
http.StatusTooManyRequests, response.Code)
-  }
+       t.ClearDatabase()
+
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
+
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       h_addr := getHAddress("abc@test")
+       solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946A90",
 "wrongSolution")
+       solutionJSON := "{\"solution\": \"" + solution + "\"}"
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusForbidden != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusForbidden, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusForbidden != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusForbidden, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusForbidden != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusForbidden, response.Code)
+       }
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusTooManyRequests != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusTooManyRequests, response.Code)
+       }
 
 }
 
 func TestRegisterRequestWrongPubkey(s *testing.T) {
-  t.ClearDatabase()
-
-  req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
-
-  if http.StatusAccepted != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusAccepted, 
response.Code)
-  }
-  file, err := os.Open("validation_code")
-  if err != nil {
-    s.Errorf("No validation code file found!\n")
-  }
-  code, err := ioutil.ReadAll(file)
-  if err != nil {
-    s.Errorf("Error reading validation code file contents!\n")
-  }
-  h_addr := getHAddress("abc@test")
-  trimCode := strings.Trim(string(code), " \r\n")
-  solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946AA0",
 trimCode)
-  solutionJSON := "{\"solution\": \"" + solution + "\"}"
-  req, _ = http.NewRequest("POST", "/" + h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
-  response = executeRequest(req)
-  if http.StatusForbidden != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusForbidden, 
response.Code)
-  }
+       t.ClearDatabase()
+
+       req, _ := http.NewRequest("POST", "/register/test", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
+
+       if http.StatusAccepted != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusAccepted, response.Code)
+       }
+       file, err := os.Open("validation_code")
+       if err != nil {
+               s.Errorf("No validation code file found!\n")
+       }
+       code, err := ioutil.ReadAll(file)
+       if err != nil {
+               s.Errorf("Error reading validation code file contents!\n")
+       }
+       h_addr := getHAddress("abc@test")
+       trimCode := strings.Trim(string(code), " \r\n")
+       solution := 
util.GenerateSolution("000G006XE97PTWV3B7AJNCRQZA6BF26HPV3XZ07293FMY7KD4181946AA0",
 trimCode)
+       solutionJSON := "{\"solution\": \"" + solution + "\"}"
+       req, _ = http.NewRequest("POST", "/"+h_addr, 
bytes.NewBuffer([]byte(solutionJSON)))
+       response = executeRequest(req)
+       if http.StatusForbidden != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusForbidden, response.Code)
+       }
 }
 
-
 func TestUnsupportedMethod(s *testing.T) {
-  t.ClearDatabase()
+       t.ClearDatabase()
 
-  req, _ := http.NewRequest("POST", "/register/email", 
bytes.NewBuffer(validRegisterRequest))
-  response := executeRequest(req)
+       req, _ := http.NewRequest("POST", "/register/email", 
bytes.NewBuffer(validRegisterRequest))
+       response := executeRequest(req)
 
-  if http.StatusNotFound != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", http.StatusNotFound, 
response.Code)
-  }
+       if http.StatusNotFound != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusNotFound, response.Code)
+       }
 }
 
 func TestPaymentRequiredMethod(s *testing.T) {
-  t.ClearDatabase()
-  t.MonthlyFee = "KUDOS:5"
-  httpmock.Activate()
-  defer httpmock.DeactivateAndReset()
-  req, _ := http.NewRequest("POST", "/register/test-cost", 
bytes.NewBuffer(validRegisterRequest))
-  httpmock.RegisterResponder("POST", 
"http://merchant.taldir/instances/myInstance/private/orders";, 
httpmock.NewStringResponder(200, newOrderMockResponse))
-  httpmock.RegisterResponder("GET", 
"http://merchant.taldir/instances/myInstance/private/orders/testOrder1234";, 
httpmock.NewStringResponder(200, newOrderStatusUnpaidMockResponse))
-
-  response := executeRequest(req)
-  t.MonthlyFee = "KUDOS:0"
-  if http.StatusPaymentRequired != response.Code {
-    s.Errorf("Expected response code %d. Got %d\n", 
http.StatusPaymentRequired, response.Code)
-  }
+       t.ClearDatabase()
+       t.MonthlyFee = "KUDOS:5"
+       httpmock.Activate()
+       defer httpmock.DeactivateAndReset()
+       req, _ := http.NewRequest("POST", "/register/test-cost", 
bytes.NewBuffer(validRegisterRequest))
+       httpmock.RegisterResponder("POST", 
"http://merchant.taldir/instances/myInstance/private/orders";, 
httpmock.NewStringResponder(200, newOrderMockResponse))
+       httpmock.RegisterResponder("GET", 
"http://merchant.taldir/instances/myInstance/private/orders/testOrder1234";, 
httpmock.NewStringResponder(200, newOrderStatusUnpaidMockResponse))
+
+       response := executeRequest(req)
+       t.MonthlyFee = "KUDOS:0"
+       if http.StatusPaymentRequired != response.Code {
+               s.Errorf("Expected response code %d. Got %d\n", 
http.StatusPaymentRequired, response.Code)
+       }
 }
diff --git a/pkg/rest/taldir.go b/pkg/rest/taldir.go
index 160d1d8..afe23d9 100644
--- a/pkg/rest/taldir.go
+++ b/pkg/rest/taldir.go
@@ -19,137 +19,134 @@
 package taldir
 
 /* TODO
- - ToS compression
- - ToS etag
+- ToS compression
+- ToS etag
 */
 
 import (
-  "os"
-  "os/exec"
-  "time"
-  "fmt"
-  "log"
-  "io/ioutil"
-  "mime"
-  "net/http"
-  "html/template"
-  "encoding/json"
-  "github.com/gorilla/mux"
-  "gorm.io/gorm"
-  "gorm.io/gorm/logger"
-  "encoding/base64"
-  "taler.net/taldir/pkg/util"
-  "taler.net/taldir/pkg/gana"
-  "taler.net/taldir/pkg/taler"
-  "crypto/sha512"
-  "gorm.io/driver/postgres"
-  "gopkg.in/ini.v1"
-  "strings"
-  "github.com/skip2/go-qrcode"
-  gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
-  "golang.org/x/text/language"
+       "crypto/sha512"
+       "encoding/base64"
+       "encoding/json"
+       "fmt"
+       gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
+       "github.com/gorilla/mux"
+       "github.com/skip2/go-qrcode"
+       "golang.org/x/text/language"
+       "gopkg.in/ini.v1"
+       "gorm.io/driver/postgres"
+       "gorm.io/gorm"
+       "gorm.io/gorm/logger"
+       "html/template"
+       "io/ioutil"
+       "log"
+       "mime"
+       "net/http"
+       "os"
+       "os/exec"
+       "strings"
+       "taler.net/taldir/pkg/gana"
+       "taler.net/taldir/pkg/taler"
+       "taler.net/taldir/pkg/util"
+       "time"
 )
 
 // Taldir is the primary object of the Taldir service
 type Taldir struct {
 
-  // The main router
-  Router *mux.Router
+       // The main router
+       Router *mux.Router
 
-  // The main DB handle
-  Db *gorm.DB
+       // The main DB handle
+       Db *gorm.DB
 
-  // Our configuration from the config.json
-  Cfg *ini.File
+       // Our configuration from the config.json
+       Cfg *ini.File
 
-  // Map of supported validators as defined in the configuration
-  Validators map[string]bool
+       // Map of supported validators as defined in the configuration
+       Validators map[string]bool
 
-  // landing page
-  ValidationTpl *template.Template
+       // landing page
+       ValidationTpl *template.Template
 
-  // The address salt
-  Salt string
+       // The address salt
+       Salt string
 
-  // The timeframe for the validation requests
-  ValidationTimeframe time.Duration
+       // The timeframe for the validation requests
+       ValidationTimeframe time.Duration
 
-  // How often may a challenge be requested
-  ValidationInitiationMax int64
+       // How often may a challenge be requested
+       ValidationInitiationMax int64
 
-  // How often may a solution be attempted (in the given timeframe)
-  SolutionAttemptsMax int
+       // How often may a solution be attempted (in the given timeframe)
+       SolutionAttemptsMax int
 
-  // The timeframe for the above solution attempts
-  SolutionTimeframe time.Duration
+       // The timeframe for the above solution attempts
+       SolutionTimeframe time.Duration
 
+       // Challenge length in bytes before encoding
+       ChallengeBytes int
 
-  // Challenge length in bytes before encoding
-  ChallengeBytes int
+       // Merchant object
+       Merchant taler.Merchant
 
-  // Merchant object
-  Merchant taler.Merchant
-
-  // Monthly fee amount
-  MonthlyFee string
+       // Monthly fee amount
+       MonthlyFee string
 }
 
 // VersionResponse is the JSON response of the /config enpoint
 type VersionResponse struct {
-  // libtool-style representation of the Merchant protocol version, see
-  // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
-  // The format is "current:revision:age".
-  Version string `json:"version"`
-
-  // Name of the protocol.
-  Name string `json:"name"` // "taler-directory"
+       // libtool-style representation of the Merchant protocol version, see
+       // 
https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+       // The format is "current:revision:age".
+       Version string `json:"version"`
 
-  // Supported registration methods
-  Methods []Method `json:"methods"`
+       // Name of the protocol.
+       Name string `json:"name"` // "taler-directory"
 
-  // fee for one month of registration
-  MonthlyFee string `json:"monthly_fee"`
+       // Supported registration methods
+       Methods []Method `json:"methods"`
 
+       // fee for one month of registration
+       MonthlyFee string `json:"monthly_fee"`
 }
 
 // Method is part of the VersionResponse and contains a supported validator
 type Method struct {
 
-  // Name of the method, e.g. "email" or "sms".
-  Name string `json:"name"`
-
-  // per challenge fee
-  ChallengeFee string `json:"challenge_fee"`
+       // Name of the method, e.g. "email" or "sms".
+       Name string `json:"name"`
 
+       // per challenge fee
+       ChallengeFee string `json:"challenge_fee"`
 }
 
 // RateLimitedResponse is the JSON response when a rate limit is hit
 type RateLimitedResponse struct {
 
-  // Taler error code, TALER_EC_TALDIR_REGISTER_RATE_LIMITED.
-  Code int `json:"code"`
+       // Taler error code, TALER_EC_TALDIR_REGISTER_RATE_LIMITED.
+       Code int `json:"code"`
 
-  // At what frequency are new registrations allowed. FIXME: In what? 
Currently: In microseconds
-  RequestFrequency int64 `json:"request_frequency"`
+       // At what frequency are new registrations allowed. FIXME: In what? 
Currently: In microseconds
+       RequestFrequency int64 `json:"request_frequency"`
 
-  // The human readable error message.
-  Hint string `json:"hint"`
+       // The human readable error message.
+       Hint string `json:"hint"`
 }
 
 // RegisterMessage is the JSON paylaod when a registration is requested
 type RegisterMessage struct {
 
-  // Address, in method-specific format
-  Address string `json:"address"`
+       // Address, in method-specific format
+       Address string `json:"address"`
 
-  // Public key of the user to register
-  PublicKey string `json:"public_key"`
+       // Public key of the user to register
+       PublicKey string `json:"public_key"`
 
-  // (HTTPS) endpoint URL for the inbox service for this address
-  Inbox string `json:"inbox_url"`
+       // (HTTPS) endpoint URL for the inbox service for this address
+       Inbox string `json:"inbox_url"`
 
-  // For how long should the registration last
-  Duration int64 `json:"duration"`
+       // For how long should the registration last
+       Duration int64 `json:"duration"`
 }
 
 // Entry is a mapping from the identity key hash to a wallet key
@@ -157,20 +154,20 @@ type RegisterMessage struct {
 // one of the identity key types supported (e.g. an email address)
 type entry struct {
 
-  // ORM
-  gorm.Model  `json:"-"`
+       // ORM
+       gorm.Model `json:"-"`
 
-  // The salted hash (SHA512) of the hashed address (h_address)
-  HsAddress string `json:"-"`
+       // The salted hash (SHA512) of the hashed address (h_address)
+       HsAddress string `json:"-"`
 
-  // (HTTPS) endpoint URL for the inbox service for this address
-  Inbox string `json:"inbox_url"`
+       // (HTTPS) endpoint URL for the inbox service for this address
+       Inbox string `json:"inbox_url"`
 
-  // Public key of the user to register in base32
-  PublicKey string `json:"public_key"`
+       // Public key of the user to register in base32
+       PublicKey string `json:"public_key"`
 
-  // How long the registration lasts in microseconds
-  Duration time.Duration `json:"-"`
+       // How long the registration lasts in microseconds
+       Duration time.Duration `json:"-"`
 }
 
 // Validation is the object created when a registration for an entry is 
initiated.
@@ -179,86 +176,85 @@ type entry struct {
 // depending on the out-of-band chennel defined through the identity key type.
 type validation struct {
 
-  // ORM
-  gorm.Model `json:"-"`
+       // ORM
+       gorm.Model `json:"-"`
 
-  // The hash (SHA512) of the address
-  HAddress string `json:"h_address"`
+       // The hash (SHA512) of the address
+       HAddress string `json:"h_address"`
 
-  // For how long should the registration last
-  Duration int64 `json:"duration"`
+       // For how long should the registration last
+       Duration int64 `json:"duration"`
 
-  // (HTTPS) endpoint URL for the inbox service for this address
-  Inbox string `json:"inbox_url"`
+       // (HTTPS) endpoint URL for the inbox service for this address
+       Inbox string `json:"inbox_url"`
 
-  // The activation code sent to the client
-  Challenge string `json:"-"`
+       // The activation code sent to the client
+       Challenge string `json:"-"`
 
-  // The challenge has been sent already
-  ChallengeSent bool `json:"-"`
+       // The challenge has been sent already
+       ChallengeSent bool `json:"-"`
 
-  // Public key of the user to register
-  PublicKey string `json:"public_key"`
+       // Public key of the user to register
+       PublicKey string `json:"public_key"`
 
-  // How often was a solution for this validation tried
-  SolutionAttemptCount int
+       // How often was a solution for this validation tried
+       SolutionAttemptCount int
 
-  // The beginning of the last solution timeframe
-  LastSolutionTimeframeStart time.Time
+       // The beginning of the last solution timeframe
+       LastSolutionTimeframeStart time.Time
 
-  // The order ID associated with this validation
-  OrderID string `json:"-"`
+       // The order ID associated with this validation
+       OrderID string `json:"-"`
 }
 
-
 // ErrorDetail is the detailed error payload returned from Taldir endpoints
 type ErrorDetail struct {
 
-  // Numeric error code unique to the condition.
-  // The other arguments are specific to the error value reported here.
-  Code int `json:"code"`
+       // Numeric error code unique to the condition.
+       // The other arguments are specific to the error value reported here.
+       Code int `json:"code"`
 
-  // Human-readable description of the error, i.e. "missing parameter", 
"commitment violation", ...
-  // Should give a human-readable hint about the error's nature. Optional, may 
change without notice!
-  Hint string `json:"hint,omitempty"`
+       // Human-readable description of the error, i.e. "missing parameter", 
"commitment violation", ...
+       // Should give a human-readable hint about the error's nature. 
Optional, may change without notice!
+       Hint string `json:"hint,omitempty"`
 
-  // Optional detail about the specific input value that failed. May change 
without notice!
-  Detail string `json:"detail,omitempty"`
+       // Optional detail about the specific input value that failed. May 
change without notice!
+       Detail string `json:"detail,omitempty"`
 
-  // Name of the parameter that was bogus (if applicable).
-  Parameter string `json:"parameter,omitempty"`
+       // Name of the parameter that was bogus (if applicable).
+       Parameter string `json:"parameter,omitempty"`
 
-  // Path to the argument that was bogus (if applicable).
-  Path string `json:"path,omitempty"`
+       // Path to the argument that was bogus (if applicable).
+       Path string `json:"path,omitempty"`
 
-  // Offset of the argument that was bogus (if applicable).
-  Offset string `json:"offset,omitempty"`
+       // Offset of the argument that was bogus (if applicable).
+       Offset string `json:"offset,omitempty"`
 
-  // Index of the argument that was bogus (if applicable).
-  Index string `json:"index,omitempty"`
+       // Index of the argument that was bogus (if applicable).
+       Index string `json:"index,omitempty"`
 
-  // Name of the object that was bogus (if applicable).
-  Object string `json:"object,omitempty"`
+       // Name of the object that was bogus (if applicable).
+       Object string `json:"object,omitempty"`
 
-  // Name of the currency than was problematic (if applicable).
-  Currency string `json:"currency,omitempty"`
+       // Name of the currency than was problematic (if applicable).
+       Currency string `json:"currency,omitempty"`
 
-  // Expected type (if applicable).
-  TypeExpected string `json:"type_expected,omitempty"`
+       // Expected type (if applicable).
+       TypeExpected string `json:"type_expected,omitempty"`
 
-  // Type that was provided instead (if applicable).
-  TypeActual string `json:"type_actual,omitempty"`
+       // Type that was provided instead (if applicable).
+       TypeActual string `json:"type_actual,omitempty"`
 }
 
 // ValidationConfirmation is the payload sent by the client t complete a
 // registration.
 type ValidationConfirmation struct {
-  // The solution is the SHA-512 hash of the challenge value
-  // chosen by TalDir (encoded as string just as given in the URL, but
-  // excluding the 0-termination) concatenated with the binary 32-byte
-  // value representing the wallet's EdDSA public key.
-  // The hash is provided as string in Crockford base32 encoding.
-  Solution string `json:"solution"`
+       // The solution is the SHA-512 hash of the challenge value
+       // chosen by TalDir (encoded as string just as given in the URL, but
+       // excluding the 0-termination) concatenated with the binary 32-byte
+       // value representing the wallet's EdDSA public key.
+       // The hash is provided as string in Crockford base32 encoding.
+       Solution string `json:"solution"`
 }
 
 // NOTE: Go stores durations as nanoseconds. TalDir usually operates on 
microseconds
@@ -267,520 +263,518 @@ const monthDurationUs = 2592000000000
 // 1 Month as Go duration
 const monthDuration = time.Duration(monthDurationUs * 1000)
 
-
 // Primary lookup function.
 // Allows the caller to query a wallet key using the hash(!) of the
 // identity, e.g. SHA512(<email address>)
-func (t *Taldir) getSingleEntry(w http.ResponseWriter, r *http.Request){
-  vars := mux.Vars(r)
-  var entry entry
-  hsAddress := saltHAddress(vars["h_address"], t.Salt)
-  var err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
-  if err == nil {
-    w.Header().Set("Content-Type", "application/json")
-    resp, _ := json.Marshal(entry)
-    w.Write(resp)
-    return
-  }
-  w.WriteHeader(http.StatusNotFound)
+func (t *Taldir) getSingleEntry(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       var entry entry
+       hsAddress := saltHAddress(vars["h_address"], t.Salt)
+       var err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
+       if err == nil {
+               w.Header().Set("Content-Type", "application/json")
+               resp, _ := json.Marshal(entry)
+               w.Write(resp)
+               return
+       }
+       w.WriteHeader(http.StatusNotFound)
 }
 
 // Hashes an identity key (e.g. sha256(<email address>)) with a salt for
 // Lookup and storage.
 func saltHAddress(hAddress string, salt string) string {
-  h := sha512.New()
-  h.Write([]byte(hAddress))
-  h.Write([]byte(salt))
-  return gnunetutil.EncodeBinaryToString(h.Sum(nil))
+       h := sha512.New()
+       h.Write([]byte(hAddress))
+       h.Write([]byte(salt))
+       return gnunetutil.EncodeBinaryToString(h.Sum(nil))
 }
 
 // Called by the registrant to validate the registration request. The 
reference ID was
 // provided "out of band" using a validation method such as email or SMS
-func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request){
-  vars := mux.Vars(r)
-  var entry entry
-  var validation validation
-  var confirm ValidationConfirmation
-  var errDetail ErrorDetail
-  if r.Body == nil {
-    http.Error(w, "No request body", 400)
-    return
-  }
-  err := json.NewDecoder(r.Body).Decode(&confirm)
-  if err != nil {
-    errDetail.Code = 1006 //TALER_EC_JSON_INVALID
-    errDetail.Hint = "Unable to parse JSON"
-    resp, _ := json.Marshal(errDetail)
-    w.WriteHeader(400)
-    w.Write(resp)
-    return
-  }
-  err = t.Db.First(&validation, "h_address = ?", vars["h_address"]).Error
-  if err != nil {
-    w.WriteHeader(http.StatusNotFound)
-    return
-  }
-  validation.SolutionAttemptCount++
-  if 
validation.LastSolutionTimeframeStart.Add(t.SolutionTimeframe).After(time.Now())
 {
-    if validation.SolutionAttemptCount > t.SolutionAttemptsMax {
-      w.WriteHeader(429)
-      return
-    }
-  } else {
-    log.Println("New solution timeframe set.")
-    validation.LastSolutionTimeframeStart = time.Now()
-    validation.SolutionAttemptCount = 1
-  }
-  t.Db.Save(&validation)
-  expectedSolution := util.GenerateSolution(validation.PublicKey, 
validation.Challenge)
-  if confirm.Solution != expectedSolution {
-    w.WriteHeader(http.StatusForbidden)
-    return
-  }
-  err = t.Db.Delete(&validation).Error
-  if err != nil {
-    log.Fatalf("Error deleting validation")
-    w.WriteHeader(http.StatusInternalServerError)
-    return
-  }
-  entry.HsAddress = saltHAddress(validation.HAddress, t.Salt)
-  entry.Inbox = validation.Inbox
-  tmpDuration := (entry.Duration.Microseconds() + validation.Duration) * 1000
-  entry.Duration = time.Duration(tmpDuration)
-  entry.PublicKey = validation.PublicKey
-  err = t.Db.First(&entry, "hs_address = ?", entry.HsAddress).Error
-  if err == nil {
-    t.Db.Save(&entry)
-  } else {
-    err = t.Db.Create(&entry).Error
-    if err != nil {
-      w.WriteHeader(http.StatusInternalServerError)
-      return
-    }
-  }
-  w.WriteHeader(http.StatusNoContent)
+func (t *Taldir) validationRequest(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       var entry entry
+       var validation validation
+       var confirm ValidationConfirmation
+       var errDetail ErrorDetail
+       if r.Body == nil {
+               http.Error(w, "No request body", 400)
+               return
+       }
+       err := json.NewDecoder(r.Body).Decode(&confirm)
+       if err != nil {
+               errDetail.Code = 1006 //TALER_EC_JSON_INVALID
+               errDetail.Hint = "Unable to parse JSON"
+               resp, _ := json.Marshal(errDetail)
+               w.WriteHeader(400)
+               w.Write(resp)
+               return
+       }
+       err = t.Db.First(&validation, "h_address = ?", vars["h_address"]).Error
+       if err != nil {
+               w.WriteHeader(http.StatusNotFound)
+               return
+       }
+       validation.SolutionAttemptCount++
+       if 
validation.LastSolutionTimeframeStart.Add(t.SolutionTimeframe).After(time.Now())
 {
+               if validation.SolutionAttemptCount > t.SolutionAttemptsMax {
+                       w.WriteHeader(429)
+                       return
+               }
+       } else {
+               log.Println("New solution timeframe set.")
+               validation.LastSolutionTimeframeStart = time.Now()
+               validation.SolutionAttemptCount = 1
+       }
+       t.Db.Save(&validation)
+       expectedSolution := util.GenerateSolution(validation.PublicKey, 
validation.Challenge)
+       if confirm.Solution != expectedSolution {
+               w.WriteHeader(http.StatusForbidden)
+               return
+       }
+       err = t.Db.Delete(&validation).Error
+       if err != nil {
+               log.Fatalf("Error deleting validation")
+               w.WriteHeader(http.StatusInternalServerError)
+               return
+       }
+       entry.HsAddress = saltHAddress(validation.HAddress, t.Salt)
+       entry.Inbox = validation.Inbox
+       tmpDuration := (entry.Duration.Microseconds() + validation.Duration) * 
1000
+       entry.Duration = time.Duration(tmpDuration)
+       entry.PublicKey = validation.PublicKey
+       err = t.Db.First(&entry, "hs_address = ?", entry.HsAddress).Error
+       if err == nil {
+               t.Db.Save(&entry)
+       } else {
+               err = t.Db.Create(&entry).Error
+               if err != nil {
+                       w.WriteHeader(http.StatusInternalServerError)
+                       return
+               }
+       }
+       w.WriteHeader(http.StatusNoContent)
 }
 
 func (t *Taldir) isRateLimited(hAddress string) (bool, error) {
-  var validations []validation
-  res := t.Db.Where("h_address = ?", hAddress).Find(&validations)
-  // NOTE: Check rate limit
-  if res.Error == nil {
-    // Limit re-initiation attempts to ValidationInitiationMax times
-    // within the expiration timeframe of a validation.
-    return res.RowsAffected >= t.ValidationInitiationMax, nil
-  }
-  return false, nil
+       var validations []validation
+       res := t.Db.Where("h_address = ?", hAddress).Find(&validations)
+       // NOTE: Check rate limit
+       if res.Error == nil {
+               // Limit re-initiation attempts to ValidationInitiationMax times
+               // within the expiration timeframe of a validation.
+               return res.RowsAffected >= t.ValidationInitiationMax, nil
+       }
+       return false, nil
 }
 
-func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request){
-  vars := mux.Vars(r)
-  var req RegisterMessage
-  var errDetail ErrorDetail
-  var validation validation
-  var entry entry
-  // Check if this validation method is supported or not.
-  if !t.Validators[vars["method"]] {
-    errDetail.Code = gana.TALDIR_METHOD_NOT_SUPPORTED
-    errDetail.Hint = "Unsupported method"
-    errDetail.Detail = "Given method: " + vars["method"]
-    resp, _ := json.Marshal(errDetail)
-    w.WriteHeader(http.StatusNotFound)
-    w.Write(resp)
-    return
-  }
-  if r.Body == nil {
-    http.Error(w, "No request body", 400)
-    return
-  }
-  err := json.NewDecoder(r.Body).Decode(&req)
-  if err != nil {
-    errDetail.Code = gana.GENERIC_JSON_INVALID
-    errDetail.Hint = "Unable to parse JSON"
-    resp, _ := json.Marshal(errDetail)
-    w.WriteHeader(400)
-    w.Write(resp)
-    return
-  }
-
-  // Setup validation object. Retrieve object from DB if it already
-  // exists.
-  h := sha512.New()
-  h.Write([]byte(req.Address))
-  hAddress := gnunetutil.EncodeBinaryToString(h.Sum(nil))
-  validation.HAddress = hAddress
-  hsAddress := saltHAddress(validation.HAddress, t.Salt)
-  err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
-  // Round to the nearest multiple of a month
-  reqDuration := time.Duration(req.Duration * 1000)
-  reqDuration = reqDuration.Round(monthDuration)
-  if err == nil {
-    // Check if  this entry is to be modified or extended
-    entryModified := (req.Inbox != entry.Inbox) ||
-                     (req.PublicKey != entry.PublicKey)
-    entryValidity := entry.CreatedAt.Add(entry.Duration)
-    // NOTE: The extension must be at least one month
-    if (reqDuration.Microseconds() == 0) && !entryModified {
-      // Nothing changed. Return validity
-      w.WriteHeader(http.StatusOK)
-      w.Header().Set("Content-Type", "application/json")
-      w.Write([]byte(fmt.Sprintf("{\"valid_for\": %d}", 
time.Until(entryValidity).Microseconds())))
-      return
-    }
-  }
-  rateLimited, err := t.isRateLimited(hAddress)
-  if nil != err {
-    log.Printf("Error checking rate limit! %w", err)
-    w.WriteHeader(http.StatusInternalServerError)
-    return
-  } else if rateLimited {
-    w.WriteHeader(http.StatusTooManyRequests)
-    rlResponse := RateLimitedResponse{
-      Code: gana.TALDIR_REGISTER_RATE_LIMITED,
-      RequestFrequency: t.ValidationTimeframe.Microseconds() / 
t.ValidationInitiationMax,
-      Hint: "Registration rate limit reached",
-    }
-    jsonResp, _ := json.Marshal(rlResponse)
-    w.Write(jsonResp)
-    t.Db.Delete(&validation)
-    return
-  }
-  err = t.Db.First(&validation, "h_address = ? AND public_key = ? AND inbox = 
? AND duration = ?",
-                                hAddress, req.PublicKey, req.Inbox, 
reqDuration).Error
-  validationExists := (nil == err)
-  // FIXME: Always set new challenge?
-  validation.Challenge = util.GenerateChallenge(t.ChallengeBytes)
-  if !validationExists {
-    validation.Inbox = req.Inbox
-    validation.PublicKey = req.PublicKey
-    validation.SolutionAttemptCount = 0
-    validation.LastSolutionTimeframeStart = time.Now()
-    validation.Duration = reqDuration.Microseconds()
-  }
-
-  fixedCost := t.Cfg.Section("taldir-" + 
vars["method"]).Key("challenge_fee").MustString("KUDOS:0")
-  sliceDuration := time.Duration(validation.Duration * 1000)
-  cost, err := util.CalculateCost(t.MonthlyFee,
-                                  fixedCost,
-                                  sliceDuration,
-                                  monthDuration)
-  if err != nil {
-    fmt.Println(err)
-    w.WriteHeader(http.StatusInternalServerError)
-    return
-  }
-  if !cost.IsZero() {
-    if len(validation.OrderID) == 0 {
-      // Add new order for new validations
-      orderID, newOrderErr := t.Merchant.AddNewOrder(*cost)
-      if newOrderErr != nil {
-        fmt.Println(newOrderErr)
-        w.WriteHeader(http.StatusInternalServerError)
-        return
-      }
-      validation.OrderID = orderID
-    }
-
-    // Check if order paid.
-    // FIXME: Remember that it was activated and paid
-    payto, paytoErr := t.Merchant.IsOrderPaid(validation.OrderID)
-    if paytoErr != nil {
-      fmt.Println(paytoErr)
-      w.WriteHeader(http.StatusInternalServerError)
-      log.Println(paytoErr)
-      return
-    }
-    if len(payto) != 0 {
-      t.Db.Save(&validation)
-      w.WriteHeader(http.StatusPaymentRequired)
-      w.Header().Set("Taler", payto) // FIXME no idea what to do with this.
-      return
-    }
-    // In this case, this order was paid
-  }
-  if validationExists {
-    err = t.Db.Save(&validation).Error
-  } else {
-    err = t.Db.Create(&validation).Error
-  }
-  if err != nil {
-    log.Println(err)
-    w.WriteHeader(500)
-    return
-  }
-  // Some validation methods are costly
-  // Require explicit whitelisting for a resend.
-  if validation.ChallengeSent &&
-     !t.Cfg.Section("taldir-" + 
vars["method"]).Key("allow_resend").MustBool(false) {
-    w.WriteHeader(202)
-    return
-  }
-  if !t.Cfg.Section("taldir-" + vars["method"]).HasKey("command") {
-    log.Fatal(err)
-    t.Db.Delete(&validation)
-    w.WriteHeader(500)
-    return
-  }
-  command := t.Cfg.Section("taldir-" + vars["method"]).Key("command").String()
-  path, err := exec.LookPath(command)
-  if err != nil {
-    log.Println(err)
-    t.Db.Delete(&validation)
-    w.WriteHeader(500)
-    return
-  }
-  out, err := exec.Command(path, req.Address, validation.Challenge).Output()
-  if err != nil {
-    log.Printf("%s, %w", out, err)
-    t.Db.Delete(&validation)
-    w.WriteHeader(500)
-    return
-  }
-  validation.ChallengeSent = true
-  w.WriteHeader(202)
+func (t *Taldir) registerRequest(w http.ResponseWriter, r *http.Request) {
+       vars := mux.Vars(r)
+       var req RegisterMessage
+       var errDetail ErrorDetail
+       var validation validation
+       var entry entry
+       // Check if this validation method is supported or not.
+       if !t.Validators[vars["method"]] {
+               errDetail.Code = gana.TALDIR_METHOD_NOT_SUPPORTED
+               errDetail.Hint = "Unsupported method"
+               errDetail.Detail = "Given method: " + vars["method"]
+               resp, _ := json.Marshal(errDetail)
+               w.WriteHeader(http.StatusNotFound)
+               w.Write(resp)
+               return
+       }
+       if r.Body == nil {
+               http.Error(w, "No request body", 400)
+               return
+       }
+       err := json.NewDecoder(r.Body).Decode(&req)
+       if err != nil {
+               errDetail.Code = gana.GENERIC_JSON_INVALID
+               errDetail.Hint = "Unable to parse JSON"
+               resp, _ := json.Marshal(errDetail)
+               w.WriteHeader(400)
+               w.Write(resp)
+               return
+       }
+
+       // Setup validation object. Retrieve object from DB if it already
+       // exists.
+       h := sha512.New()
+       h.Write([]byte(req.Address))
+       hAddress := gnunetutil.EncodeBinaryToString(h.Sum(nil))
+       validation.HAddress = hAddress
+       hsAddress := saltHAddress(validation.HAddress, t.Salt)
+       err = t.Db.First(&entry, "hs_address = ?", hsAddress).Error
+       // Round to the nearest multiple of a month
+       reqDuration := time.Duration(req.Duration * 1000)
+       reqDuration = reqDuration.Round(monthDuration)
+       if err == nil {
+               // Check if  this entry is to be modified or extended
+               entryModified := (req.Inbox != entry.Inbox) ||
+                       (req.PublicKey != entry.PublicKey)
+               entryValidity := entry.CreatedAt.Add(entry.Duration)
+               // NOTE: The extension must be at least one month
+               if (reqDuration.Microseconds() == 0) && !entryModified {
+                       // Nothing changed. Return validity
+                       w.WriteHeader(http.StatusOK)
+                       w.Header().Set("Content-Type", "application/json")
+                       w.Write([]byte(fmt.Sprintf("{\"valid_for\": %d}", 
time.Until(entryValidity).Microseconds())))
+                       return
+               }
+       }
+       rateLimited, err := t.isRateLimited(hAddress)
+       if nil != err {
+               log.Printf("Error checking rate limit! %w", err)
+               w.WriteHeader(http.StatusInternalServerError)
+               return
+       } else if rateLimited {
+               w.WriteHeader(http.StatusTooManyRequests)
+               rlResponse := RateLimitedResponse{
+                       Code:             gana.TALDIR_REGISTER_RATE_LIMITED,
+                       RequestFrequency: t.ValidationTimeframe.Microseconds() 
/ t.ValidationInitiationMax,
+                       Hint:             "Registration rate limit reached",
+               }
+               jsonResp, _ := json.Marshal(rlResponse)
+               w.Write(jsonResp)
+               t.Db.Delete(&validation)
+               return
+       }
+       err = t.Db.First(&validation, "h_address = ? AND public_key = ? AND 
inbox = ? AND duration = ?",
+               hAddress, req.PublicKey, req.Inbox, reqDuration).Error
+       validationExists := (nil == err)
+       // FIXME: Always set new challenge?
+       validation.Challenge = util.GenerateChallenge(t.ChallengeBytes)
+       if !validationExists {
+               validation.Inbox = req.Inbox
+               validation.PublicKey = req.PublicKey
+               validation.SolutionAttemptCount = 0
+               validation.LastSolutionTimeframeStart = time.Now()
+               validation.Duration = reqDuration.Microseconds()
+       }
+
+       fixedCost := t.Cfg.Section("taldir-" + 
vars["method"]).Key("challenge_fee").MustString("KUDOS:0")
+       sliceDuration := time.Duration(validation.Duration * 1000)
+       cost, err := util.CalculateCost(t.MonthlyFee,
+               fixedCost,
+               sliceDuration,
+               monthDuration)
+       if err != nil {
+               fmt.Println(err)
+               w.WriteHeader(http.StatusInternalServerError)
+               return
+       }
+       if !cost.IsZero() {
+               if len(validation.OrderID) == 0 {
+                       // Add new order for new validations
+                       orderID, newOrderErr := t.Merchant.AddNewOrder(*cost)
+                       if newOrderErr != nil {
+                               fmt.Println(newOrderErr)
+                               w.WriteHeader(http.StatusInternalServerError)
+                               return
+                       }
+                       validation.OrderID = orderID
+               }
+
+               // Check if order paid.
+               // FIXME: Remember that it was activated and paid
+               payto, paytoErr := t.Merchant.IsOrderPaid(validation.OrderID)
+               if paytoErr != nil {
+                       fmt.Println(paytoErr)
+                       w.WriteHeader(http.StatusInternalServerError)
+                       log.Println(paytoErr)
+                       return
+               }
+               if len(payto) != 0 {
+                       t.Db.Save(&validation)
+                       w.WriteHeader(http.StatusPaymentRequired)
+                       w.Header().Set("Taler", payto) // FIXME no idea what to 
do with this.
+                       return
+               }
+               // In this case, this order was paid
+       }
+       if validationExists {
+               err = t.Db.Save(&validation).Error
+       } else {
+               err = t.Db.Create(&validation).Error
+       }
+       if err != nil {
+               log.Println(err)
+               w.WriteHeader(500)
+               return
+       }
+       // Some validation methods are costly
+       // Require explicit whitelisting for a resend.
+       if validation.ChallengeSent &&
+               
!t.Cfg.Section("taldir-"+vars["method"]).Key("allow_resend").MustBool(false) {
+               w.WriteHeader(202)
+               return
+       }
+       if !t.Cfg.Section("taldir-" + vars["method"]).HasKey("command") {
+               log.Fatal(err)
+               t.Db.Delete(&validation)
+               w.WriteHeader(500)
+               return
+       }
+       command := t.Cfg.Section("taldir-" + 
vars["method"]).Key("command").String()
+       path, err := exec.LookPath(command)
+       if err != nil {
+               log.Println(err)
+               t.Db.Delete(&validation)
+               w.WriteHeader(500)
+               return
+       }
+       out, err := exec.Command(path, req.Address, 
validation.Challenge).Output()
+       if err != nil {
+               log.Printf("%s, %w", out, err)
+               t.Db.Delete(&validation)
+               w.WriteHeader(500)
+               return
+       }
+       validation.ChallengeSent = true
+       w.WriteHeader(202)
 }
 
 func (t *Taldir) configResponse(w http.ResponseWriter, r *http.Request) {
-  meths := []Method{}
-  i := 0
-  for key := range t.Validators {
-    var meth Method
-    meth.Name = key
-    meth.ChallengeFee = t.Cfg.Section("taldir-" + 
key).Key("challenge_fee").MustString("KUDOS:1")
-    i++
-    meths = append(meths, meth)
-  }
-  cfg := VersionResponse{
-    Version: "0:0:0",
-    Name: "taler-directory",
-    MonthlyFee: 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:1"),
-    Methods: meths,
-  }
-  w.Header().Set("Content-Type", "application/json")
-  response, _ := json.Marshal(cfg)
-  w.Write(response)
+       meths := []Method{}
+       i := 0
+       for key := range t.Validators {
+               var meth Method
+               meth.Name = key
+               meth.ChallengeFee = t.Cfg.Section("taldir-" + 
key).Key("challenge_fee").MustString("KUDOS:1")
+               i++
+               meths = append(meths, meth)
+       }
+       cfg := VersionResponse{
+               Version:    "0:0:0",
+               Name:       "taler-directory",
+               MonthlyFee: 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:1"),
+               Methods:    meths,
+       }
+       w.Header().Set("Content-Type", "application/json")
+       response, _ := json.Marshal(cfg)
+       w.Write(response)
 }
 
 func (t *Taldir) validationPage(w http.ResponseWriter, r *http.Request) {
-  vars := mux.Vars(r)
-  var walletLink string
-  var png []byte
-  var validation validation
-
-  err := t.Db.First(&validation, "h_address = ?", vars["h_address"]).Error
-  w.Header().Set("Content-Type", "text/html; charset=utf-8")
-  if err != nil {
-    // This validation does not exist.
-    w.WriteHeader(404)
-    return
-  }
-
-  walletLink = "taler://taldir/" + vars["h_address"] + "/" + vars["challenge"] 
+ "-wallet"
-  png, err = qrcode.Encode(walletLink, qrcode.Medium, 256)
-  if err != nil {
-    w.WriteHeader(500)
-    return
-  }
-  encodedPng := base64.StdEncoding.EncodeToString(png)
-
-  fullData := map[string]interface{}{
-    "QRCode": template.URL("data:image/png;base64," + encodedPng),
-    "WalletLink": template.URL(walletLink),
-  }
-  t.ValidationTpl.Execute(w, fullData)
-  return
+       vars := mux.Vars(r)
+       var walletLink string
+       var png []byte
+       var validation validation
+
+       err := t.Db.First(&validation, "h_address = ?", vars["h_address"]).Error
+       w.Header().Set("Content-Type", "text/html; charset=utf-8")
+       if err != nil {
+               // This validation does not exist.
+               w.WriteHeader(404)
+               return
+       }
+
+       walletLink = "taler://taldir/" + vars["h_address"] + "/" + 
vars["challenge"] + "-wallet"
+       png, err = qrcode.Encode(walletLink, qrcode.Medium, 256)
+       if err != nil {
+               w.WriteHeader(500)
+               return
+       }
+       encodedPng := base64.StdEncoding.EncodeToString(png)
+
+       fullData := map[string]interface{}{
+               "QRCode":     template.URL("data:image/png;base64," + 
encodedPng),
+               "WalletLink": template.URL(walletLink),
+       }
+       t.ValidationTpl.Execute(w, fullData)
+       return
 }
 
 // ClearDatabase nukes the database (for tests)
 func (t *Taldir) ClearDatabase() {
-  t.Db.Where("1 = 1").Delete(&entry{})
-  t.Db.Where("1 = 1").Delete(&validation{})
+       t.Db.Where("1 = 1").Delete(&entry{})
+       t.Db.Where("1 = 1").Delete(&validation{})
 }
 
 func (t *Taldir) termsResponse(w http.ResponseWriter, r *http.Request) {
-  fileType := 
t.Cfg.Section("taldir").Key("default_doc_filetype").MustString("text/html")
-  termsLocation := 
t.Cfg.Section("taldir").Key("default_tos_path").MustString("terms/")
-  for _, typ := range r.Header["Accept"] {
-    for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("supported_doc_filetypes").String(), 
" ") {
-      if typ == a {
-        fileType = a
-      }
-    }
-  }
-
-  if len(r.Header.Get("Accept-Language")) != 0 {
-    acceptLangs, _, _ := 
language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
-    for _, lang := range acceptLangs {
-      extensions, _ := mime.ExtensionsByType(fileType)
-      for _, ext := range extensions {
-        docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, lang.String(), ext)
-        log.Printf("Trying %s\n", docFile)
-        fileBytes, err := ioutil.ReadFile(docFile)
-        if nil == err {
-          w.Header().Set("Content-Type", fileType)
-          w.Write(fileBytes)
-          return
-        }
-      }
-    }
-  }
-  // Default document in expected/default format
-  defaultLanguage := 
t.Cfg.Section("taldir").Key("default_doc_lang").MustString("en")
-  extensions, _ := mime.ExtensionsByType(fileType)
-  for _, ext := range extensions {
-    docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, defaultLanguage, ext)
-    log.Println("Trying " + docFile)
-    fileBytes, err := ioutil.ReadFile(docFile)
-    if nil == err {
-      w.Header().Set("Content-Type", fileType)
-      w.Write(fileBytes)
-      return
-    }
-  }
-  w.WriteHeader(http.StatusNotFound)
+       fileType := 
t.Cfg.Section("taldir").Key("default_doc_filetype").MustString("text/html")
+       termsLocation := 
t.Cfg.Section("taldir").Key("default_tos_path").MustString("terms/")
+       for _, typ := range r.Header["Accept"] {
+               for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("supported_doc_filetypes").String(), 
" ") {
+                       if typ == a {
+                               fileType = a
+                       }
+               }
+       }
+
+       if len(r.Header.Get("Accept-Language")) != 0 {
+               acceptLangs, _, _ := 
language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
+               for _, lang := range acceptLangs {
+                       extensions, _ := mime.ExtensionsByType(fileType)
+                       for _, ext := range extensions {
+                               docFile := fmt.Sprintf("%s/%s/0%s", 
termsLocation, lang.String(), ext)
+                               log.Printf("Trying %s\n", docFile)
+                               fileBytes, err := ioutil.ReadFile(docFile)
+                               if nil == err {
+                                       w.Header().Set("Content-Type", fileType)
+                                       w.Write(fileBytes)
+                                       return
+                               }
+                       }
+               }
+       }
+       // Default document in expected/default format
+       defaultLanguage := 
t.Cfg.Section("taldir").Key("default_doc_lang").MustString("en")
+       extensions, _ := mime.ExtensionsByType(fileType)
+       for _, ext := range extensions {
+               docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, 
defaultLanguage, ext)
+               log.Println("Trying " + docFile)
+               fileBytes, err := ioutil.ReadFile(docFile)
+               if nil == err {
+                       w.Header().Set("Content-Type", fileType)
+                       w.Write(fileBytes)
+                       return
+               }
+       }
+       w.WriteHeader(http.StatusNotFound)
 }
 
 func (t *Taldir) privacyResponse(w http.ResponseWriter, r *http.Request) {
-  fileType := 
t.Cfg.Section("taldir").Key("default_doc_filetype").MustString("text/html")
-  termsLocation := 
t.Cfg.Section("taldir").Key("default_pp_path").MustString("privacy/")
-  for _, typ := range r.Header["Accept"] {
-    for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("supported_doc_filetypes").String(), 
" ") {
-      if typ == a {
-        fileType = a
-      }
-    }
-  }
-
-  if len(r.Header.Get("Accept-Language")) != 0 {
-    acceptLangs, _, _ := 
language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
-    for _, lang := range acceptLangs {
-      extensions, _ := mime.ExtensionsByType(fileType)
-      for _, ext := range extensions {
-        docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, lang.String(), ext)
-        log.Printf("Trying %s\n", docFile)
-        fileBytes, err := ioutil.ReadFile(docFile)
-        if nil == err {
-          w.Header().Set("Content-Type", fileType)
-          w.Write(fileBytes)
-          return
-        }
-      }
-    }
-  }
-  // Default document in expected/default format
-  defaultLanguage := 
t.Cfg.Section("taldir").Key("default_doc_lang").MustString("en")
-  extensions, _ := mime.ExtensionsByType(fileType)
-  for _, ext := range extensions {
-    docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, defaultLanguage, ext)
-    fileBytes, err := ioutil.ReadFile(docFile)
-    if nil == err {
-      w.Header().Set("Content-Type", fileType)
-      w.Write(fileBytes)
-      return
-    }
-  }
-  w.WriteHeader(http.StatusNotFound)
+       fileType := 
t.Cfg.Section("taldir").Key("default_doc_filetype").MustString("text/html")
+       termsLocation := 
t.Cfg.Section("taldir").Key("default_pp_path").MustString("privacy/")
+       for _, typ := range r.Header["Accept"] {
+               for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("supported_doc_filetypes").String(), 
" ") {
+                       if typ == a {
+                               fileType = a
+                       }
+               }
+       }
+
+       if len(r.Header.Get("Accept-Language")) != 0 {
+               acceptLangs, _, _ := 
language.ParseAcceptLanguage(r.Header.Get("Accept-Language"))
+               for _, lang := range acceptLangs {
+                       extensions, _ := mime.ExtensionsByType(fileType)
+                       for _, ext := range extensions {
+                               docFile := fmt.Sprintf("%s/%s/0%s", 
termsLocation, lang.String(), ext)
+                               log.Printf("Trying %s\n", docFile)
+                               fileBytes, err := ioutil.ReadFile(docFile)
+                               if nil == err {
+                                       w.Header().Set("Content-Type", fileType)
+                                       w.Write(fileBytes)
+                                       return
+                               }
+                       }
+               }
+       }
+       // Default document in expected/default format
+       defaultLanguage := 
t.Cfg.Section("taldir").Key("default_doc_lang").MustString("en")
+       extensions, _ := mime.ExtensionsByType(fileType)
+       for _, ext := range extensions {
+               docFile := fmt.Sprintf("%s/%s/0%s", termsLocation, 
defaultLanguage, ext)
+               fileBytes, err := ioutil.ReadFile(docFile)
+               if nil == err {
+                       w.Header().Set("Content-Type", fileType)
+                       w.Write(fileBytes)
+                       return
+               }
+       }
+       w.WriteHeader(http.StatusNotFound)
 }
 
-
 func (t *Taldir) setupHandlers() {
-  t.Router = mux.NewRouter().StrictSlash(true)
+       t.Router = mux.NewRouter().StrictSlash(true)
 
-  /* ToS API */
-  t.Router.HandleFunc("/terms", t.termsResponse).Methods("GET")
-  t.Router.HandleFunc("/privacy", t.privacyResponse).Methods("GET")
+       /* ToS API */
+       t.Router.HandleFunc("/terms", t.termsResponse).Methods("GET")
+       t.Router.HandleFunc("/privacy", t.privacyResponse).Methods("GET")
 
-  /* Config API */
-  t.Router.HandleFunc("/config", t.configResponse).Methods("GET")
+       /* Config API */
+       t.Router.HandleFunc("/config", t.configResponse).Methods("GET")
 
-  /* Aissets HTML */
-  t.Router.PathPrefix("/css").Handler(http.StripPrefix("/css", 
http.FileServer(http.Dir("./static/css"))))
+       /* Aissets HTML */
+       t.Router.PathPrefix("/css").Handler(http.StripPrefix("/css", 
http.FileServer(http.Dir("./static/css"))))
 
-  /* Registration API */
-  t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET")
-  t.Router.HandleFunc("/register/{method}", t.registerRequest).Methods("POST")
-  t.Router.HandleFunc("/register/{h_address}/{challenge}", 
t.validationPage).Methods("GET")
-  t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST")
+       /* Registration API */
+       t.Router.HandleFunc("/{h_address}", t.getSingleEntry).Methods("GET")
+       t.Router.HandleFunc("/register/{method}", 
t.registerRequest).Methods("POST")
+       t.Router.HandleFunc("/register/{h_address}/{challenge}", 
t.validationPage).Methods("GET")
+       t.Router.HandleFunc("/{h_address}", t.validationRequest).Methods("POST")
 
 }
 
 // Initialize the Taldir instance with cfgfile
 func (t *Taldir) Initialize(cfgfile string) {
-  _cfg, err := ini.Load(cfgfile)
-  if err != nil {
-    fmt.Printf("Failed to read config: %v", err)
-    os.Exit(1)
-  }
-  t.Cfg = _cfg
-  if t.Cfg.Section("taldir").Key("production").MustBool(false) {
-    fmt.Println("Production mode enabled")
-  }
-
-  t.Validators = make(map[string]bool)
-  for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("validators").String(), " ") {
-    t.Validators[a] = true
-  }
-  t.ChallengeBytes = t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16)
-  t.ValidationInitiationMax = 
t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt64(3)
-  t.SolutionAttemptsMax = 
t.Cfg.Section("taldir").Key("solution_attempt_max").MustInt(3)
-
-  validationTTLStr := 
t.Cfg.Section("taldir").Key("validation_timeframe").MustString("5m")
-  t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr)
-  if err != nil {
-    log.Fatal(err)
-  }
-
-  retryTimeframeStr := 
t.Cfg.Section("taldir").Key("solution_attempt_timeframe").MustString("1h")
-  t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr)
-  if err != nil {
-    log.Fatal(err)
-  }
-  t.MonthlyFee = 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:0")
-
-  psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s 
sslmode=disable",
-  t.Cfg.Section("taldir-pq").Key("host").MustString("localhost"),
-  t.Cfg.Section("taldir-pq").Key("port").MustInt64(5432),
-  t.Cfg.Section("taldir-pq").Key("user").MustString("taldir"),
-  t.Cfg.Section("taldir-pq").Key("password").MustString("secret"),
-  t.Cfg.Section("taldir-pq").Key("db_name").MustString("taldir"))
-  _db, err := gorm.Open(postgres.Open(psqlconn), &gorm.Config{
-    Logger: logger.Default.LogMode(logger.Silent),
-  })
-  if err != nil {
-    panic(err)
-  }
-  t.Db = _db
-  if err := t.Db.AutoMigrate(&entry{}); err != nil {
-    panic(err)
-  }
-  if err := t.Db.AutoMigrate(&validation{}); err != nil {
-    panic(err)
-  }
-
-  // Clean up validations
-  validationExpStr := 
t.Cfg.Section("taldir").Key("validation_expiration").MustString("24h")
-  validationExp, err := time.ParseDuration(validationExpStr)
-  if err != nil {
-    log.Fatal(err)
-  }
-  go func() {
-    for true {
-      tx := t.Db.Where("created_at < ?", 
time.Now().Add(-validationExp)).Delete(&validation{})
-      log.Printf("Cleaned up %d stale validations.\n", tx.RowsAffected)
-      time.Sleep(validationExp)
-    }
-  }()
-  validationLandingTplFile := 
t.Cfg.Section("taldir").Key("validation_landing").MustString("templates/validation_landing.html")
-  t.ValidationTpl, err = template.ParseFiles(validationLandingTplFile)
-  if err != nil {
-    fmt.Println(err)
-  }
-  t.Salt = os.Getenv("TALDIR_SALT")
-  if "" == t.Salt {
-    t.Salt = t.Cfg.Section("taldir").Key("salt").MustString("ChangeMe")
-  }
-  merchURL := 
t.Cfg.Section("taldir").Key("merchant_baseurl_private").MustString("http://merchant.taldir/instances/myInstance";)
-  merchToken := 
t.Cfg.Section("taldir").Key("merchant_token").MustString("secretAccessToken")
-  t.Merchant = taler.NewMerchant(merchURL, merchToken)
-  t.setupHandlers()
+       _cfg, err := ini.Load(cfgfile)
+       if err != nil {
+               fmt.Printf("Failed to read config: %v", err)
+               os.Exit(1)
+       }
+       t.Cfg = _cfg
+       if t.Cfg.Section("taldir").Key("production").MustBool(false) {
+               fmt.Println("Production mode enabled")
+       }
+
+       t.Validators = make(map[string]bool)
+       for _, a := range 
strings.Split(t.Cfg.Section("taldir").Key("validators").String(), " ") {
+               t.Validators[a] = true
+       }
+       t.ChallengeBytes = 
t.Cfg.Section("taldir").Key("challenge_bytes").MustInt(16)
+       t.ValidationInitiationMax = 
t.Cfg.Section("taldir").Key("validation_initiation_max").MustInt64(3)
+       t.SolutionAttemptsMax = 
t.Cfg.Section("taldir").Key("solution_attempt_max").MustInt(3)
+
+       validationTTLStr := 
t.Cfg.Section("taldir").Key("validation_timeframe").MustString("5m")
+       t.ValidationTimeframe, err = time.ParseDuration(validationTTLStr)
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       retryTimeframeStr := 
t.Cfg.Section("taldir").Key("solution_attempt_timeframe").MustString("1h")
+       t.SolutionTimeframe, err = time.ParseDuration(retryTimeframeStr)
+       if err != nil {
+               log.Fatal(err)
+       }
+       t.MonthlyFee = 
t.Cfg.Section("taldir").Key("monthly_fee").MustString("KUDOS:0")
+
+       psqlconn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s 
sslmode=disable",
+               t.Cfg.Section("taldir-pq").Key("host").MustString("localhost"),
+               t.Cfg.Section("taldir-pq").Key("port").MustInt64(5432),
+               t.Cfg.Section("taldir-pq").Key("user").MustString("taldir"),
+               t.Cfg.Section("taldir-pq").Key("password").MustString("secret"),
+               t.Cfg.Section("taldir-pq").Key("db_name").MustString("taldir"))
+       _db, err := gorm.Open(postgres.Open(psqlconn), &gorm.Config{
+               Logger: logger.Default.LogMode(logger.Silent),
+       })
+       if err != nil {
+               panic(err)
+       }
+       t.Db = _db
+       if err := t.Db.AutoMigrate(&entry{}); err != nil {
+               panic(err)
+       }
+       if err := t.Db.AutoMigrate(&validation{}); err != nil {
+               panic(err)
+       }
+
+       // Clean up validations
+       validationExpStr := 
t.Cfg.Section("taldir").Key("validation_expiration").MustString("24h")
+       validationExp, err := time.ParseDuration(validationExpStr)
+       if err != nil {
+               log.Fatal(err)
+       }
+       go func() {
+               for true {
+                       tx := t.Db.Where("created_at < ?", 
time.Now().Add(-validationExp)).Delete(&validation{})
+                       log.Printf("Cleaned up %d stale validations.\n", 
tx.RowsAffected)
+                       time.Sleep(validationExp)
+               }
+       }()
+       validationLandingTplFile := 
t.Cfg.Section("taldir").Key("validation_landing").MustString("templates/validation_landing.html")
+       t.ValidationTpl, err = template.ParseFiles(validationLandingTplFile)
+       if err != nil {
+               fmt.Println(err)
+       }
+       t.Salt = os.Getenv("TALDIR_SALT")
+       if "" == t.Salt {
+               t.Salt = 
t.Cfg.Section("taldir").Key("salt").MustString("ChangeMe")
+       }
+       merchURL := 
t.Cfg.Section("taldir").Key("merchant_baseurl_private").MustString("http://merchant.taldir/instances/myInstance";)
+       merchToken := 
t.Cfg.Section("taldir").Key("merchant_token").MustString("secretAccessToken")
+       t.Merchant = taler.NewMerchant(merchURL, merchToken)
+       t.setupHandlers()
 }
diff --git a/pkg/taler/merchant.go b/pkg/taler/merchant.go
index 1606b3d..862f00c 100644
--- a/pkg/taler/merchant.go
+++ b/pkg/taler/merchant.go
@@ -1,161 +1,156 @@
 package taler
 
 import (
-  "net/http"
-  "encoding/json"
-  "bytes"
-  "fmt"
-  "errors"
-  "io/ioutil"
-  talerutil "taler.net/taler-go.git/pkg/util"
+       "bytes"
+       "encoding/json"
+       "errors"
+       "fmt"
+       "io/ioutil"
+       "net/http"
+       talerutil "taler.net/taler-go.git/pkg/util"
 )
 
 type PostOrderRequest struct {
-  // The order must at least contain the minimal
-  // order detail, but can override all.
-  order MinimalOrderDetail
-
-  // If set, the backend will then set the refund deadline to the current
-  // time plus the specified delay.  If it's not set, refunds will not be
-  // possible.
-  RefundDelay int64 `json:"refund_delay,omitempty"`
-
-  // Specifies the payment target preferred by the client. Can be used
-  // to select among the various (active) wire methods supported by the 
instance.
-  PaymentTarget string `json:"payment_target,omitempty"`
-
-  // Specifies that some products are to be included in the
-  // order from the inventory.  For these inventory management
-  // is performed (so the products must be in stock) and
-  // details are completed from the product data of the backend.
-  // FIXME: Not sure we actually need this for now
-  //InventoryProducts []MinimalInventoryProduct 
`json:"inventory_products,omitempty"`
-
-  // Specifies a lock identifier that was used to
-  // lock a product in the inventory.  Only useful if
-  // inventory_products is set.  Used in case a frontend
-  // reserved quantities of the individual products while
-  // the shopping cart was being built.  Multiple UUIDs can
-  // be used in case different UUIDs were used for different
-  // products (i.e. in case the user started with multiple
-  // shopping sessions that were combined during checkout).
-  LockUuids []string `json:"lock_uuids"`
-
-  // Should a token for claiming the order be generated?
-  // False can make sense if the ORDER_ID is sufficiently
-  // high entropy to prevent adversarial claims (like it is
-  // if the backend auto-generates one). Default is 'true'.
-  CreateToken bool `json:"create_token,omitempty"`
-
+       // The order must at least contain the minimal
+       // order detail, but can override all.
+       order MinimalOrderDetail
+
+       // If set, the backend will then set the refund deadline to the current
+       // time plus the specified delay.  If it's not set, refunds will not be
+       // possible.
+       RefundDelay int64 `json:"refund_delay,omitempty"`
+
+       // Specifies the payment target preferred by the client. Can be used
+       // to select among the various (active) wire methods supported by the 
instance.
+       PaymentTarget string `json:"payment_target,omitempty"`
+
+       // Specifies that some products are to be included in the
+       // order from the inventory.  For these inventory management
+       // is performed (so the products must be in stock) and
+       // details are completed from the product data of the backend.
+       // FIXME: Not sure we actually need this for now
+       //InventoryProducts []MinimalInventoryProduct 
`json:"inventory_products,omitempty"`
+
+       // Specifies a lock identifier that was used to
+       // lock a product in the inventory.  Only useful if
+       // inventory_products is set.  Used in case a frontend
+       // reserved quantities of the individual products while
+       // the shopping cart was being built.  Multiple UUIDs can
+       // be used in case different UUIDs were used for different
+       // products (i.e. in case the user started with multiple
+       // shopping sessions that were combined during checkout).
+       LockUuids []string `json:"lock_uuids"`
+
+       // Should a token for claiming the order be generated?
+       // False can make sense if the ORDER_ID is sufficiently
+       // high entropy to prevent adversarial claims (like it is
+       // if the backend auto-generates one). Default is 'true'.
+       CreateToken bool `json:"create_token,omitempty"`
 }
 
 type MinimalOrderDetail struct {
-  // Amount to be paid by the customer.
-  Amount string
+       // Amount to be paid by the customer.
+       Amount string
 
-  // Short summary of the order.
-  Summary string;
+       // Short summary of the order.
+       Summary string
 }
 
-
 // NOTE: Part of the above but optional
 type FulfillmentMetadata struct {
-  // See documentation of fulfillment_url in ContractTerms.
-  // Either fulfillment_url or fulfillment_message must be specified.
-  FulfillmentUrl string `json:"fulfillment_url,omitempty"`
+       // See documentation of fulfillment_url in ContractTerms.
+       // Either fulfillment_url or fulfillment_message must be specified.
+       FulfillmentUrl string `json:"fulfillment_url,omitempty"`
 
-  // See documentation of fulfillment_message in ContractTerms.
-  // Either fulfillment_url or fulfillment_message must be specified.
-  FulfillmentMessage string `json:"fulfillment_message,omitempty"`
+       // See documentation of fulfillment_message in ContractTerms.
+       // Either fulfillment_url or fulfillment_message must be specified.
+       FulfillmentMessage string `json:"fulfillment_message,omitempty"`
 }
 
 type PostOrderResponse struct {
-  // Order ID of the response that was just created.
-  OrderId string `json:"order_id"`
+       // Order ID of the response that was just created.
+       OrderId string `json:"order_id"`
 }
 
 type PostOrderResponseToken struct {
-  // Token that authorizes the wallet to claim the order.
-  // Provided only if "create_token" was set to 'true'
-  // in the request.
-  Token string
+       // Token that authorizes the wallet to claim the order.
+       // Provided only if "create_token" was set to 'true'
+       // in the request.
+       Token string
 }
 
 type CheckPaymentStatusResponse struct {
-  // Status of the order
-  OrderStatus string `json:"order_status"`
+       // Status of the order
+       OrderStatus string `json:"order_status"`
 }
 
 type CheckPaymentPaytoResponse struct {
-  // Status of the order
-  TalerPayUri string `json:"taler_pay_uri"`
+       // Status of the order
+       TalerPayUri string `json:"taler_pay_uri"`
 }
 
-
-
 type Merchant struct {
 
-  // The host of this merchant
-  BaseUrlPrivate string
-
-  // The access token to use for the private API
-  AccessToken string
+       // The host of this merchant
+       BaseUrlPrivate string
 
+       // The access token to use for the private API
+       AccessToken string
 }
 
 func NewMerchant(merchBaseUrlPrivate string, merchAccessToken string) Merchant 
{
-  return Merchant{
-    BaseUrlPrivate: merchBaseUrlPrivate,
-    AccessToken: merchAccessToken,
-  }
+       return Merchant{
+               BaseUrlPrivate: merchBaseUrlPrivate,
+               AccessToken:    merchAccessToken,
+       }
 }
 
 func (m *Merchant) IsOrderPaid(orderId string) (string, error) {
-  var orderPaidResponse CheckPaymentStatusResponse
-  var paytoResponse CheckPaymentPaytoResponse
-  resp, err := http.Get(m.BaseUrlPrivate + "/private/orders/" + orderId)
-  if nil != err {
-    return "", err
-  }
-  defer resp.Body.Close()
-  if http.StatusOK != resp.StatusCode {
-    message := fmt.Sprintf("Expected response code %d. Got %d", http.StatusOK, 
resp.StatusCode)
-    return "", errors.New(message)
-  }
-  respData, err := ioutil.ReadAll(resp.Body)
-  if err != nil {
-    return "", err
-  }
-  err = json.NewDecoder(bytes.NewReader(respData)).Decode(&orderPaidResponse)
-  if err != nil {
-    return "", err
-  }
-  if orderPaidResponse.OrderStatus != "paid" {
-    err = json.NewDecoder(bytes.NewReader(respData)).Decode(&paytoResponse)
-    return paytoResponse.TalerPayUri, err
-  }
-  return "", nil
+       var orderPaidResponse CheckPaymentStatusResponse
+       var paytoResponse CheckPaymentPaytoResponse
+       resp, err := http.Get(m.BaseUrlPrivate + "/private/orders/" + orderId)
+       if nil != err {
+               return "", err
+       }
+       defer resp.Body.Close()
+       if http.StatusOK != resp.StatusCode {
+               message := fmt.Sprintf("Expected response code %d. Got %d", 
http.StatusOK, resp.StatusCode)
+               return "", errors.New(message)
+       }
+       respData, err := ioutil.ReadAll(resp.Body)
+       if err != nil {
+               return "", err
+       }
+       err = 
json.NewDecoder(bytes.NewReader(respData)).Decode(&orderPaidResponse)
+       if err != nil {
+               return "", err
+       }
+       if orderPaidResponse.OrderStatus != "paid" {
+               err = 
json.NewDecoder(bytes.NewReader(respData)).Decode(&paytoResponse)
+               return paytoResponse.TalerPayUri, err
+       }
+       return "", nil
 }
 
 func (m *Merchant) AddNewOrder(cost talerutil.Amount) (string, error) {
-  var newOrder PostOrderRequest
-  var orderDetail MinimalOrderDetail
-  var orderResponse PostOrderResponse
-  orderDetail.Amount = cost.String()
-  // FIXME get from cfg
-  orderDetail.Summary = "This is an order to a TalDir registration"
-  newOrder.order = orderDetail
-  reqString, _ := json.Marshal(newOrder)
-  resp, err := http.Post(m.BaseUrlPrivate + "/private/orders", 
"application/json", bytes.NewBuffer(reqString))
-
-  if nil != err {
-    return "", err
-  }
-  defer resp.Body.Close()
-  if http.StatusOK != resp.StatusCode {
-    message := fmt.Sprintf("Expected response code %d. Got %d", http.StatusOK, 
resp.StatusCode)
-    return "", errors.New(message)
-  }
-  err = json.NewDecoder(resp.Body).Decode(&orderResponse)
-  return orderResponse.OrderId, err
+       var newOrder PostOrderRequest
+       var orderDetail MinimalOrderDetail
+       var orderResponse PostOrderResponse
+       orderDetail.Amount = cost.String()
+       // FIXME get from cfg
+       orderDetail.Summary = "This is an order to a TalDir registration"
+       newOrder.order = orderDetail
+       reqString, _ := json.Marshal(newOrder)
+       resp, err := http.Post(m.BaseUrlPrivate+"/private/orders", 
"application/json", bytes.NewBuffer(reqString))
+
+       if nil != err {
+               return "", err
+       }
+       defer resp.Body.Close()
+       if http.StatusOK != resp.StatusCode {
+               message := fmt.Sprintf("Expected response code %d. Got %d", 
http.StatusOK, resp.StatusCode)
+               return "", errors.New(message)
+       }
+       err = json.NewDecoder(resp.Body).Decode(&orderResponse)
+       return orderResponse.OrderId, err
 }
diff --git a/pkg/util/helper.go b/pkg/util/helper.go
index 9243c5e..b99d6af 100644
--- a/pkg/util/helper.go
+++ b/pkg/util/helper.go
@@ -16,67 +16,65 @@
 //
 // SPDX-License-Identifier: AGPL3.0-or-later
 
-
 package util
 
 import (
-  "fmt"
-  "crypto/sha512"
-  "math/rand"
-  "time"
-  gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
-  talerutil "taler.net/taler-go.git/pkg/util"
+       "crypto/sha512"
+       "fmt"
+       gnunetutil "git.gnunet.org/gnunet-go.git/pkg/util"
+       "math/rand"
+       talerutil "taler.net/taler-go.git/pkg/util"
+       "time"
 )
 
-
 // Generates a solution from a challenge and pubkey
 func GenerateSolution(pubkeyEncoded string, challenge string) string {
-  pubkey, err := gnunetutil.DecodeStringToBinary(pubkeyEncoded, 36)
-  if err != nil {
-    fmt.Println("error decoding pubkey:", err)
-    return ""
-  }
-  h := sha512.New()
-  h.Write([]byte(challenge))
-  h.Write(pubkey)
-  return gnunetutil.EncodeBinaryToString(h.Sum(nil))
+       pubkey, err := gnunetutil.DecodeStringToBinary(pubkeyEncoded, 36)
+       if err != nil {
+               fmt.Println("error decoding pubkey:", err)
+               return ""
+       }
+       h := sha512.New()
+       h.Write([]byte(challenge))
+       h.Write(pubkey)
+       return gnunetutil.EncodeBinaryToString(h.Sum(nil))
 }
 
 // Generates random reference token used in the validation flow.
 func GenerateChallenge(bytes int) string {
-  randBytes := make([]byte, bytes)
-  _, err := rand.Read(randBytes)
-  if err != nil {
-    panic(err)
-  }
-  return gnunetutil.EncodeBinaryToString(randBytes)
+       randBytes := make([]byte, bytes)
+       _, err := rand.Read(randBytes)
+       if err != nil {
+               panic(err)
+       }
+       return gnunetutil.EncodeBinaryToString(randBytes)
 }
 
 // Check if this is a non-zero, positive amount
 func CalculateCost(sliceCostAmount string, fixedCostAmount string, howLong 
time.Duration, sliceDuration time.Duration) (*talerutil.Amount, error) {
-  sliceCount := int(float64(howLong.Microseconds()) / 
float64(sliceDuration.Microseconds()))
-  sliceCost, err := talerutil.ParseAmount(sliceCostAmount)
-  if nil != err {
-    return nil, err
-  }
-  fixedCost, err := talerutil.ParseAmount(fixedCostAmount)
-  if nil != err {
-    return nil, err
-  }
-  sum := &talerutil.Amount{
-    Currency: sliceCost.Currency,
-    Value: 0,
-    Fraction: 0,
-  }
-  for i := 0; i < sliceCount; i++ {
-    sum, err = sum.Add(*sliceCost)
-    if nil != err {
-      return nil, err
-    }
-  }
-  sum, err = sum.Add(*fixedCost)
-  if nil != err {
-    return nil, err
-  }
-  return sum, nil
+       sliceCount := int(float64(howLong.Microseconds()) / 
float64(sliceDuration.Microseconds()))
+       sliceCost, err := talerutil.ParseAmount(sliceCostAmount)
+       if nil != err {
+               return nil, err
+       }
+       fixedCost, err := talerutil.ParseAmount(fixedCostAmount)
+       if nil != err {
+               return nil, err
+       }
+       sum := &talerutil.Amount{
+               Currency: sliceCost.Currency,
+               Value:    0,
+               Fraction: 0,
+       }
+       for i := 0; i < sliceCount; i++ {
+               sum, err = sum.Add(*sliceCost)
+               if nil != err {
+                       return nil, err
+               }
+       }
+       sum, err = sum.Add(*fixedCost)
+       if nil != err {
+               return nil, err
+       }
+       return sum, nil
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]