summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/.gitignore1
-rw-r--r--src/include/Makefile.am13
-rw-r--r--src/include/gettext.h71
-rw-r--r--src/include/platform.h247
-rw-r--r--src/include/taler_amount_lib.h107
-rw-r--r--src/include/taler_attributes.h129
-rw-r--r--src/include/taler_auditor_service.h226
-rw-r--r--src/include/taler_auditordb_plugin.h1285
-rw-r--r--src/include/taler_bank_service.h333
-rw-r--r--src/include/taler_crypto_lib.h5360
-rw-r--r--src/include/taler_curl_lib.h22
-rw-r--r--src/include/taler_error_codes.h2550
-rw-r--r--src/include/taler_exchange_service.h6697
-rw-r--r--src/include/taler_exchangedb_lib.h484
-rw-r--r--src/include/taler_exchangedb_plugin.h5788
-rw-r--r--src/include/taler_extensions.h386
-rw-r--r--src/include/taler_extensions_policy.h205
-rw-r--r--src/include/taler_fakebank_lib.h112
-rw-r--r--src/include/taler_json_lib.h674
-rw-r--r--src/include/taler_kyclogic_lib.h374
-rw-r--r--src/include/taler_kyclogic_plugin.h384
-rw-r--r--src/include/taler_mhd_lib.h553
-rw-r--r--src/include/taler_pq_lib.h357
-rw-r--r--src/include/taler_signatures.h1417
-rw-r--r--src/include/taler_sq_lib.h99
-rw-r--r--src/include/taler_templating_lib.h130
-rw-r--r--src/include/taler_testing_lib.h2792
-rw-r--r--src/include/taler_twister_testing_lib.h19
-rw-r--r--src/include/taler_util.h542
29 files changed, 22882 insertions, 8475 deletions
diff --git a/src/include/.gitignore b/src/include/.gitignore
new file mode 100644
index 000000000..beba883b6
--- /dev/null
+++ b/src/include/.gitignore
@@ -0,0 +1 @@
+taler_signatures.h
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
index b8ea0d175..45d74ab8e 100644
--- a/src/include/Makefile.am
+++ b/src/include/Makefile.am
@@ -2,25 +2,34 @@
talerincludedir = $(includedir)/taler
talerinclude_HEADERS = \
- platform.h \
+ platform.h gettext.h \
taler_auditor_service.h \
taler_amount_lib.h \
+ taler_attributes.h \
taler_auditordb_lib.h \
taler_auditordb_plugin.h \
taler_bank_service.h \
taler_crypto_lib.h \
taler_curl_lib.h \
+ taler_dbevents.h \
taler_error_codes.h \
taler_exchange_service.h \
taler_exchangedb_lib.h \
taler_exchangedb_plugin.h \
+ taler_extensions.h \
+ taler_extensions_policy.h \
taler_fakebank_lib.h \
+ taler_kyclogic_lib.h \
+ taler_kyclogic_plugin.h \
taler_json_lib.h \
taler_testing_lib.h \
taler_util.h \
taler_mhd_lib.h \
taler_pq_lib.h \
- taler_signatures.h
+ taler_signatures.h \
+ taler_sq_lib.h \
+ taler_templating_lib.h \
+ taler_twister_testing_lib.h
EXTRA_DIST = \
backoff.h \
diff --git a/src/include/gettext.h b/src/include/gettext.h
new file mode 100644
index 000000000..458512657
--- /dev/null
+++ b/src/include/gettext.h
@@ -0,0 +1,71 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+#include <libintl.h>
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+ chokes if dcgettext is defined as a macro. So include it now, to make
+ later inclusions of <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is GNUNET_OK. */
+#if defined(__sun)
+#include <locale.h>
+#endif
+
+/* Disabled NLS.
+ The casts to 'const char *' serve the purpose of producing warnings
+ for invalid uses of the value returned from these functions.
+ On pre-ANSI systems without 'const', the config.h file is supposed to
+ contain "#define const". */
+#define gettext(Msgid) ((const char *) (Msgid))
+#define dgettext(Domainname, Msgid) ((const char *) (Msgid))
+#define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
+#define ngettext(Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+#define dngettext(Domainname, Msgid1, Msgid2, N) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+#define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+ ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
+/* slight modification here to avoid warnings: generate GNUNET_NO code,
+ not even the cast... */
+#define textdomain(Domainname)
+#define bindtextdomain(Domainname, Dirname)
+#define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+ extraction of messages, but does not call gettext(). The run-time
+ translation is done at a different place in the code.
+ The argument, String, should be a literal string. Concatenated strings
+ and other string expressions won't work.
+ The macro's expansion is not parenthesized, so that it is suitable as
+ initializer for static 'char[]' or 'const char[]' variables. */
+#define gettext_noop(String) String
+
+#endif /* _LIBGETTEXT_H */
diff --git a/src/include/platform.h b/src/include/platform.h
index ec2f70768..db04cb972 100644
--- a/src/include/platform.h
+++ b/src/include/platform.h
@@ -20,18 +20,21 @@
* rest of the modules
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
-
#ifndef PLATFORM_H_
#define PLATFORM_H_
/* Include our configuration header */
#ifndef HAVE_USED_CONFIG_H
-# define HAVE_USED_CONFIG_H
-# ifdef HAVE_CONFIG_H
-# include "taler_config.h"
-# endif
+#define HAVE_USED_CONFIG_H
+#ifdef HAVE_CONFIG_H
+#include "taler_config.h"
+#endif
#endif
+/* For the exchange build, we do NOT want gettext, even
+ if it is available! */
+#undef ENABLE_NLS
+
#if (GNUNET_EXTRA_LOGGING >= 1)
#define VERBOSE(cmd) cmd
@@ -42,9 +45,6 @@
/* Include the features available for GNU source */
#define _GNU_SOURCE
-/* Include GNUnet's platform file */
-#include <gnunet/platform.h>
-
/* Do not use shortcuts for gcrypt mpi */
#define GCRYPT_NO_MPI_MACROS 1
@@ -63,6 +63,237 @@
is needed for performance reasons. */
#define ENABLE_SANITY_CHECKS 1
+
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+#include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IP_H
+#include <netinet/ip.h> /* superset of previous */
+#endif
+#include <arpa/inet.h>
+#include <netinet/tcp.h>
+#include <pwd.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+#include <grp.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <signal.h>
+#include <libgen.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h> /* for mallinfo on GNU */
+#endif
+#include <unistd.h> /* KLB_FIX */
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h> /* KLB_FIX */
+#include <fcntl.h>
+#include <math.h>
+#if HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#include <time.h>
+#ifdef BSD
+#include <net/if.h>
+#endif
+#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
+#include <semaphore.h>
+#endif
+#ifdef DARWIN
+#include <dlfcn.h>
+#include <semaphore.h>
+#include <net/if.h>
+#endif
+#if defined(__linux__) || defined(GNU)
+#include <net/if.h>
+#endif
+#ifdef SOLARIS
+#include <sys/sockio.h>
+#include <sys/filio.h>
+#include <sys/loadavg.h>
+#include <semaphore.h>
+#endif
+#if HAVE_UCRED_H
+#include <ucred.h>
+#endif
+#if HAVE_SYS_UCRED_H
+#include <sys/ucred.h>
+#endif
+#if HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif
+#include <errno.h>
+#include <limits.h>
+
+#if HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
+#include <ctype.h>
+#if HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+#if HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#if HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+
+#define DIR_SEPARATOR '/'
+#define DIR_SEPARATOR_STR "/"
+#define PATH_SEPARATOR ':'
+#define PATH_SEPARATOR_STR ":"
+#define NEWLINE "\n"
+
+
+#include <locale.h>
+#include "gettext.h"
+/**
+ * GNU gettext support macro.
+ */
+#define _(String) dgettext (PACKAGE, String)
+
+
+#include <sys/mman.h>
+
+/* FreeBSD_kernel is not defined on the now discontinued kFreeBSD */
+#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
+#define __BYTE_ORDER BYTE_ORDER
+#define __BIG_ENDIAN BIG_ENDIAN
+#endif
+
+#ifdef DARWIN
+#define __BYTE_ORDER BYTE_ORDER
+#define __BIG_ENDIAN BIG_ENDIAN
+/* not available on darwin, override configure */
+#undef HAVE_STAT64
+#undef HAVE_MREMAP
+#endif
+
+#if ! HAVE_ATOLL
+long long
+atoll (const char *nptr);
+
+#endif
+
+#if ENABLE_NLS
+#include "langinfo.h"
+#endif
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) (-1))
+#endif
+
+#ifndef O_LARGEFILE
+#define O_LARGEFILE 0
+#endif
+
+
+#if defined(__sparc__)
+#define MAKE_UNALIGNED(val) ({ __typeof__((val)) __tmp; memmove (&__tmp, &(val), \
+ sizeof((val))); \
+ __tmp; })
+#else
+#define MAKE_UNALIGNED(val) val
+#endif
+
+
+#ifndef PATH_MAX
+/**
+ * Assumed maximum path length.
+ */
+#define PATH_MAX 4096
+#endif
+
+#if HAVE_THREAD_LOCAL_GCC
+#define TALER_THREAD_LOCAL __thread
+#else
+#define TALER_THREAD_LOCAL
+#endif
+
+
+/* LSB-style exit status codes */
+#ifndef EXIT_INVALIDARGUMENT
+/**
+ * Command-line arguments are invalid.
+ * Restarting useless.
+ */
+#define EXIT_INVALIDARGUMENT 2
+#endif
+
+#ifndef EXIT_NOTIMPLEMENTED
+/**
+ * The requested operation is not implemented.
+ * Restarting useless.
+ */
+#define EXIT_NOTIMPLEMENTED 3
+#endif
+
+#ifndef EXIT_NOPERMISSION
+/**
+ * Permissions needed to run are not available.
+ * Restarting useless.
+ */
+#define EXIT_NOPERMISSION 4
+#endif
+
+#ifndef EXIT_NOTINSTALLED
+/**
+ * Key resources are not installed.
+ * Restarting useless.
+ */
+#define EXIT_NOTINSTALLED 5
+#endif
+
+#ifndef EXIT_NOTCONFIGURED
+/**
+ * Key configuration settings are missing or invalid.
+ * Restarting useless.
+ */
+#define EXIT_NOTCONFIGURED 6
+#endif
+
+#ifndef EXIT_NOTRUNNING
+#define EXIT_NOTRUNNING 7
+#endif
+
+
+#ifndef EXIT_NO_RESTART
+/**
+ * Exit code from 'main' if we do not want to be restarted,
+ * except by manual intervention (hard failure).
+ */
+#define EXIT_NO_RESTART 9
+#endif
+
+
+/**
+ * clang et al do not have such an attribute
+ */
+#if __has_attribute (__nonstring__)
+# define __nonstring __attribute__((__nonstring__))
+#else
+# define __nonstring
+#endif
+
+
#endif /* PLATFORM_H_ */
/* end of platform.h */
diff --git a/src/include/taler_amount_lib.h b/src/include/taler_amount_lib.h
index 63c5dba40..937238d15 100644
--- a/src/include/taler_amount_lib.h
+++ b/src/include/taler_amount_lib.h
@@ -18,9 +18,16 @@
* @brief amount-representation utility functions
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
*/
+#if ! defined (__TALER_UTIL_LIB_H_INSIDE__)
+#error "Only <taler_util.h> can be included directly."
+#endif
+
#ifndef TALER_AMOUNT_LIB_H
#define TALER_AMOUNT_LIB_H
+#include <stdint.h>
+#include "gnunet/gnunet_common.h"
+
#ifdef __cplusplus
extern "C"
{
@@ -64,6 +71,11 @@ extern "C"
*/
#define TALER_AMOUNT_FRAC_LEN 8
+/**
+ * Maximum legal 'value' for an amount, based on IEEE double (for JavaScript compatibility).
+ */
+#define TALER_AMOUNT_MAX_VALUE (1LLU << 52)
+
GNUNET_NETWORK_STRUCT_BEGIN
@@ -116,6 +128,16 @@ struct TALER_Amount
/**
+ * Check that the currency code in @a str is well-formed.
+ *
+ * @param str currency code name to validate
+ * @return #GNUNET_OK if @a str is a valid currency code
+ */
+enum GNUNET_GenericReturnValue
+TALER_check_currency (const char *str);
+
+
+/**
* Parse monetary amount, in the format "T:V.F".
*
* @param str amount string
@@ -123,7 +145,7 @@ struct TALER_Amount
* @return #GNUNET_OK if the string is a valid monetary amount specification,
* #GNUNET_SYSERR if it is invalid.
*/
-int
+enum GNUNET_GenericReturnValue
TALER_string_to_amount (const char *str,
struct TALER_Amount *amount);
@@ -137,7 +159,7 @@ TALER_string_to_amount (const char *str,
* @return #GNUNET_OK if the string is a valid amount specification,
* #GNUNET_SYSERR if it is invalid.
*/
-int
+enum GNUNET_GenericReturnValue
TALER_string_to_amount_nbo (const char *str,
struct TALER_AmountNBO *amount_nbo);
@@ -150,22 +172,45 @@ TALER_string_to_amount_nbo (const char *str,
* @return #GNUNET_OK if @a cur is a valid currency specification,
* #GNUNET_SYSERR if it is invalid.
*/
-int
-TALER_amount_get_zero (const char *cur,
+enum GNUNET_GenericReturnValue
+TALER_amount_set_zero (const char *cur,
struct TALER_Amount *amount);
/**
+ * Test if the given @a amount is zero.
+ *
+ * @param amount amount to compare to zero
+ * @return true if the amount is zero,
+ * false if it is non-zero or invalid
+ */
+bool
+TALER_amount_is_zero (const struct TALER_Amount *amount);
+
+
+/**
* Test if the given amount is valid.
*
* @param amount amount to check
* @return #GNUNET_OK if @a amount is valid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_amount_is_valid (const struct TALER_Amount *amount);
/**
+ * Test if the given amount is in the given currency
+ *
+ * @param amount amount to check
+ * @param currency currency to check for
+ * @return #GNUNET_OK if @a amount is in @a currency
+ */
+enum GNUNET_GenericReturnValue
+TALER_amount_is_currency (const struct TALER_Amount *amount,
+ const char *currency);
+
+
+/**
* Convert amount from host to network representation.
*
* @param[out] res where to store amount in network representation
@@ -206,6 +251,24 @@ TALER_amount_cmp (const struct TALER_Amount *a1,
/**
+ * Compare the value/fraction of two amounts. Does not compare the currency.
+ * Comparing amounts of different currencies will cause the program to abort().
+ * If unsure, check with #TALER_amount_cmp_currency() first to be sure that
+ * the currencies of the two amounts are identical. NBO variant.
+ *
+ * @param a1 first amount
+ * @param a2 second amount
+ * @return result of the comparison
+ * -1 if `a1 < a2`
+ * 1 if `a1 > a2`
+ * 0 if `a1 == a2`.
+ */
+int
+TALER_amount_cmp_nbo (const struct TALER_AmountNBO *a1,
+ const struct TALER_AmountNBO *a2);
+
+
+/**
* Test if @a a1 and @a a2 are the same currency.
*
* @param a1 amount to test
@@ -214,7 +277,7 @@ TALER_amount_cmp (const struct TALER_Amount *a1,
* #GNUNET_NO if the currencies are different
* #GNUNET_SYSERR if either amount is invalid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_amount_cmp_currency (const struct TALER_Amount *a1,
const struct TALER_Amount *a2);
@@ -228,7 +291,7 @@ TALER_amount_cmp_currency (const struct TALER_Amount *a1,
* #GNUNET_NO if the currencies are different
* #GNUNET_SYSERR if either amount is invalid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_amount_cmp_currency_nbo (const struct TALER_AmountNBO *a1,
const struct TALER_AmountNBO *a2);
@@ -314,6 +377,32 @@ TALER_amount_divide (struct TALER_Amount *result,
const struct TALER_Amount *dividend,
uint32_t divisor);
+/**
+ * Divide one amount by another. Note that this function
+ * may introduce a rounding error. It rounds down.
+ *
+ * @param dividend amount to divide
+ * @param divisor by what to divide, must be positive
+ * @return @a dividend / @a divisor, rounded down. -1 on currency mismatch,
+ * INT_MAX for division by zero
+ */
+int
+TALER_amount_divide2 (const struct TALER_Amount *dividend,
+ const struct TALER_Amount *divisor);
+
+
+/**
+ * Multiply an @a amount by a @ factor.
+ *
+ * @param[out] result where to store @a amount * @a factor
+ * @param amount amount to multiply
+ * @param factor factor by which to multiply
+ */
+enum TALER_AmountArithmeticResult
+TALER_amount_multiply (struct TALER_Amount *result,
+ const struct TALER_Amount *amount,
+ uint32_t factor);
+
/**
* Normalize the given amount.
@@ -323,7 +412,7 @@ TALER_amount_divide (struct TALER_Amount *result,
* #GNUNET_NO if value was already normalized
* #GNUNET_SYSERR if value was invalid or could not be normalized
*/
-int
+enum GNUNET_GenericReturnValue
TALER_amount_normalize (struct TALER_Amount *amount);
@@ -361,7 +450,7 @@ TALER_amount2s (const struct TALER_Amount *amount);
* @return #GNUNET_OK on success, #GNUNET_NO if rounding was unnecessary,
* #GNUNET_SYSERR if the amount or currency or @a round_unit was invalid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_amount_round_down (struct TALER_Amount *amount,
const struct TALER_Amount *round_unit);
diff --git a/src/include/taler_attributes.h b/src/include/taler_attributes.h
new file mode 100644
index 000000000..862a26928
--- /dev/null
+++ b/src/include/taler_attributes.h
@@ -0,0 +1,129 @@
+/*
+ This file is part of GNU Taler
+ Copyright (C) 2023 Taler Systems SA
+
+ GNU Taler is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: LGPL3.0-or-later
+
+ Note: the LGPL does not apply to all components of GNU Taler,
+ but it does apply to this file.
+ */
+/**
+ * @file src/include/taler_attributes.h
+ * @brief GNU Taler database event types, TO BE generated via https://gana.gnunet.org/
+ */
+#ifndef GNU_TALER_ATTRIBUTES_H
+#define GNU_TALER_ATTRIBUTES_H
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+/**
+ * Legal name of the business/company.
+ */
+#define TALER_ATTRIBUTE_COMPANY_NAME "company_name"
+
+/**
+ * Legal country of registration of the business/company,
+ * 2-letter country code using ISO 3166-2.
+ */
+#define TALER_ATTRIBUTE_REGISTRATION_COUNTRY "registration_country"
+
+/**
+ * Full name, when known/possible using "Lastname, Firstname(s)" format,
+ * but "Firstname(s) Lastname" or "Firstname M. Lastname" should also be
+ * tolerated (as is "Name", especially if the person only has one name).
+ * If the person has no name, an empty string must be given.
+ * NULL for not collected.
+ */
+#define TALER_ATTRIBUTE_FULL_NAME "full_name"
+
+/**
+ * True/false indicator if the individual is a politically
+ * exposed person.
+ */
+#define TALER_ATTRIBUTE_PEP "pep"
+
+/**
+ * Street-level address. Usually includes the street and the house number. May
+ * consist of multiple lines (separated by '\n'). Identifies a house in a city. The city is not
+ * part of the street.
+ */
+#define TALER_ATTRIBUTE_ADDRESS_STREET "street"
+
+/**
+ * City including postal code. If available, a 2-letter country-code prefixes
+ * the postal code, which is before the city (e.g. "DE-42289 Wuppertal"). If
+ * the country code is unknown, the "CC-" prefix is missing. If the ZIP code
+ * is unknown, the hyphen is followed by a space ("DE- Wuppertal"). If only
+ * the city name is known, it is prefixed by a space (" ").
+ * If the city name is unknown, a space is at the end of the value.
+ */
+#define TALER_ATTRIBUTE_ADDRESS_CITY "city"
+
+/**
+ * Phone number (of business or individual). Should come with the "+CC"
+ * prefix including the country code.
+ */
+#define TALER_ATTRIBUTE_PHONE "phone"
+
+/**
+ * Email address (of business or individual). Should be
+ * in the format "user@hostname".
+ */
+#define TALER_ATTRIBUTE_EMAIL "email"
+
+/**
+ * Birthdate of the person, as far as known. YYYY-MM-DD, a value
+ * of 0 (for DD, MM or even YYYY) is to be used for 'unknown'
+ * according to official records.
+ * Thus, 1950-00-00 stands for a birthdate in 1950 with unknown
+ * day and month. If official documents record January 1st or
+ * some other date instead, that day may also be specified.
+ * NULL for not collected.
+ */
+#define TALER_ATTRIBUTE_BIRTHDATE "birthdate"
+
+/**
+ * Citizenship(s) of the person using 2-letter country codes ("US", "DE",
+ * "FR", "IT", etc.) separated by commas if multiple citizenships are
+ * confirmed ("EN,US,DE"). Note that in the latter case it is not guaranteed
+ * that all nationalities were necessarily recorded. Empty string for
+ * stateless persons. NULL for not collected.
+ */
+#define TALER_ATTRIBUTE_NATIONALITIES "nationalities"
+
+/**
+ * Residence countries(s) of the person using 2-letter country codes ("US",
+ * "DE", "FR", "IT", etc.) separated by commas if multiple residences are
+ * confirmed ("EN,US,DE"). Note that in the latter case it is not guaranteed
+ * that all residences were necessarily recorded. Empty string for
+ * international nomads. NULL for not collected.
+ */
+#define TALER_ATTRIBUTE_RESIDENCES "residences"
+
+
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/include/taler_auditor_service.h b/src/include/taler_auditor_service.h
index 27959a889..36ea781b1 100644
--- a/src/include/taler_auditor_service.h
+++ b/src/include/taler_auditor_service.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2020 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -16,6 +16,8 @@
/**
* @file include/taler_auditor_service.h
* @brief C interface of libtalerauditor, a C library to use auditor's HTTP API
+ * This library is not thread-safe, all APIs must only be used from a single thread.
+ * This library calls abort() if it runs out of memory. Be aware of these limitations.
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
*/
@@ -28,12 +30,12 @@
#include <gnunet/gnunet_curl_lib.h>
-/* ********************* /version *********************** */
+/* ********************* /config *********************** */
/**
- * @brief Information we get from the auditor about auditors.
+ * @brief Information we get from the auditor about itself.
*/
-struct TALER_AUDITOR_VersionInformation
+struct TALER_AUDITOR_ConfigInformation
{
/**
* Public key of the auditing institution. Wallets and merchants
@@ -44,6 +46,11 @@ struct TALER_AUDITOR_VersionInformation
struct TALER_AuditorPublicKeyP auditor_pub;
/**
+ * Master public key of the audited exchange.
+ */
+ struct TALER_MasterPublicKeyP exchange_master_public_key;
+
+ /**
* Supported Taler protocol version by the auditor.
* String in the format current:revision:age using the
* semantics of GNU libtool. See
@@ -147,56 +154,90 @@ struct TALER_AUDITOR_HttpResponse
/**
+ * Response to /config request.
+ */
+struct TALER_AUDITOR_ConfigResponse
+{
+ /**
+ * HTTP response.
+ */
+ struct TALER_AUDITOR_HttpResponse hr;
+
+ /**
+ * Details depending on HTTP status.
+ */
+ union
+ {
+
+ /**
+ * Details for #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * Protocol compatibility evaluation.
+ */
+ enum TALER_AUDITOR_VersionCompatibility compat;
+
+ /**
+ * Config data returned by /config.
+ */
+ struct TALER_AUDITOR_ConfigInformation vi;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
* Function called with information about the auditor.
*
* @param cls closure
- * @param hr HTTP response data
- * @param vi basic information about the auditor
- * @param compat protocol compatibility information
+ * @param vr response data
*/
typedef void
-(*TALER_AUDITOR_VersionCallback) (
+(*TALER_AUDITOR_ConfigCallback) (
void *cls,
- const struct TALER_AUDITOR_HttpResponse *hr,
- const struct TALER_AUDITOR_VersionInformation *vi,
- enum TALER_AUDITOR_VersionCompatibility compat);
+ const struct TALER_AUDITOR_ConfigResponse *vr);
/**
* @brief Handle to the auditor. This is where we interact with
* a particular auditor and keep the per-auditor information.
*/
-struct TALER_AUDITOR_Handle;
+struct TALER_AUDITOR_GetConfigHandle;
/**
- * Initialise a connection to the auditor. Will connect to the
+ * Obtain meta data about an auditor. Will connect to the
* auditor and obtain information about the auditor's master public
* key and the auditor's auditor. The respective information will
- * be passed to the @a version_cb once available, and all future
- * interactions with the auditor will be checked to be signed
- * (where appropriate) by the respective master key.
+ * be passed to the @a config_cb once available.
*
- * @param ctx the context
+ * @param ctx the context for CURL requests
* @param url HTTP base URL for the auditor
- * @param version_cb function to call with the auditor's version information
- * @param version_cb_cls closure for @a version_cb
+ * @param config_cb function to call with the auditor's config information
+ * @param config_cb_cls closure for @a config_cb
* @return the auditor handle; NULL upon error
*/
-struct TALER_AUDITOR_Handle *
-TALER_AUDITOR_connect (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_AUDITOR_VersionCallback version_cb,
- void *version_cb_cls);
+struct TALER_AUDITOR_GetConfigHandle *
+TALER_AUDITOR_get_config (struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_AUDITOR_ConfigCallback config_cb,
+ void *config_cb_cls);
/**
- * Disconnect from the auditor.
+ * Cancel auditor config request.
*
- * @param auditor the auditor handle
+ * @param[in] auditor the auditor handle
*/
void
-TALER_AUDITOR_disconnect (struct TALER_AUDITOR_Handle *auditor);
+TALER_AUDITOR_get_config_cancel (
+ struct TALER_AUDITOR_GetConfigHandle *auditor);
/**
@@ -206,16 +247,28 @@ struct TALER_AUDITOR_DepositConfirmationHandle;
/**
+ * Response to /deposit-confirmation request.
+ */
+struct TALER_AUDITOR_DepositConfirmationResponse
+{
+ /**
+ * HTTP response.
+ */
+ struct TALER_AUDITOR_HttpResponse hr;
+};
+
+
+/**
* Signature of functions called with the result from our call to the
* auditor's /deposit-confirmation handler.
*
* @param cls closure
- * @param hr HTTP response data
+ * @param dcr response data
*/
typedef void
(*TALER_AUDITOR_DepositConfirmationResultCallback)(
void *cls,
- const struct TALER_AUDITOR_HttpResponse *hr);
+ const struct TALER_AUDITOR_DepositConfirmationResponse *dcr);
/**
@@ -225,19 +278,23 @@ typedef void
* that the response is well-formed. If the auditor's reply is not
* well-formed, we return an HTTP status code of zero to @a cb.
*
- * We also verify that the @a exchange_sig is valid for this deposit-confirmation
- * request, and that the @a master_sig is a valid signature for @a
- * exchange_pub. Also, the @a auditor must be ready to operate (i.e. have
- * finished processing the /version reply). If either check fails, we do
- * NOT initiate the transaction with the auditor and instead return NULL.
+ * We also verify that the @a exchange_sig is valid for this
+ * deposit-confirmation request, and that the @a master_sig is a valid
+ * signature for @a exchange_pub. If the check fails, we do NOT initiate the
+ * transaction with the auditor and instead return NULL.
*
- * @param auditor the auditor handle; the auditor must be ready to operate
+ * @param ctx the context for CURL requests
+ * @param url HTTP base URL for the auditor
* @param h_wire hash of merchant wire details
+ * @param h_policy hash over the policy, if any
* @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the auditor)
- * @param timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param exchange_timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param wire_deadline date until which the exchange should wire the funds
* @param refund_deadline date until which the merchant can issue a refund to the customer via the auditor (can be zero if refunds are not allowed); must not be after the @a wire_deadline
- * @param amount_without_fee the amount confirmed to be wired by the exchange to the merchant
- * @param coin_pub coin’s public key
+ * @param total_without_fee the amount confirmed to be wired by the exchange to the merchant
+ * @param num_coins number of coins involved in the batch deposit
+ * @param coin_pubs array of the coin’s public keys
+ * @param coin_sigs array of the original deposit signatures of the coins in the batch
* @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
* @param exchange_sig the signature made with purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT
* @param exchange_pub the public key of the exchange that matches @a exchange_sig
@@ -253,20 +310,25 @@ typedef void
*/
struct TALER_AUDITOR_DepositConfirmationHandle *
TALER_AUDITOR_deposit_confirmation (
- struct TALER_AUDITOR_Handle *auditor,
- const struct GNUNET_HashCode *h_wire,
- const struct GNUNET_HashCode *h_contract_terms,
- struct GNUNET_TIME_Absolute timestamp,
- struct GNUNET_TIME_Absolute refund_deadline,
- const struct TALER_Amount *amount_without_fee,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
+ struct GNUNET_TIME_Timestamp wire_deadline,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ const struct TALER_Amount *total_without_fee,
+ unsigned int num_coins,
+ const struct TALER_CoinSpendPublicKeyP *coin_pubs[static num_coins],
+ const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_ExchangePublicKeyP *exchange_pub,
const struct TALER_ExchangeSignatureP *exchange_sig,
const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Absolute ep_start,
- struct GNUNET_TIME_Absolute ep_expire,
- struct GNUNET_TIME_Absolute ep_end,
+ struct GNUNET_TIME_Timestamp ep_start,
+ struct GNUNET_TIME_Timestamp ep_expire,
+ struct GNUNET_TIME_Timestamp ep_end,
const struct TALER_MasterSignatureP *master_sig,
TALER_AUDITOR_DepositConfirmationResultCallback cb,
void *cb_cls);
@@ -283,72 +345,4 @@ TALER_AUDITOR_deposit_confirmation_cancel (
struct TALER_AUDITOR_DepositConfirmationHandle *deposit_confirmation);
-/**
- * Handle for /exchanges API returned by
- * #TALER_AUDITOR_list_exchanges() so that the operation can be
- * cancelled with #TALER_AUDITOR_list_exchanges_cancel()
- */
-struct TALER_AUDITOR_ListExchangesHandle;
-
-
-/**
- * Information about an exchange kept by the auditor.
- */
-struct TALER_AUDITOR_ExchangeInfo
-{
- /**
- * Master public key of the exchange.
- */
- struct TALER_MasterPublicKeyP master_pub;
-
- /**
- * Base URL of the exchange's API.
- */
- const char *exchange_url;
-};
-
-
-/**
- * Function called with the result from /exchagnes.
- *
- * @param cls closure
- * @param hr HTTP response data
- * @param num_exchanges length of array at @a ei
- * @param ei information about exchanges returned by the auditor
- */
-typedef void
-(*TALER_AUDITOR_ListExchangesResultCallback)(
- void *cls,
- const struct TALER_AUDITOR_HttpResponse *hr,
- unsigned int num_exchanges,
- const struct TALER_AUDITOR_ExchangeInfo *ei);
-
-/**
- * Submit an /exchanges request to the auditor and get the
- * auditor's response. If the auditor's reply is not
- * well-formed, we return an HTTP status code of zero to @a cb.
- *
- * @param auditor the auditor handle; the auditor must be ready to operate
- * @param cb the callback to call when a reply for this request is available
- * @param cb_cls closure for the above callback
- * @return a handle for this request; NULL if the inputs are invalid (i.e.
- * signatures fail to verify). In this case, the callback is not called.
- */
-struct TALER_AUDITOR_ListExchangesHandle *
-TALER_AUDITOR_list_exchanges (struct TALER_AUDITOR_Handle *auditor,
- TALER_AUDITOR_ListExchangesResultCallback cb,
- void *cb_cls);
-
-
-/**
- * Cancel a list exchanges request. This function cannot be used
- * on a request handle if a response is already served for it.
- *
- * @param leh the list exchanges request handle
- */
-void
-TALER_AUDITOR_list_exchanges_cancel (
- struct TALER_AUDITOR_ListExchangesHandle *leh);
-
-
#endif /* _TALER_AUDITOR_SERVICE_H */
diff --git a/src/include/taler_auditordb_plugin.h b/src/include/taler_auditordb_plugin.h
index 9a7f6ed7a..c0a771343 100644
--- a/src/include/taler_auditordb_plugin.h
+++ b/src/include/taler_auditordb_plugin.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -25,43 +25,12 @@
#include <jansson.h>
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_db_lib.h>
+#include "taler_util.h"
#include "taler_auditordb_lib.h"
#include "taler_signatures.h"
/**
- * Function called with information about exchanges this
- * auditor is monitoring.
- *
- * @param cls closure
- * @param master_pub master public key of the exchange
- * @param exchange_url base URL of the exchange's API
- */
-typedef void
-(*TALER_AUDITORDB_ExchangeCallback)(
- void *cls,
- const struct TALER_MasterPublicKeyP *master_pub,
- const char *exchange_url);
-
-
-/**
- * Function called with the results of select_denomination_info()
- *
- * @param cls closure
- * @param issue issuing information with value, fees and other info about the denomination.
- *
- * @return sets the return value of select_denomination_info(),
- * #GNUNET_OK to continue,
- * #GNUNET_NO to stop processing further rows
- * #GNUNET_SYSERR or other values on error.
- */
-typedef int
-(*TALER_AUDITORDB_DenominationInfoDataCallback)(
- void *cls,
- const struct TALER_DenominationKeyValidityPS *issue);
-
-
-/**
* Function called with the results of select_historic_denom_revenue()
*
* @param cls closure
@@ -76,11 +45,11 @@ typedef int
* #GNUNET_NO to stop processing further rows
* #GNUNET_SYSERR or other values on error.
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_AUDITORDB_HistoricDenominationRevenueDataCallback)(
void *cls,
- const struct GNUNET_HashCode *denom_pub_hash,
- struct GNUNET_TIME_Absolute revenue_timestamp,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ struct GNUNET_TIME_Timestamp revenue_timestamp,
const struct TALER_Amount *revenue_balance,
const struct TALER_Amount *loss_balance);
@@ -98,262 +67,210 @@ typedef int
* #GNUNET_NO to stop processing further rows
* #GNUNET_SYSERR or other values on error.
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_AUDITORDB_HistoricReserveRevenueDataCallback)(
void *cls,
- struct GNUNET_TIME_Absolute start_time,
- struct GNUNET_TIME_Absolute end_time,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
const struct TALER_Amount *reserve_profits);
/**
- * Structure for remembering the wire auditor's progress over the
- * various tables and (auditor) transactions.
- */
-struct TALER_AUDITORDB_WireProgressPoint
-{
-
- /**
- * Time until which we have confirmed that all wire transactions
- * that the exchange should do, have indeed been done.
- */
- struct GNUNET_TIME_Absolute last_timestamp;
-
- /**
- * reserves_close uuid until which we have checked
- * reserve closures.
- */
- uint64_t last_reserve_close_uuid;
-};
-
-
-/**
- * Structure for remembering the wire auditor's progress over the
- * various tables and (auditor) transactions per wire account.
+ * Information about a signing key of an exchange.
*/
-struct TALER_AUDITORDB_WireAccountProgressPoint
+struct TALER_AUDITORDB_ExchangeSigningKey
{
- /**
- * serial ID of the last reserve_in transfer the wire auditor processed
- */
- uint64_t last_reserve_in_serial_id;
/**
- * serial ID of the last wire_out the wire auditor processed
+ * When does @e exchange_pub start to be used?
*/
- uint64_t last_wire_out_serial_id;
+ struct GNUNET_TIME_Timestamp ep_start;
-};
-
-
-/**
- * Structure for remembering the auditor's progress over the various
- * tables and (auditor) transactions when analyzing reserves.
- */
-struct TALER_AUDITORDB_ProgressPointReserve
-{
/**
- * serial ID of the last reserve_in transfer the auditor processed
+ * When will the exchange stop signing with @e exchange_pub?
*/
- uint64_t last_reserve_in_serial_id;
+ struct GNUNET_TIME_Timestamp ep_expire;
/**
- * serial ID of the last reserve_out the auditor processed
+ * When does the signing key expire (for legal disputes)?
*/
- uint64_t last_reserve_out_serial_id;
+ struct GNUNET_TIME_Timestamp ep_end;
/**
- * serial ID of the last recoup entry the auditor processed when
- * considering reserves.
+ * What is the public offline signing key this is all about?
*/
- uint64_t last_reserve_recoup_serial_id;
+ struct TALER_ExchangePublicKeyP exchange_pub;
/**
- * serial ID of the last reserve_close
- * entry the auditor processed.
+ * Signature by the offline master key affirming the above.
*/
- uint64_t last_reserve_close_serial_id;
-
+ struct TALER_MasterSignatureP master_sig;
};
/**
- * Structure for remembering the auditor's progress over the various
- * tables and (auditor) transactions when analyzing reserves.
+ * Information about a deposit confirmation we received from
+ * a merchant.
*/
-struct TALER_AUDITORDB_ProgressPointDepositConfirmation
+struct TALER_AUDITORDB_DepositConfirmation
{
+
/**
- * serial ID of the last deposit_confirmation the auditor processed
+ * Hash over the contract for which this deposit is made.
*/
- uint64_t last_deposit_confirmation_serial_id;
-
-
-};
-
-
-/**
- * Structure for remembering the auditor's progress over the various
- * tables and (auditor) transactions when analyzing aggregations.
- */
-struct TALER_AUDITORDB_ProgressPointAggregation
-{
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
- * serial ID of the last prewire transfer the auditor processed
+ * Hash over the policy extension for the deposit.
*/
- uint64_t last_wire_out_serial_id;
-};
-
+ struct TALER_ExtensionPolicyHashP h_policy;
-/**
- * Structure for remembering the auditor's progress over the various
- * tables and (auditor) transactions when analyzing coins.
- */
-struct TALER_AUDITORDB_ProgressPointCoin
-{
/**
- * serial ID of the last withdraw the auditor processed
+ * Hash over the wiring information of the merchant.
*/
- uint64_t last_withdraw_serial_id;
+ struct TALER_MerchantWireHashP h_wire;
/**
- * serial ID of the last deposit the auditor processed
+ * Time when this deposit confirmation was generated by the exchange.
*/
- uint64_t last_deposit_serial_id;
+ struct GNUNET_TIME_Timestamp exchange_timestamp;
/**
- * serial ID of the last refresh the auditor processed
+ * How much time does the @e merchant have to issue a refund
+ * request? Zero if refunds are not allowed. After this time, the
+ * coin cannot be refunded. Note that the wire transfer will not be
+ * performed by the exchange until the refund deadline. This value
+ * is taken from the original deposit request.
*/
- uint64_t last_melt_serial_id;
+ struct GNUNET_TIME_Timestamp refund_deadline;
/**
- * serial ID of the last refund the auditor processed
+ * How much time does the @e exchange have to wire the funds?
*/
- uint64_t last_refund_serial_id;
+ struct GNUNET_TIME_Timestamp wire_deadline;
/**
- * Serial ID of the last recoup operation the auditor processed.
+ * Amount to be deposited, excluding fee. Calculated from the
+ * amount with fee and the fee from the deposit request.
*/
- uint64_t last_recoup_serial_id;
+ struct TALER_Amount total_without_fee;
/**
- * Serial ID of the last recoup-of-refresh operation the auditor processed.
+ * Length of the @e coin_pubs and @e coin_sigs arrays.
*/
- uint64_t last_recoup_refresh_serial_id;
-
-};
+ unsigned int num_coins;
-
-/**
- * Information about a signing key of an exchange.
- */
-struct TALER_AUDITORDB_ExchangeSigningKey
-{
/**
- * Public master key of the exchange that certified @e master_sig.
+ * Array of the coin public keys involved in the
+ * batch deposit operation.
*/
- struct TALER_MasterPublicKeyP master_public_key;
+ const struct TALER_CoinSpendPublicKeyP *coin_pubs;
/**
- * When does @e exchange_pub start to be used?
+ * Array of coin deposit signatures from the deposit operation.
*/
- struct GNUNET_TIME_Absolute ep_start;
+ const struct TALER_CoinSpendSignatureP *coin_sigs;
/**
- * When will the exchange stop signing with @e exchange_pub?
+ * The Merchant's public key. Allows the merchant to later refund
+ * the transaction or to inquire about the wire transfer identifier.
*/
- struct GNUNET_TIME_Absolute ep_expire;
+ struct TALER_MerchantPublicKeyP merchant;
/**
- * When does the signing key expire (for legal disputes)?
+ * Signature from the exchange of type
+ * #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.
*/
- struct GNUNET_TIME_Absolute ep_end;
+ struct TALER_ExchangeSignatureP exchange_sig;
/**
- * What is the public offline signing key this is all about?
+ * Public signing key from the exchange matching @e exchange_sig.
*/
struct TALER_ExchangePublicKeyP exchange_pub;
/**
- * Signature by the offline master key affirming the above.
+ * Exchange master signature over @e exchange_sig.
*/
struct TALER_MasterSignatureP master_sig;
+
};
/**
- * Information about a deposit confirmation we received from
- * a merchant.
+ * Balance values for a reserve (or all reserves).
*/
-struct TALER_AUDITORDB_DepositConfirmation
+struct TALER_AUDITORDB_ReserveFeeBalance
{
-
/**
- * Hash over the contract for which this deposit is made.
+ * Remaining funds.
*/
- struct GNUNET_HashCode h_contract_terms;
+ struct TALER_Amount reserve_balance;
/**
- * Hash over the wiring information of the merchant.
+ * Losses from operations that should not have
+ * happened (e.g. negative balance).
*/
- struct GNUNET_HashCode h_wire;
+ struct TALER_Amount reserve_loss;
/**
- * Time when this confirmation was generated.
+ * Fees charged for withdraw.
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct TALER_Amount withdraw_fee_balance;
/**
- * How much time does the @e merchant have to issue a refund
- * request? Zero if refunds are not allowed. After this time, the
- * coin cannot be refunded. Note that the wire transfer will not be
- * performed by the exchange until the refund deadline. This value
- * is taken from the original deposit request.
+ * Fees charged for closing.
*/
- struct GNUNET_TIME_Absolute refund_deadline;
+ struct TALER_Amount close_fee_balance;
/**
- * Amount to be deposited, excluding fee. Calculated from the
- * amount with fee and the fee from the deposit request.
+ * Fees charged for purse creation.
*/
- struct TALER_Amount amount_without_fee;
+ struct TALER_Amount purse_fee_balance;
/**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange. The deposit request is to be
- * signed by the corresponding private key (using EdDSA).
+ * Opening fees charged.
*/
- struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_Amount open_fee_balance;
/**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
+ * History fees charged.
*/
- struct TALER_MerchantPublicKeyP merchant;
+ struct TALER_Amount history_fee_balance;
+};
+
+/**
+ * Balance data for denominations in circulation.
+ */
+struct TALER_AUDITORDB_DenominationCirculationData
+{
/**
- * Signature from the exchange of type
- * #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.
+ * Amount of outstanding coins in circulation.
*/
- struct TALER_ExchangeSignatureP exchange_sig;
+ struct TALER_Amount denom_balance;
/**
- * Public signing key from the exchange matching @e exchange_sig.
+ * Amount lost due coins illicitly accepted (effectively, a
+ * negative @a denom_balance).
*/
- struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_Amount denom_loss;
/**
- * Exchange master signature over @e exchange_sig.
+ * Total amount that could still be theoretically lost in the future due to
+ * recoup operations. (Total put into circulation minus @e recoup_loss).
*/
- struct TALER_MasterSignatureP master_sig;
+ struct TALER_Amount denom_risk;
/**
- * Master public key of the exchange corresponding to @e master_sig.
- * Identifies the exchange this is about.
+ * Amount lost due to recoups.
*/
- struct TALER_MasterPublicKeyP master_public_key;
+ struct TALER_Amount recoup_loss;
+ /**
+ * Number of coins of this denomination that the exchange signed into
+ * existence.
+ */
+ uint64_t num_issued;
};
@@ -364,8 +281,9 @@ struct TALER_AUDITORDB_DepositConfirmation
* @param cls closure
* @param serial_id location of the @a dc in the database
* @param dc the deposit confirmation itself
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop iterating
*/
-typedef void
+typedef enum GNUNET_GenericReturnValue
(*TALER_AUDITORDB_DepositConfirmationCallback)(
void *cls,
uint64_t serial_id,
@@ -373,9 +291,39 @@ typedef void
/**
- * Handle for one session with the database.
+ * Function called on deposits that are past their due date
+ * and have not yet seen a wire transfer.
+ *
+ * @param cls closure
+ * @param batch_deposit_serial_id where in the table are we
+ * @param total_amount value of all missing deposits, including fees
+ * @param wire_target_h_payto hash of the recipient account's payto URI
+ * @param deadline what was the earliest requested wire transfer deadline
+ */
+typedef void
+(*TALER_AUDITORDB_WireMissingCallback)(
+ void *cls,
+ uint64_t batch_deposit_serial_id,
+ const struct TALER_Amount *total_amount,
+ const struct TALER_PaytoHashP *wire_target_h_payto,
+ struct GNUNET_TIME_Timestamp deadline);
+
+
+/**
+ * Function called on expired purses.
+ *
+ * @param cls closure
+ * @param purse_pub public key of the purse
+ * @param balance amount of money in the purse
+ * @param expiration_date when did the purse expire?
+ * @return #GNUNET_OK to continue to iterate
*/
-struct TALER_AUDITORDB_Session;
+typedef enum GNUNET_GenericReturnValue
+(*TALER_AUDITORDB_ExpiredPurseCallback)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *balance,
+ struct GNUNET_TIME_Timestamp expiration_date);
/**
@@ -400,14 +348,58 @@ struct TALER_AUDITORDB_Plugin
char *library_name;
/**
- * Get the thread-local database-handle.
- * Connect to the db if the connection does not exist yet.
+ * Fully connect to the db if the connection does not exist yet
+ * and check that there is no transaction currently running.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param the database connection, or NULL on error
+ * @return #GNUNET_OK on success
+ * #GNUNET_NO if we rolled back an earlier transaction
+ * #GNUNET_SYSERR if we have no DB connection
*/
- struct TALER_AUDITORDB_Session *
- (*get_session) (void *cls);
+ enum GNUNET_GenericReturnValue
+ (*preflight)(void *cls);
+
+
+ /**
+ * Register callback to be invoked on events of type @a es.
+ *
+ * @param cls database context to use
+ * @param es specification of the event to listen for
+ * @param timeout how long to wait for the event
+ * @param cb function to call when the event happens, possibly
+ * mulrewardle times (until cancel is invoked)
+ * @param cb_cls closure for @a cb
+ * @return handle useful to cancel the listener
+ */
+ struct GNUNET_DB_EventHandler *
+ (*event_listen)(void *cls,
+ const struct GNUNET_DB_EventHeaderP *es,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_DB_EventCallback cb,
+ void *cb_cls);
+
+ /**
+ * Stop notifications.
+ *
+ * @param eh handle to unregister.
+ */
+ void
+ (*event_listen_cancel)(struct GNUNET_DB_EventHandler *eh);
+
+
+ /**
+ * Notify all that listen on @a es of an event.
+ *
+ * @param cls database context to use
+ * @param es specification of the event to generate
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+ void
+ (*event_notify)(void *cls,
+ const struct GNUNET_DB_EventHeaderP *es,
+ const void *extra,
+ size_t extra_size);
/**
@@ -421,54 +413,52 @@ struct TALER_AUDITORDB_Plugin
* used when restarting the auditor
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
- int
- (*drop_tables) (void *cls,
- int drop_exchangelist);
+ enum GNUNET_GenericReturnValue
+ (*drop_tables)(void *cls,
+ bool drop_exchangelist);
/**
* Create the necessary tables if they are not present
*
* @param cls the @e cls of this struct with the plugin-specific state
+ * @param support_partitions true to support partitioning
+ * @param num_partitions number of partitions to use
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
- int
- (*create_tables) (void *cls);
+ enum GNUNET_GenericReturnValue
+ (*create_tables)(void *cls,
+ bool support_partitions,
+ uint32_t num_partitions);
/**
* Start a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @return #GNUNET_OK on success
*/
- int
- (*start) (void *cls,
- struct TALER_AUDITORDB_Session *session);
+ enum GNUNET_GenericReturnValue
+ (*start)(void *cls);
/**
* Commit a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*commit)(void *cls,
- struct TALER_AUDITORDB_Session *session);
+ (*commit)(void *cls);
/**
* Abort/rollback a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
*/
void
- (*rollback) (void *cls,
- struct TALER_AUDITORDB_Session *session);
+ (*rollback) (void *cls);
/**
@@ -479,263 +469,26 @@ struct TALER_AUDITORDB_Plugin
* @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors
*/
- int
- (*gc) (void *cls);
-
-
- /**
- * Insert information about an exchange this auditor will be auditing.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param master_pub master public key of the exchange
- * @param exchange_url public (base) URL of the API of the exchange
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*insert_exchange)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const char *exchange_url);
-
-
- /**
- * Delete an exchange from the list of exchanges this auditor is auditing.
- * Warning: this will cascade and delete all knowledge of this auditor related
- * to this exchange!
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param master_pub master public key of the exchange
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*delete_exchange)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub);
-
-
- /**
- * Obtain information about exchanges this auditor is auditing.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param cb function to call with the results
- * @param cb_cls closure for @a cb
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*list_exchanges)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- TALER_AUDITORDB_ExchangeCallback cb,
- void *cb_cls);
-
- /**
- * Insert information about a signing key of the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param sk signing key information to store
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*insert_exchange_signkey)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_AUDITORDB_ExchangeSigningKey *sk);
-
-
- /**
- * Insert information about a deposit confirmation into the database.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param dc deposit confirmation information to store
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*insert_deposit_confirmation)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_AUDITORDB_DepositConfirmation *dc);
-
-
- /**
- * Get information about deposit confirmations from the database.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param master_public_key for which exchange do we want to get deposit confirmations
- * @param start_id row/serial ID where to start the iteration (0 from
- * the start, exclusive, i.e. serial_ids must start from 1)
- * @param cb function to call with results
- * @param cb_cls closure for @a cb
- * @return query result status
- */
- enum GNUNET_DB_QueryStatus
- (*get_deposit_confirmations)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_public_key,
- uint64_t start_id,
- TALER_AUDITORDB_DepositConfirmationCallback cb,
- void *cb_cls);
-
-
- /**
- * Insert information about a denomination key and in particular
- * the properties (value, fees, expiration times) the coins signed
- * with this key have.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param issue issuing information with value, fees and other info about the denomination
- * @return status of database operation
- */
- enum GNUNET_DB_QueryStatus
- (*insert_denomination_info)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_DenominationKeyValidityPS *issue);
-
-
- /**
- * Get information about denomination keys of a particular exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param cb function to call with the results
- * @param cb_cls closure for @a cb
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*select_denomination_info)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- TALER_AUDITORDB_DenominationInfoDataCallback cb,
- void *cb_cls);
-
-
- /**
- * Insert information about the auditor's progress with an exchange's
- * data.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppc where is the auditor in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*insert_auditor_progress_coin)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointCoin *ppc);
-
-
- /**
- * Update information about the progress of the auditor. There
- * must be an existing record for the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppc where is the auditor in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*update_auditor_progress_coin)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointCoin *ppc);
-
-
- /**
- * Get information about the progress of the auditor.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] ppc set to where the auditor is in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*get_auditor_progress_coin)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_AUDITORDB_ProgressPointCoin *ppc);
-
- /**
- * Insert information about the auditor's progress with an exchange's
- * data.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppr where is the auditor in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*insert_auditor_progress_reserve)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointReserve *ppr);
-
+ enum GNUNET_GenericReturnValue
+ (*gc)(void *cls);
- /**
- * Update information about the progress of the auditor. There
- * must be an existing record for the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppr where is the auditor in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*update_auditor_progress_reserve)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointReserve *ppr);
-
-
- /**
- * Get information about the progress of the auditor.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] ppr set to where the auditor is in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*get_auditor_progress_reserve)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_AUDITORDB_ProgressPointReserve *ppr);
/**
* Insert information about the auditor's progress with an exchange's
* data.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppdc where is the auditor in processing
+ * @param progress_key name of the progress indicator
+ * @param progress_offset offset until which we have made progress
+ * @param ... NULL terminated list of additional key-value pairs to insert
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_auditor_progress_deposit_confirmation)(
+ (*insert_auditor_progress)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc);
+ const char *progress_key,
+ uint64_t progress_offset,
+ ...);
/**
@@ -743,213 +496,142 @@ struct TALER_AUDITORDB_Plugin
* must be an existing record for the exchange.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppdc where is the auditor in processing
+ * @param progress_key name of the progress indicator
+ * @param progress_offset offset until which we have made progress
+ * @param ... NULL terminated list of additional key-value pairs to update
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_auditor_progress_deposit_confirmation)(
+ (*update_auditor_progress)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc);
+ const char *progress_key,
+ uint64_t progress_offset,
+ ...);
/**
* Get information about the progress of the auditor.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] ppdc set to where the auditor is in processing
+ * @param progress_key name of the progress indicator
+ * @param[out] progress_offset set to offset until which we have made progress, set to 0 if key was not found
+ * @param ... NULL terminated list of additional key-value pairs to fetch
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_auditor_progress_deposit_confirmation)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_AUDITORDB_ProgressPointDepositConfirmation *ppdc);
+ (*get_auditor_progress)(void *cls,
+ const char *progress_key,
+ uint64_t *progress_offset,
+ ...);
/**
- * Insert information about the auditor's progress with an exchange's
- * data.
+ * Insert information about a balance tracked by the auditor. There must not be an
+ * existing record.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppa where is the auditor in processing
+ * @param balance_key key of the balance to store
+ * @param balance_value value to store
+ * @param ... NULL terminated list of additional key-value pairs to insert
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_auditor_progress_aggregation)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointAggregation *ppa);
+ (*insert_balance)(void *cls,
+ const char *balance_key,
+ const struct TALER_Amount *balance_value,
+ ...);
/**
- * Update information about the progress of the auditor. There
- * must be an existing record for the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param ppa where is the auditor in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*update_auditor_progress_aggregation)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_ProgressPointAggregation *ppa);
-
-
- /**
- * Get information about the progress of the auditor.
+ * Insert information about a balance tracked by the auditor. Destructively updates an
+ * existing record, which must already exist.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] ppa set to where the auditor is in processing
+ * @param balance_key key of the balance to store
+ * @param balance_amount value to store
+ * @param ... NULL terminated list of additional key-value pairs to update
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_auditor_progress_aggregation)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_AUDITORDB_ProgressPointAggregation *ppa);
+ (*update_balance)(void *cls,
+ const char *balance_key,
+ const struct TALER_Amount *balance_amount,
+ ...);
/**
- * Insert information about the wire auditor's progress with an exchange's
- * data.
+ * Get summary information about balance tracked by the auditor.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param pp where is the auditor in processing
- * @param in_wire_off how far are we in the incoming wire transaction history
- * @param out_wire_off how far are we in the outgoing wire transaction history
+ * @param balance_key key of the balance to store
+ * @param[out] balance_value set to amount stored under @a balance_key, set to invalid amount (all zero) if key was not found
+ * @param ... NULL terminated list of additional key-value pairs to fetch
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_wire_auditor_account_progress)(
- void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const char *account_name,
- const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
- uint64_t in_wire_off,
- uint64_t out_wire_off);
+ (*get_balance)(void *cls,
+ const char *balance_key,
+ struct TALER_Amount *balance_value,
+ ...);
/**
- * Update information about the progress of the wire auditor. There
- * must be an existing record for the exchange.
+ * Insert information about a signing key of the exchange.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param pp where is the auditor in processing
- * @param in_wire_off how far are we in the incoming wire transaction history
- * @param out_wire_off how far are we in the outgoing wire transaction history
- * @return transaction status code
+ * @param sk signing key information to store
+ * @return query result status
*/
enum GNUNET_DB_QueryStatus
- (*update_wire_auditor_account_progress)(
+ (*insert_exchange_signkey)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const char *account_name,
- const struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
- uint64_t in_wire_off,
- uint64_t out_wire_off);
+ const struct TALER_AUDITORDB_ExchangeSigningKey *sk);
/**
- * Get information about the progress of the wire auditor.
+ * Insert information about a deposit confirmation into the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param[out] pp where is the auditor in processing
- * @param[out] in_wire_off how far are we in the incoming wire transaction history
- * @param[out] out_wire_off how far are we in the outgoing wire transaction history
- * @return transaction status code
+ * @param dc deposit confirmation information to store
+ * @return query result status
*/
enum GNUNET_DB_QueryStatus
- (*get_wire_auditor_account_progress)(
+ (*insert_deposit_confirmation)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const char *account_name,
- struct TALER_AUDITORDB_WireAccountProgressPoint *pp,
- uint64_t *in_wire_off,
- uint64_t *out_wire_off);
+ const struct TALER_AUDITORDB_DepositConfirmation *dc);
/**
- * Insert information about the wire auditor's progress with an exchange's
- * data.
+ * Get information about deposit confirmations from the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param pp where is the auditor in processing
- * @return transaction status code
+ * @param start_id row/serial ID where to start the iteration (0 from
+ * the start, exclusive, i.e. serial_ids must start from 1)
+ * @param return_suppressed should suppressed rows be returned anyway?
+ * @param cb function to call with results
+ * @param cb_cls closure for @a cb
+ * @return query result status
*/
enum GNUNET_DB_QueryStatus
- (*insert_wire_auditor_progress)(
+ (*get_deposit_confirmations)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_WireProgressPoint *pp);
+ uint64_t start_id,
+ bool return_suppressed,
+ TALER_AUDITORDB_DepositConfirmationCallback cb,
+ void *cb_cls);
/**
- * Update information about the progress of the wire auditor. There
- * must be an existing record for the exchange.
+ * Delete information about a deposit confirmation from the database.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param pp where is the auditor in processing
- * @return transaction status code
+ * @param row_id row to delete
+ * @return query result status
*/
enum GNUNET_DB_QueryStatus
- (*update_wire_auditor_progress)(
+ (*delete_deposit_confirmation)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_AUDITORDB_WireProgressPoint *pp);
-
-
- /**
- * Get information about the progress of the wire auditor.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param account_name name of the wire account we are auditing
- * @param[out] pp set to where the auditor is in processing
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*get_wire_auditor_progress)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_AUDITORDB_WireProgressPoint *pp);
+ uint64_t row_id);
/**
@@ -957,25 +639,19 @@ struct TALER_AUDITORDB_Plugin
* existing record for the reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param reserve_pub public key of the reserve
- * @param master_pub master public key of the exchange
- * @param reserve_balance amount stored in the reserve
- * @param withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param rfb balance amounts for the reserve
* @param expiration_date expiration date of the reserve
* @param origin_account where did the money in the reserve originally come from
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_reserve_info)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *reserve_balance,
- const struct TALER_Amount *withdraw_fee_balance,
- struct GNUNET_TIME_Absolute expiration_date,
- const char *origin_account);
+ (*insert_reserve_info)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_AUDITORDB_ReserveFeeBalance *rfb,
+ struct GNUNET_TIME_Timestamp expiration_date,
+ const char *origin_account);
/**
@@ -983,352 +659,241 @@ struct TALER_AUDITORDB_Plugin
* existing record, which must already exist.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param reserve_pub public key of the reserve
- * @param master_pub master public key of the exchange
- * @param reserve_balance amount stored in the reserve
- * @param withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param rfb balance amounts for the reserve
* @param expiration_date expiration date of the reserve
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_reserve_info)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *reserve_balance,
- const struct TALER_Amount *withdraw_fee_balance,
- struct GNUNET_TIME_Absolute expiration_date);
+ (*update_reserve_info)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_AUDITORDB_ReserveFeeBalance *rfb,
+ struct GNUNET_TIME_Timestamp expiration_date);
/**
* Get information about a reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param reserve_pub public key of the reserve
- * @param master_pub master public key of the exchange
* @param[out] rowid which row did we get the information from
- * @param[out] reserve_balance amount stored in the reserve
- * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param[out] rfb set to balances associated with the reserve
* @param[out] expiration_date expiration date of the reserve
* @param[out] sender_account from where did the money in the reserve originally come from
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_reserve_info)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_MasterPublicKeyP *master_pub,
- uint64_t *rowid,
- struct TALER_Amount *reserve_balance,
- struct TALER_Amount *withdraw_fee_balance,
- struct GNUNET_TIME_Absolute *expiration_date,
- char **sender_account);
+ (*get_reserve_info)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t *rowid,
+ struct TALER_AUDITORDB_ReserveFeeBalance *rfb,
+ struct GNUNET_TIME_Timestamp *expiration_date,
+ char **sender_account);
/**
* Delete information about a reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param reserve_pub public key of the reserve
- * @param master_pub master public key of the exchange
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*del_reserve_info)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_MasterPublicKeyP *master_pub);
+ const struct TALER_ReservePublicKeyP *reserve_pub);
/**
- * Insert information about all reserves. There must not be an
- * existing record for the @a master_pub.
+ * Insert new row into the pending deposits table.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param reserve_balance amount stored in the reserve
- * @param withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param batch_deposit_serial_id where in the table are we
+ * @param total_amount value of all missing deposits, including fees
+ * @param wire_target_h_payto hash of the recipient account's payto URI
+ * @param deadline what was the requested wire transfer deadline
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_reserve_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *reserve_balance,
- const struct TALER_Amount *withdraw_fee_balance);
+ (*insert_pending_deposit)(
+ void *cls,
+ uint64_t batch_deposit_serial_id,
+ const struct TALER_PaytoHashP *wire_target_h_payto,
+ const struct TALER_Amount *total_amount,
+ struct GNUNET_TIME_Timestamp deadline);
/**
- * Update information about all reserves. Destructively updates an
- * existing record, which must already exist.
+ * Delete a row from the pending deposit table.
+ * Usually done when the respective wire transfer
+ * was finally detected.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param reserve_balance amount stored in the reserve
- * @param withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param batch_deposit_serial_id which entry to delete
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_reserve_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *reserve_balance,
- const struct TALER_Amount *withdraw_fee_balance);
+ (*delete_pending_deposit)(
+ void *cls,
+ uint64_t batch_deposit_serial_id);
/**
- * Get summary information about all reserves.
+ * Return (batch) deposits for which we have not yet
+ * seen the required wire transfer.
*
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param[out] reserve_balance amount stored in the reserve
- * @param[out] withdraw_fee_balance amount the exchange gained in withdraw fees
- * due to withdrawals from this reserve
+ * @param deadline only return up to this deadline
+ * @param cb function to call on each entry
+ * @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_reserve_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_Amount *reserve_balance,
- struct TALER_Amount *withdraw_fee_balance);
+ (*select_pending_deposits)(
+ void *cls,
+ struct GNUNET_TIME_Absolute deadline,
+ TALER_AUDITORDB_WireMissingCallback cb,
+ void *cb_cls);
/**
- * Insert information about exchange's wire fee balance. There must not be an
- * existing record for the same @a master_pub.
+ * Insert information about a purse. There must not be an
+ * existing record for the purse.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param wire_fee_balance amount the exchange gained in wire fees
+ * @param purse_pub public key of the purse
+ * @param balance balance of the purse
+ * @param expiration_date expiration date of the purse
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_wire_fee_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *wire_fee_balance);
+ (*insert_purse_info)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *balance,
+ struct GNUNET_TIME_Timestamp expiration_date);
/**
- * Insert information about exchange's wire fee balance. Destructively updates an
+ * Update information about a purse. Destructively updates an
* existing record, which must already exist.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param wire_fee_balance amount the exchange gained in wire fees
+ * @param purse_pub public key of the purse
+ * @param balance new balance for the purse
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_wire_fee_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *wire_fee_balance);
+ (*update_purse_info)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *balance);
/**
- * Get summary information about an exchanges wire fee balance.
+ * Get information about a purse.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master public key of the exchange
- * @param[out] wire_fee_balance set amount the exchange gained in wire fees
+ * @param purse_pub public key of the purse
+ * @param[out] rowid which row did we get the information from
+ * @param[out] balance set to balance of the purse
+ * @param[out] expiration_date expiration date of the purse
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_wire_fee_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_Amount *wire_fee_balance);
+ (*get_purse_info)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ uint64_t *rowid,
+ struct TALER_Amount *balance,
+ struct GNUNET_TIME_Timestamp *expiration_date);
/**
- * Insert information about a denomination key's balances. There
- * must not be an existing record for the denomination key.
+ * Delete information about a purse.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param denom_pub_hash hash of the denomination public key
- * @param denom_balance value of coins outstanding with this denomination key
- * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
- * @param denom_risk value of coins issued with this denomination key
- * @param denom_recoup value of coins paid back if this denomination key was revoked
- * @param num_issued how many coins of this denomination did the exchange blind-sign
+ * @param purse_pub public key of the reserve
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_denomination_balance)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
- const struct TALER_Amount *denom_balance,
- const struct TALER_Amount *denom_loss,
- const struct TALER_Amount *denom_risk,
- const struct TALER_Amount *recoup_loss,
- uint64_t num_issued);
+ (*delete_purse_info)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub);
/**
- * Update information about a denomination key's balances. There
- * must be an existing record for the denomination key.
+ * Get information about expired purses.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param denom_pub_hash hash of the denomination public key
- * @param denom_balance value of coins outstanding with this denomination key
- * @param denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
- * @param denom_risk value of coins issued with this denomination key
- * @param denom_recoup value of coins paid back if this denomination key was revoked
- * @param num_issued how many coins of this denomination did the exchange blind-sign
+ * @param cb function to call on expired purses
+ * @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_denomination_balance)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
- const struct TALER_Amount *denom_balance,
- const struct TALER_Amount *denom_loss,
- const struct TALER_Amount *denom_risk,
- const struct TALER_Amount *recoup_loss,
- uint64_t num_issued);
+ (*select_purse_expired)(
+ void *cls,
+ TALER_AUDITORDB_ExpiredPurseCallback cb,
+ void *cb_cls);
/**
- * Get information about a denomination key's balances.
+ * Insert information about a denomination key's balances. There
+ * must not be an existing record for the denomination key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param denom_pub_hash hash of the denomination public key
- * @param[out] denom_balance value of coins outstanding with this denomination key
- * @param[out] denom_loss value of coins redeemed that were not outstanding (effectively, negative @a denom_balance)
- * @param[out] denom_risk value of coins issued with this denomination key
- * @param[out] denom_recoup value of coins paid back if this denomination key was revoked
- * @param[out] num_issued how many coins of this denomination did the exchange blind-sign
+ * @param dcd denomination circulation data to store
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_denomination_balance)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
- struct TALER_Amount *denom_balance,
- struct TALER_Amount *denom_loss,
- struct TALER_Amount *denom_risk,
- struct TALER_Amount *recoup_loss,
- uint64_t *num_issued);
+ (*insert_denomination_balance)(
+ void *cls,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ const struct TALER_AUDITORDB_DenominationCirculationData *dcd);
/**
- * Delete information about a denomination key's balances.
+ * Update information about a denomination key's balances. There
+ * must be an existing record for the denomination key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param denom_pub_hash hash of the denomination public key
+ * @param dcd denomination circulation data to store
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*del_denomination_balance)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash);
-
-
- /**
- * Insert information about an exchange's denomination balances. There
- * must not be an existing record for the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param denom_balance value of coins outstanding with this denomination key
- * @param deposit_fee_balance total deposit fees collected for this DK
- * @param melt_fee_balance total melt fees collected for this DK
- * @param refund_fee_balance total refund fees collected for this DK
- * @param risk maximum risk exposure of the exchange
- * @param recoup_loss actual losses from recoup (actualized @a risk)
- * @param irregular_recoups recoups made of non-revoked coins (reduces
- * risk, but should never happen)
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*insert_balance_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *denom_balance,
- const struct TALER_Amount *deposit_fee_balance,
- const struct TALER_Amount *melt_fee_balance,
- const struct TALER_Amount *refund_fee_balance,
- const struct TALER_Amount *risk,
- const struct TALER_Amount *recoup_loss,
- const struct TALER_Amount *irregular_recoups);
-
+ (*update_denomination_balance)(
+ void *cls,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ const struct TALER_AUDITORDB_DenominationCirculationData *dcd);
/**
- * Update information about an exchange's denomination balances. There
- * must be an existing record for the exchange.
+ * Delete information about a denomination key's balances.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param denom_balance value of coins outstanding with this denomination key
- * @param deposit_fee_balance total deposit fees collected for this DK
- * @param melt_fee_balance total melt fees collected for this DK
- * @param refund_fee_balance total refund fees collected for this DK
- * @param risk maximum risk exposure of the exchange
- * @param recoup_loss actual losses from recoup (actualized @a risk)
- * @param irregular_recoups recoups made of non-revoked coins (reduces
- * risk, but should never happen)
+ * @param denom_pub_hash hash of the denomination public key
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*update_balance_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *denom_balance,
- const struct TALER_Amount *deposit_fee_balance,
- const struct TALER_Amount *melt_fee_balance,
- const struct TALER_Amount *refund_fee_balance,
- const struct TALER_Amount *risk,
- const struct TALER_Amount *recoup_loss,
- const struct TALER_Amount *irregular_recoups);
+ (*del_denomination_balance)(
+ void *cls,
+ const struct TALER_DenominationHashP *denom_pub_hash);
/**
- * Get information about an exchange's denomination balances.
+ * Get information about a denomination key's balances.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] denom_balance value of coins outstanding with this denomination key
- * @param[out] deposit_fee_balance total deposit fees collected for this DK
- * @param[out] melt_fee_balance total melt fees collected for this DK
- * @param[out] refund_fee_balance total refund fees collected for this DK
- * @param[out] risk maximum risk exposure of the exchange
- * @param[out] recoup_loss actual losses from recoup (actualized @a risk)
- * @param[out] irregular_recoups recoups made of non-revoked coins (reduces
- * risk, but should never happen)
+ * @param denom_pub_hash hash of the denomination public key
+ * @param[out] dcd denomination circulation data to initialize
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_balance_summary)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_Amount *denom_balance,
- struct TALER_Amount *deposit_fee_balance,
- struct TALER_Amount *melt_fee_balance,
- struct TALER_Amount *refund_fee_balance,
- struct TALER_Amount *risk,
- struct TALER_Amount *recoup_loss,
- struct TALER_Amount *irregular_recoup);
+ (*get_denomination_balance)(
+ void *cls,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ struct TALER_AUDITORDB_DenominationCirculationData *dcd);
/**
@@ -1336,8 +901,6 @@ struct TALER_AUDITORDB_Plugin
* revenue about a denomination key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
* @param denom_pub_hash hash of the denomination key
* @param revenue_timestamp when did this profit get realized
* @param revenue_balance what was the total profit made from
@@ -1349,21 +912,16 @@ struct TALER_AUDITORDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_historic_denom_revenue)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct GNUNET_HashCode *denom_pub_hash,
- struct GNUNET_TIME_Absolute revenue_timestamp,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ struct GNUNET_TIME_Timestamp revenue_timestamp,
const struct TALER_Amount *revenue_balance,
const struct TALER_Amount *recoup_loss_balance);
/**
- * Obtain all of the historic denomination key revenue
- * of the given @a master_pub.
+ * Obtain all of the historic denomination key revenue.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
* @param cb function to call with the results
* @param cb_cls closure for @a cb
* @return transaction status code
@@ -1371,8 +929,6 @@ struct TALER_AUDITORDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_historic_denom_revenue)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
TALER_AUDITORDB_HistoricDenominationRevenueDataCallback cb,
void *cb_cls);
@@ -1381,8 +937,6 @@ struct TALER_AUDITORDB_Plugin
* Insert information about an exchange's historic revenue from reserves.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
* @param start_time beginning of aggregated time interval
* @param end_time end of aggregated time interval
* @param reserve_profits total profits made
@@ -1391,10 +945,8 @@ struct TALER_AUDITORDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_historic_reserve_revenue)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct GNUNET_TIME_Absolute start_time,
- struct GNUNET_TIME_Absolute end_time,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
const struct TALER_Amount *reserve_profits);
@@ -1402,8 +954,6 @@ struct TALER_AUDITORDB_Plugin
* Return information about an exchange's historic revenue from reserves.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
* @param cb function to call with results
* @param cb_cls closure for @a cb
* @return transaction status code
@@ -1411,62 +961,9 @@ struct TALER_AUDITORDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_historic_reserve_revenue)(
void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
TALER_AUDITORDB_HistoricReserveRevenueDataCallback cb,
void *cb_cls);
-
- /**
- * Insert information about the predicted exchange's bank
- * account balance.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param balance what the bank account balance of the exchange should show
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*insert_predicted_result)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *balance);
-
-
- /**
- * Update information about an exchange's predicted balance. There
- * must be an existing record for the exchange.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param balance what the bank account balance of the exchange should show
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*update_predicted_result)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- const struct TALER_Amount *balance);
-
-
- /**
- * Get an exchange's predicted balance.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
- * @param master_pub master key of the exchange
- * @param[out] balance expected bank account balance of the exchange
- * @return transaction status code
- */
- enum GNUNET_DB_QueryStatus
- (*get_predicted_balance)(void *cls,
- struct TALER_AUDITORDB_Session *session,
- const struct TALER_MasterPublicKeyP *master_pub,
- struct TALER_Amount *balance);
-
-
};
diff --git a/src/include/taler_bank_service.h b/src/include/taler_bank_service.h
index 0212e61f1..e8e32947b 100644
--- a/src/include/taler_bank_service.h
+++ b/src/include/taler_bank_service.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2015-2020 Taler Systems SA
+ Copyright (C) 2015-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -100,24 +100,64 @@ struct TALER_BANK_AdminAddIncomingHandle;
/**
+ * Response details for a history request.
+ */
+struct TALER_BANK_AdminAddIncomingResponse
+{
+
+ /**
+ * HTTP status.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
+ * Full response, NULL if body was not in JSON format.
+ */
+ const json_t *response;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was #MHD_HTTP_OK
+ */
+ struct
+ {
+ /**
+ * unique ID of the wire transfer in the bank's records
+ */
+ uint64_t serial_id;
+
+ /**
+ * time when the transaction was made.
+ */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ } ok;
+
+ } details;
+
+};
+
+/**
* Callbacks of this type are used to return the result of submitting
* a request to transfer funds to the exchange.
*
* @param cls closure
- * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
- * 0 if the bank's reply is bogus (fails to follow the protocol)
- * @param ec detailed error code
- * @param serial_id unique ID of the wire transfer in the bank's records; UINT64_MAX on error
- * @param timestamp time when the transaction was made.
- * @param json detailed response from the HTTPD, or NULL if reply was not in JSON
+ * @param air response details
*/
typedef void
-(*TALER_BANK_AdminAddIncomingCallback) (void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t serial_id,
- struct GNUNET_TIME_Absolute timestamp,
- const json_t *json);
+(*TALER_BANK_AdminAddIncomingCallback) (
+ void *cls,
+ const struct TALER_BANK_AdminAddIncomingResponse *air);
/**
@@ -190,20 +230,64 @@ struct TALER_BANK_TransferHandle;
/**
+ * Response details for a history request.
+ */
+struct TALER_BANK_TransferResponse
+{
+
+ /**
+ * HTTP status.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
+ * Full response, NULL if body was not in JSON format.
+ */
+ const json_t *response;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was #MHD_HTTP_OK
+ */
+ struct
+ {
+
+
+ /**
+ * unique ID of the wire transfer in the bank's records
+ */
+ uint64_t row_id;
+
+ /**
+ * when did the transaction go into effect
+ */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ } ok;
+ } details;
+};
+
+
+/**
* Function called with the result from the execute step.
*
* @param cls closure
- * @param response_code HTTP status code
- * @param ec taler error code
- * @param row_id unique ID of the wire transfer in the bank's records
- * @param timestamp when did the transaction go into effect
+ * @param tr response details
*/
typedef void
-(*TALER_BANK_TransferCallback)(void *cls,
- unsigned int response_code,
- enum TALER_ErrorCode ec,
- uint64_t row_id,
- struct GNUNET_TIME_Absolute timestamp);
+(*TALER_BANK_TransferCallback)(
+ void *cls,
+ const struct TALER_BANK_TransferResponse *tr);
/**
@@ -259,6 +343,11 @@ struct TALER_BANK_CreditHistoryHandle;
struct TALER_BANK_CreditDetails
{
/**
+ * Serial ID of the wire transfer.
+ */
+ uint64_t serial_id;
+
+ /**
* Amount that was transferred
*/
struct TALER_Amount amount;
@@ -266,25 +355,75 @@ struct TALER_BANK_CreditDetails
/**
* Time of the the transfer
*/
- struct GNUNET_TIME_Absolute execution_date;
+ struct GNUNET_TIME_Timestamp execution_date;
/**
- * Reserve public key encoded in the wire
- * transfer subject.
+ * Reserve public key encoded in the wire transfer subject.
*/
struct TALER_ReservePublicKeyP reserve_pub;
/**
- * payto://-URL of the source account that
- * send the funds.
+ * payto://-URL of the source account that send the funds.
+ */
+ const char *debit_account_uri;
+
+};
+
+
+/**
+ * Response details for a history request.
+ */
+struct TALER_BANK_CreditHistoryResponse
+{
+
+ /**
+ * HTTP status. Note that #MHD_HTTP_OK and #MHD_HTTP_NO_CONTENT are both
+ * successful replies, but @e details will only contain @e success information
+ * if this is set to #MHD_HTTP_OK.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
*/
- const char *debit_account_url;
+ enum TALER_ErrorCode ec;
/**
- * payto://-URL of the target account that
- * received the funds.
+ * Full response, NULL if body was not in JSON format.
*/
- const char *credit_account_url;
+ const json_t *response;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * payto://-URL of the target account that received the funds.
+ */
+ const char *credit_account_uri;
+
+ /**
+ * Array of transactions received.
+ */
+ const struct TALER_BANK_CreditDetails *details;
+
+ /**
+ * Length of the @e details array.
+ */
+ unsigned int details_length;
+
+ } ok;
+
+ } details;
+
};
@@ -293,25 +432,12 @@ struct TALER_BANK_CreditDetails
* the bank for the credit transaction history.
*
* @param cls closure
- * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
- * 0 if the bank's reply is bogus (fails to follow the protocol),
- * #MHD_HTTP_NO_CONTENT if there are no more results; on success the
- * last callback is always of this status (even if `abs(num_results)` were
- * already returned).
- * @param ec detailed error code
- * @param serial_id monotonically increasing counter corresponding to the transaction
- * @param details details about the wire transfer
- * @param json detailed response from the HTTPD, or NULL if reply was not in JSON
- * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ * @param reply details about the response
*/
-typedef int
-(*TALER_BANK_CreditHistoryCallback) (
+typedef void
+(*TALER_BANK_CreditHistoryCallback)(
void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t serial_id,
- const struct TALER_BANK_CreditDetails *details,
- const json_t *json);
+ const struct TALER_BANK_CreditHistoryResponse *reply);
/**
@@ -323,6 +449,8 @@ typedef int
* @param num_results how many results do we want; negative numbers to go into the past,
* positive numbers to go into the future starting at @a start_row;
* must not be zero.
+ * @param timeout how long the client is willing to wait for more results
+ * (only useful if @a num_results is positive)
* @param hres_cb the callback to call with the transaction history
* @param hres_cb_cls closure for the above callback
* @return NULL
@@ -330,12 +458,14 @@ typedef int
* In this case, the callback is not called.
*/
struct TALER_BANK_CreditHistoryHandle *
-TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx,
- const struct TALER_BANK_AuthenticationData *auth,
- uint64_t start_row,
- int64_t num_results,
- TALER_BANK_CreditHistoryCallback hres_cb,
- void *hres_cb_cls);
+TALER_BANK_credit_history (
+ struct GNUNET_CURL_Context *ctx,
+ const struct TALER_BANK_AuthenticationData *auth,
+ uint64_t start_row,
+ int64_t num_results,
+ struct GNUNET_TIME_Relative timeout,
+ TALER_BANK_CreditHistoryCallback hres_cb,
+ void *hres_cb_cls);
/**
@@ -364,6 +494,11 @@ struct TALER_BANK_DebitHistoryHandle;
struct TALER_BANK_DebitDetails
{
/**
+ * Serial ID of the wire transfer.
+ */
+ uint64_t serial_id;
+
+ /**
* Amount that was transferred
*/
struct TALER_Amount amount;
@@ -371,7 +506,7 @@ struct TALER_BANK_DebitDetails
/**
* Time of the the transfer
*/
- struct GNUNET_TIME_Absolute execution_date;
+ struct GNUNET_TIME_Timestamp execution_date;
/**
* Wire transfer identifier used by the exchange.
@@ -384,16 +519,66 @@ struct TALER_BANK_DebitDetails
const char *exchange_base_url;
/**
- * payto://-URL of the source account that
- * send the funds.
+ * payto://-URI of the target account that received the funds.
*/
- const char *debit_account_url;
+ const char *credit_account_uri;
+
+};
+
+
+/**
+ * Response details for a history request.
+ */
+struct TALER_BANK_DebitHistoryResponse
+{
/**
- * payto://-URL of the target account that
- * received the funds.
+ * HTTP status. Note that #MHD_HTTP_OK and #MHD_HTTP_NO_CONTENT are both
+ * successful replies, but @e details will only contain @e success information
+ * if this is set to #MHD_HTTP_OK.
*/
- const char *credit_account_url;
+ unsigned int http_status;
+
+ /**
+ * Taler error code, #TALER_EC_NONE on success.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
+ * Full response, NULL if body was not in JSON format.
+ */
+ const json_t *response;
+
+ /**
+ * Details returned depending on the @e http_status.
+ */
+ union
+ {
+
+ /**
+ * Details if status was #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * payto://-URI of the source account that send the funds.
+ */
+ const char *debit_account_uri;
+
+ /**
+ * Array of transactions initiated.
+ */
+ const struct TALER_BANK_DebitDetails *details;
+
+ /**
+ * Length of the @e details array.
+ */
+ unsigned int details_length;
+
+ } ok;
+
+ } details;
};
@@ -403,25 +588,12 @@ struct TALER_BANK_DebitDetails
* the bank for the debit transaction history.
*
* @param cls closure
- * @param http_status HTTP response code, #MHD_HTTP_OK (200) for successful status request
- * 0 if the bank's reply is bogus (fails to follow the protocol),
- * #MHD_HTTP_NO_CONTENT if there are no more results; on success the
- * last callback is always of this status (even if `abs(num_results)` were
- * already returned).
- * @param ec detailed error code
- * @param serial_id monotonically increasing counter corresponding to the transaction
- * @param details details about the wire transfer
- * @param json detailed response from the HTTPD, or NULL if reply was not in JSON
- * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
+ * @param reply details about the response
*/
-typedef int
-(*TALER_BANK_DebitHistoryCallback) (
+typedef void
+(*TALER_BANK_DebitHistoryCallback)(
void *cls,
- unsigned int http_status,
- enum TALER_ErrorCode ec,
- uint64_t serial_id,
- const struct TALER_BANK_DebitDetails *details,
- const json_t *json);
+ const struct TALER_BANK_DebitHistoryResponse *reply);
/**
@@ -433,6 +605,8 @@ typedef int
* @param num_results how many results do we want; negative numbers to go into the past,
* positive numbers to go into the future starting at @a start_row;
* must not be zero.
+ * @param timeout how long the client is willing to wait for more results
+ * (only useful if @a num_results is positive)
* @param hres_cb the callback to call with the transaction history
* @param hres_cb_cls closure for the above callback
* @return NULL
@@ -444,6 +618,7 @@ TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx,
const struct TALER_BANK_AuthenticationData *auth,
uint64_t start_row,
int64_t num_results,
+ struct GNUNET_TIME_Relative timeout,
TALER_BANK_DebitHistoryCallback hres_cb,
void *hres_cb_cls);
@@ -471,7 +646,7 @@ TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh);
* @param[out] auth set to the configuration data found
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TALER_BANK_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *section,
struct TALER_BANK_AuthenticationData *auth);
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index 3c5358144..b941316b5 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2018 Taler Systems SA
+ Copyright (C) 2014-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -18,14 +18,88 @@
* @brief taler-specific crypto functions
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff <christian@grothoff.org>
+ * @author Özgür Kesim <oec-taler@kesim.org>
*/
+#if ! defined (__TALER_UTIL_LIB_H_INSIDE__)
+#error "Only <taler_util.h> can be included directly."
+#endif
+
#ifndef TALER_CRYPTO_LIB_H
#define TALER_CRYPTO_LIB_H
#include <gnunet/gnunet_util_lib.h>
-#include "taler_util.h"
-
+#include "taler_error_codes.h"
#include <gcrypt.h>
+#include <jansson.h>
+
+
+/**
+ * Maximum number of coins we allow per operation.
+ */
+#define TALER_MAX_FRESH_COINS 256
+
+/**
+ * Cut-and-choose size for refreshing. Client looses the gamble (of
+ * unaccountable transfers) with probability 1/TALER_CNC_KAPPA. Refresh cost
+ * increases linearly with TALER_CNC_KAPPA, and 3 is sufficient up to a
+ * income/sales tax of 66% of total transaction value. As there is
+ * no good reason to change this security parameter, we declare it
+ * fixed and part of the protocol.
+ */
+#define TALER_CNC_KAPPA 3
+#define TALER_CNC_KAPPA_MINUS_ONE_STR "2"
+
+
+/**
+ * Possible AML decision states.
+ */
+enum TALER_AmlDecisionState
+{
+
+ /**
+ * All AML requirements are currently satisfied.
+ */
+ TALER_AML_NORMAL = 0,
+
+ /**
+ * An AML investigation is pending.
+ */
+ TALER_AML_PENDING = 1,
+
+ /**
+ * An AML decision has concluded that the funds must be frozen.
+ */
+ TALER_AML_FROZEN = 2,
+
+ /**
+ * Maximum allowed numeric value for AML status.
+ */
+ TALER_AML_MAX = 2
+};
+
+
+/**
+ * Possible algorithms for confirmation code generation.
+ */
+enum TALER_MerchantConfirmationAlgorithm
+{
+
+ /**
+ * No purchase confirmation.
+ */
+ TALER_MCA_NONE = 0,
+
+ /**
+ * Purchase confirmation without payment
+ */
+ TALER_MCA_WITHOUT_PRICE = 1,
+
+ /**
+ * Purchase confirmation with payment
+ */
+ TALER_MCA_WITH_PRICE = 2
+
+};
/* ****************** Coin crypto primitives ************* */
@@ -33,6 +107,64 @@
GNUNET_NETWORK_STRUCT_BEGIN
/**
+ * @brief Type of public keys for Taler security modules (software or hardware).
+ * Note that there are usually at least two security modules (RSA and EdDSA),
+ * each with its own private key.
+ */
+struct TALER_SecurityModulePublicKeyP
+{
+ /**
+ * Taler uses EdDSA for security modules.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+};
+
+/**
+ * @brief Set of the public keys of the security modules
+ */
+struct TALER_SecurityModulePublicKeySetP
+{
+ /**
+ * Public key of the RSA security module
+ */
+ struct TALER_SecurityModulePublicKeyP rsa;
+
+ /**
+ * Public key of the CS security module
+ */
+ struct TALER_SecurityModulePublicKeyP cs;
+
+ /**
+ * Public key of the eddsa security module
+ */
+ struct TALER_SecurityModulePublicKeyP eddsa;
+};
+
+/**
+ * @brief Type of private keys for Taler security modules (software or hardware).
+ */
+struct TALER_SecurityModulePrivateKeyP
+{
+ /**
+ * Taler uses EdDSA for security modules.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
+};
+
+
+/**
+ * @brief Type of signatures used for Taler security modules (software or hardware).
+ */
+struct TALER_SecurityModuleSignatureP
+{
+ /**
+ * Taler uses EdDSA for security modules.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
+};
+
+
+/**
* @brief Type of public keys for Taler reserves.
*/
struct TALER_ReservePublicKeyP
@@ -69,6 +201,18 @@ struct TALER_ReserveSignatureP
/**
+ * (Symmetric) key used to encrypt KYC attribute data in the database.
+ */
+struct TALER_AttributeKeyP
+{
+ /**
+ * Actual key material.
+ */
+ struct GNUNET_HashCode key;
+};
+
+
+/**
* @brief Type of public keys to for merchant authorizations.
* Merchants can issue refunds using the corresponding
* private key.
@@ -122,7 +266,7 @@ struct TALER_TransferPublicKeyP
/**
- * @brief Type of transfer public keys used during refresh
+ * @brief Type of transfer private keys used during refresh
* operations.
*/
struct TALER_TransferPrivateKeyP
@@ -135,6 +279,32 @@ struct TALER_TransferPrivateKeyP
/**
+ * @brief Type of public keys used for contract
+ * encryption.
+ */
+struct TALER_ContractDiffiePublicP
+{
+ /**
+ * Taler uses ECDHE for contract encryption.
+ */
+ struct GNUNET_CRYPTO_EcdhePublicKey ecdhe_pub;
+};
+
+
+/**
+ * @brief Type of private keys used for contract
+ * encryption.
+ */
+struct TALER_ContractDiffiePrivateP
+{
+ /**
+ * Taler uses ECDHE for contract encryption.
+ */
+ struct GNUNET_CRYPTO_EcdhePrivateKey ecdhe_priv;
+};
+
+
+/**
* @brief Type of online public keys used by the exchange to sign
* messages.
*/
@@ -185,50 +355,62 @@ struct TALER_MasterPublicKeyP
/**
- * @brief Type of the public key used by the auditor.
+ * @brief Type of the offline master public keys used by the exchange.
*/
-struct TALER_AuditorPublicKeyP
+struct TALER_MasterPrivateKeyP
{
/**
- * Taler uses EdDSA for the auditor's signing key.
+ * Taler uses EdDSA for the long-term offline master key.
*/
- struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
};
/**
- * @brief Type of signatures used by the auditor.
+ * @brief Type of signatures by the offline master public key used by the exchange.
*/
-struct TALER_AuditorSignatureP
+struct TALER_MasterSignatureP
{
/**
- * Taler uses EdDSA signatures for auditors.
+ * Taler uses EdDSA for the long-term offline master key.
*/
- struct GNUNET_CRYPTO_EddsaSignature eddsa_sig;
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
};
/**
- * @brief Type of the offline master public keys used by the exchange.
+ * @brief Type of the private key used by the auditor.
*/
-struct TALER_MasterPrivateKeyP
+struct TALER_AuditorPrivateKeyP
{
/**
- * Taler uses EdDSA for the long-term offline master key.
+ * Taler uses EdDSA for the auditor's signing key.
*/
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
};
/**
- * @brief Type of signatures by the offline master public key used by the exchange.
+ * @brief Type of the public key used by the auditor.
*/
-struct TALER_MasterSignatureP
+struct TALER_AuditorPublicKeyP
{
/**
- * Taler uses EdDSA for the long-term offline master key.
+ * Taler uses EdDSA for the auditor's signing key.
*/
- struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
+ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+};
+
+
+/**
+ * @brief Type of signatures used by the auditor.
+ */
+struct TALER_AuditorSignatureP
+{
+ /**
+ * Taler uses EdDSA signatures for auditors.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_sig;
};
@@ -258,7 +440,6 @@ struct TALER_CoinSpendPrivateKeyP
struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
};
-
/**
* @brief Type of signatures made with Taler coins.
*/
@@ -272,14 +453,163 @@ struct TALER_CoinSpendSignatureP
/**
- * @brief Type of blinding keys for Taler.
+ * @brief Type of private keys for age commitment in coins.
+ */
+struct TALER_AgeCommitmentPrivateKeyP
+{
+#ifdef AGE_RESTRICTION_WITH_ECDSA
+ /**
+ * Taler uses EcDSA for coins when signing age verification attestation.
+ */
+ struct GNUNET_CRYPTO_EcdsaPrivateKey priv;
+#else
+ /**
+ * Taler uses Edx25519 for coins when signing age verification attestation.
+ */
+ struct GNUNET_CRYPTO_Edx25519PrivateKey priv;
+#endif
+};
+
+
+/**
+ * @brief Type of public keys for age commitment in coins.
+ */
+struct TALER_AgeCommitmentPublicKeyP
+{
+#ifdef AGE_RESTRICTION_WITH_ECDSA
+ /**
+ * Taler uses EcDSA for coins when signing age verification attestation.
+ */
+ struct GNUNET_CRYPTO_EcdsaPublicKey pub;
+#else
+ /**
+ * Taler uses Edx25519 for coins when signing age verification attestation.
+ */
+ struct GNUNET_CRYPTO_Edx25519PublicKey pub;
+#endif
+};
+
+
+/*
+ * @brief Hash to represent the commitment to n*kappa blinded keys during a
+ * age-withdrawal. It is the running SHA512 hash over the hashes of the blinded
+ * envelopes of n*kappa coins.
+ */
+struct TALER_AgeWithdrawCommitmentHashP
+{
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * @brief Type of online public keys used by the wallet to establish a purse and the associated contract meta data.
*/
-struct TALER_DenominationBlindingKeyP
+struct TALER_PurseContractPublicKeyP
{
/**
- * Taler uses RSA for blind signatures.
+ * Taler uses EdDSA for purse message signing.
*/
- struct GNUNET_CRYPTO_RsaBlindingKeySecret bks;
+ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+};
+
+
+/**
+ * @brief Type of online private keys used by the wallet to
+ * bind a purse to a particular contract (and other meta data).
+ */
+struct TALER_PurseContractPrivateKeyP
+{
+ /**
+ * Taler uses EdDSA for online signatures sessions.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
+};
+
+
+/**
+ * @brief Type of signatures used by the wallet to sign purse creation messages online.
+ */
+struct TALER_PurseContractSignatureP
+{
+ /**
+ * Taler uses EdDSA for online signatures sessions.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
+};
+
+
+/**
+ * @brief Type of online public keys used by the wallet to
+ * sign a merge of a purse into an account.
+ */
+struct TALER_PurseMergePublicKeyP
+{
+ /**
+ * Taler uses EdDSA for purse message signing.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+};
+
+
+/**
+ * @brief Type of online private keys used by the wallet to
+ * sign a merge of a purse into an account.
+ */
+struct TALER_PurseMergePrivateKeyP
+{
+ /**
+ * Taler uses EdDSA for online signatures sessions.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
+};
+
+
+/**
+ * @brief Type of signatures used by the wallet to sign purse merge requests online.
+ */
+struct TALER_PurseMergeSignatureP
+{
+ /**
+ * Taler uses EdDSA for online signatures sessions.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
+};
+
+
+/**
+ * @brief Type of online public keys used by AML officers.
+ */
+struct TALER_AmlOfficerPublicKeyP
+{
+ /**
+ * Taler uses EdDSA for AML decision signing.
+ */
+ struct GNUNET_CRYPTO_EddsaPublicKey eddsa_pub;
+};
+
+
+/**
+ * @brief Type of online private keys used to identify
+ * AML officers.
+ */
+struct TALER_AmlOfficerPrivateKeyP
+{
+ /**
+ * Taler uses EdDSA for AML decision signing.
+ */
+ struct GNUNET_CRYPTO_EddsaPrivateKey eddsa_priv;
+};
+
+
+/**
+ * @brief Type of signatures used by AML officers.
+ */
+struct TALER_AmlOfficerSignatureP
+{
+ /**
+ * Taler uses EdDSA for AML decision signing.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature eddsa_signature;
};
@@ -296,30 +626,635 @@ struct TALER_RefreshCommitmentP
};
+/**
+ * Symmetric key we use to encrypt KYC attributes
+ * in our database.
+ */
+struct TALER_AttributeEncryptionKeyP
+{
+ /**
+ * The key is a hash code.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Token used for access control to the merchant's unclaimed
+ * orders.
+ */
+struct TALER_ClaimTokenP
+{
+ /**
+ * The token is a 128-bit UUID.
+ */
+ struct GNUNET_Uuid token;
+};
+
+
+/**
+ * Salt used to hash a merchant's payto:// URI to
+ * compute the "h_wire" (say for deposit requests).
+ */
+struct TALER_WireSaltP
+{
+ /**
+ * Actual 128-bit salt value.
+ */
+ uint32_t salt[4];
+};
+
+
+/**
+ * Hash used to represent an CS public key. Does not include age
+ * restrictions and is ONLY for CS. Used ONLY for interactions with the CS
+ * security module.
+ */
+struct TALER_CsPubHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent an RSA public key. Does not include age
+ * restrictions and is ONLY for RSA. Used ONLY for interactions with the RSA
+ * security module.
+ */
+struct TALER_RsaPubHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Master key material for the deriviation of
+ * private coins and blinding factors during
+ * withdraw or refresh.
+ */
+struct TALER_PlanchetMasterSecretP
+{
+
+ /**
+ * Key material.
+ */
+ uint32_t key_data[8];
+
+};
+
+
+/**
+ * Master key material for the deriviation of
+ * private coins and blinding factors.
+ */
+struct TALER_RefreshMasterSecretP
+{
+
+ /**
+ * Key material.
+ */
+ uint32_t key_data[8];
+
+};
+
+
+/**
+ * Hash used to represent a denomination public key
+ * and associated age restrictions (if any).
+ */
+struct TALER_DenominationHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent the private part
+ * of a contract between merchant and consumer.
+ */
+struct TALER_PrivateContractHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent the policy extension to a deposit
+ */
+struct TALER_ExtensionPolicyHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent the salted hash of a
+ * merchant's bank account.
+ */
+struct TALER_MerchantWireHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent the unsalted hash of a
+ * payto:// URI representing a bank account.
+ */
+struct TALER_PaytoHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_ShortHashCode hash;
+};
+
+
+/**
+ * Hash used to represent a commitment to a blinded
+ * coin, i.e. the hash of the envelope.
+ */
+struct TALER_BlindedCoinHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Hash used to represent the hash of the public
+ * key of a coin (without blinding).
+ */
+struct TALER_CoinPubHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * @brief Value that uniquely identifies a reward.
+ */
+struct TALER_RewardIdentifierP
+{
+ /**
+ * The tip identifier is a SHA-512 hash code.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * @brief Value that uniquely identifies a tip pick up operation.
+ */
+struct TALER_PickupIdentifierP
+{
+ /**
+ * The pickup identifier is a SHA-512 hash code.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * @brief Salted hash over the JSON object representing the manifests of
+ * extensions.
+ */
+struct TALER_ExtensionManifestsHashP
+{
+ /**
+ * Actual hash value.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+
+/**
+ * Set of the fees applying to a denomination.
+ */
+struct TALER_DenomFeeSetNBOP
+{
+
+ /**
+ * The fee the exchange charges when a coin of this type is withdrawn.
+ * (can be zero).
+ */
+ struct TALER_AmountNBO withdraw;
+
+ /**
+ * The fee the exchange charges when a coin of this type is deposited.
+ * (can be zero).
+ */
+ struct TALER_AmountNBO deposit;
+
+ /**
+ * The fee the exchange charges when a coin of this type is refreshed.
+ * (can be zero).
+ */
+ struct TALER_AmountNBO refresh;
+
+ /**
+ * The fee the exchange charges when a coin of this type is refunded.
+ * (can be zero). Note that refund fees are charged to the customer;
+ * if a refund is given, the deposit fee is also refunded.
+ */
+ struct TALER_AmountNBO refund;
+
+};
+
+
+/**
+ * Set of the fees applying for a given
+ * time-range and wire method.
+ */
+struct TALER_WireFeeSetNBOP
+{
+
+ /**
+ * The fee the exchange charges for wiring funds
+ * to a merchant.
+ */
+ struct TALER_AmountNBO wire;
+
+ /**
+ * The fee the exchange charges for closing a reserve
+ * and wiring the funds back to the origin account.
+ */
+ struct TALER_AmountNBO closing;
+
+};
+
+
+/**
+ * Set of the fees applying globally for a given
+ * time-range.
+ */
+struct TALER_GlobalFeeSetNBOP
+{
+
+ /**
+ * The fee the exchange charges for returning the history of a reserve or
+ * account.
+ */
+ struct TALER_AmountNBO history;
+
+ /**
+ * The fee the exchange charges for keeping an account or reserve open for a
+ * year.
+ */
+ struct TALER_AmountNBO account;
+
+ /**
+ * The fee the exchange charges if a purse is abandoned and this was not
+ * covered by the account limit.
+ */
+ struct TALER_AmountNBO purse;
+};
+
+
GNUNET_NETWORK_STRUCT_END
/**
+ * Compute RFC 3548 base32 decoding of @a val and write
+ * result to @a udata.
+ *
+ * @param val value to decode
+ * @param val_size number of bytes in @a val
+ * @param key is the val in bits
+ * @param key_len is the size of @a key
+ */
+int
+TALER_rfc3548_base32decode (const char *val,
+ size_t val_size,
+ void *key,
+ size_t key_len);
+
+
+/**
+ * @brief Builds POS confirmation token to verify payment.
+ *
+ * @param pos_key encoded key for verification payment
+ * @param pos_alg algorithm to compute the payment verification
+ * @param total of the order paid
+ * @param ts is the time given
+ * @return POS token on success, NULL otherwise
+ */
+char *
+TALER_build_pos_confirmation (const char *pos_key,
+ enum TALER_MerchantConfirmationAlgorithm pos_alg,
+ const struct TALER_Amount *total,
+ struct GNUNET_TIME_Timestamp ts);
+
+
+/**
+ * Set of the fees applying to a denomination.
+ */
+struct TALER_DenomFeeSet
+{
+
+ /**
+ * The fee the exchange charges when a coin of this type is withdrawn.
+ * (can be zero).
+ */
+ struct TALER_Amount withdraw;
+
+ /**
+ * The fee the exchange charges when a coin of this type is deposited.
+ * (can be zero).
+ */
+ struct TALER_Amount deposit;
+
+ /**
+ * The fee the exchange charges when a coin of this type is refreshed.
+ * (can be zero).
+ */
+ struct TALER_Amount refresh;
+
+ /**
+ * The fee the exchange charges when a coin of this type is refunded.
+ * (can be zero). Note that refund fees are charged to the customer;
+ * if a refund is given, the deposit fee is also refunded.
+ */
+ struct TALER_Amount refund;
+
+};
+
+
+/**
+ * Set of the fees applying for a given time-range and wire method.
+ */
+struct TALER_WireFeeSet
+{
+
+ /**
+ * The fee the exchange charges for wiring funds to a merchant.
+ */
+ struct TALER_Amount wire;
+
+ /**
+ * The fee the exchange charges for closing a reserve
+ * and wiring the funds back to the origin account.
+ */
+ struct TALER_Amount closing;
+
+};
+
+
+/**
+ * Set of the fees applying globally for a given
+ * time-range.
+ */
+struct TALER_GlobalFeeSet
+{
+
+ /**
+ * The fee the exchange charges for returning the
+ * history of a reserve or account.
+ */
+ struct TALER_Amount history;
+
+ /**
+ * The fee the exchange charges for keeping
+ * an account or reserve open for a year.
+ */
+ struct TALER_Amount account;
+
+ /**
+ * The fee the exchange charges if a purse
+ * is abandoned and this was not covered by
+ * the account limit.
+ */
+ struct TALER_Amount purse;
+};
+
+
+/**
+ * Convert fee set from host to network byte order.
+ *
+ * @param[out] nbo where to write the result
+ * @param fees fee set to convert
+ */
+void
+TALER_denom_fee_set_hton (struct TALER_DenomFeeSetNBOP *nbo,
+ const struct TALER_DenomFeeSet *fees);
+
+
+/**
+ * Convert fee set from network to host network byte order.
+ *
+ * @param[out] fees where to write the result
+ * @param nbo fee set to convert
+ */
+void
+TALER_denom_fee_set_ntoh (struct TALER_DenomFeeSet *fees,
+ const struct TALER_DenomFeeSetNBOP *nbo);
+
+
+/**
+ * Convert global fee set from host to network byte order.
+ *
+ * @param[out] nbo where to write the result
+ * @param fees fee set to convert
+ */
+void
+TALER_global_fee_set_hton (struct TALER_GlobalFeeSetNBOP *nbo,
+ const struct TALER_GlobalFeeSet *fees);
+
+
+/**
+ * Convert global fee set from network to host network byte order.
+ *
+ * @param[out] fees where to write the result
+ * @param nbo fee set to convert
+ */
+void
+TALER_global_fee_set_ntoh (struct TALER_GlobalFeeSet *fees,
+ const struct TALER_GlobalFeeSetNBOP *nbo);
+
+
+/**
+ * Compare global fee sets.
+ *
+ * @param f1 first set to compare
+ * @param f2 second set to compare
+ * @return 0 if sets are equal
+ */
+int
+TALER_global_fee_set_cmp (const struct TALER_GlobalFeeSet *f1,
+ const struct TALER_GlobalFeeSet *f2);
+
+
+/**
+ * Convert wire fee set from host to network byte order.
+ *
+ * @param[out] nbo where to write the result
+ * @param fees fee set to convert
+ */
+void
+TALER_wire_fee_set_hton (struct TALER_WireFeeSetNBOP *nbo,
+ const struct TALER_WireFeeSet *fees);
+
+
+/**
+ * Convert wire fee set from network to host network byte order.
+ *
+ * @param[out] fees where to write the result
+ * @param nbo fee set to convert
+ */
+void
+TALER_wire_fee_set_ntoh (struct TALER_WireFeeSet *fees,
+ const struct TALER_WireFeeSetNBOP *nbo);
+
+
+/**
+ * Compare wire fee sets.
+ *
+ * @param f1 first set to compare
+ * @param f2 second set to compare
+ * @return 0 if sets are equal
+ */
+int
+TALER_wire_fee_set_cmp (const struct TALER_WireFeeSet *f1,
+ const struct TALER_WireFeeSet *f2);
+
+
+/**
+ * Hash @a rsa.
+ *
+ * @param rsa key to hash
+ * @param[out] h_rsa where to write the result
+ */
+void
+TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa,
+ struct TALER_RsaPubHashP *h_rsa);
+
+
+/**
+ * Hash @a cs.
+ *
+ * @param cs key to hash
+ * @param[out] h_cs where to write the result
+ */
+void
+TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs,
+ struct TALER_CsPubHashP *h_cs);
+
+
+/**
* @brief Type of (unblinded) coin signatures for Taler.
*/
struct TALER_DenominationSignature
{
/**
- * Taler uses RSA for blinding.
+ * Denominations use blind signatures.
*/
- struct GNUNET_CRYPTO_RsaSignature *rsa_signature;
+ struct GNUNET_CRYPTO_UnblindedSignature *unblinded_sig;
+};
+
+
+/**
+ * @brief Type for *blinded* denomination signatures for Taler.
+ * Must be unblinded before it becomes valid.
+ */
+struct TALER_BlindedDenominationSignature
+{
+ /**
+ * Denominations use blind signatures.
+ */
+ struct GNUNET_CRYPTO_BlindedSignature *blinded_sig;
+};
+
+
+/* *************** Age Restriction *********************************** */
+
+/*
+ * @brief Type of a list of age groups, represented as bit mask.
+ *
+ * The bits set in the mask mark the edges at the beginning of a next age
+ * group. F.e. for the age groups
+ * 0-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-21, 21-*
+ * the following bits are set:
+ *
+ * 31 24 16 8 0
+ * | | | | |
+ * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
+ *
+ * A value of 0 means that the exchange does not support the extension for
+ * age-restriction.
+ *
+ * For a non-0 age mask, the 0th bit always must be set, otherwise the age
+ * mask is considered invalid.
+ */
+struct TALER_AgeMask
+{
+ uint32_t bits;
+};
+
+/**
+ * @brief Age commitment of a coin.
+ */
+struct TALER_AgeCommitmentHash
+{
+ /**
+ * The commitment is a SHA-256 hash code.
+ */
+ struct GNUNET_ShortHashCode shash;
+};
+
+/**
+ * @brief Signature of an age with the private key for the corresponding age group of an age commitment.
+ */
+struct TALER_AgeAttestation
+{
+#ifdef AGE_RESTRICTION_WITH_ECDSA
+ struct GNUNET_CRYPTO_EcdsaSignature signature;
+#else
+ struct GNUNET_CRYPTO_Edx25519Signature signature;
+#endif
};
+#define TALER_AgeCommitmentHash_isNullOrZero(ph) ((NULL == ph) || \
+ GNUNET_is_zero (ph))
/**
* @brief Type of public signing keys for verifying blindly signed coins.
*/
struct TALER_DenominationPublicKey
{
+
/**
- * Taler uses RSA for signing coins.
+ * Age restriction mask used for the key.
*/
- struct GNUNET_CRYPTO_RsaPublicKey *rsa_public_key;
+ struct TALER_AgeMask age_mask;
+
+ /**
+ * Type of the public key.
+ */
+ struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub_key;
+
};
@@ -328,10 +1263,22 @@ struct TALER_DenominationPublicKey
*/
struct TALER_DenominationPrivateKey
{
+
+ struct GNUNET_CRYPTO_BlindSignPrivateKey *bsign_priv_key;
+
+};
+
+
+/**
+ * @brief Blinded planchet send to exchange for blind signing.
+ */
+struct TALER_BlindedPlanchet
+{
/**
- * Taler uses RSA for signing coins.
+ * A blinded message.
*/
- struct GNUNET_CRYPTO_RsaPrivateKey *rsa_private_key;
+ struct GNUNET_CRYPTO_BlindedMessage *blinded_message;
+
};
@@ -351,7 +1298,18 @@ struct TALER_CoinPublicInfo
* Hash of the public key representing the denomination of the coin that is
* being deposited.
*/
- struct GNUNET_HashCode denom_pub_hash;
+ struct TALER_DenominationHashP denom_pub_hash;
+
+ /**
+ * Hash of the age commitment. If no age commitment was provided, it must be
+ * set to all zeroes.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * True, if age commitment is not applicable.
+ */
+ bool no_age_commitment;
/**
* (Unblinded) signature over @e coin_pub with @e denom_pub,
@@ -370,7 +1328,7 @@ struct TALER_TrackTransferDetails
/**
* Hash of the proposal data.
*/
- struct GNUNET_HashCode h_contract_terms;
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
* Which coin was deposited?
@@ -378,19 +1336,391 @@ struct TALER_TrackTransferDetails
struct TALER_CoinSpendPublicKeyP coin_pub;
/**
- * Value of the deposit (including fee).
+ * Value of the deposit (including fee), after refunds.
*/
struct TALER_Amount coin_value;
/**
- * Fee charged by the exchange for the deposit.
+ * Fee charged by the exchange for the deposit,
+ * possibly reduced (or waived) due to refunds.
*/
struct TALER_Amount coin_fee;
+ /**
+ * Total amount of refunds applied to this coin.
+ */
+ struct TALER_Amount refund_total;
+
+};
+
+
+/**
+ * @brief Inputs needed from the exchange for blind signing.
+ */
+struct TALER_ExchangeWithdrawValues
+{
+
+ /**
+ * Input values.
+ */
+ struct GNUNET_CRYPTO_BlindingInputValues *blinding_inputs;
};
/**
+ * Return the alg value singleton for creation of
+ * blinding secrets for RSA.
+ *
+ * @return singleton to use for RSA blinding
+ */
+const struct TALER_ExchangeWithdrawValues *
+TALER_denom_ewv_rsa_singleton (void);
+
+
+/**
+ * Make a (deep) copy of the given @a bi_src to
+ * @a bi_dst.
+ *
+ * @param[out] bi_dst target to copy to
+ * @param bi_src blinding input values to copy
+ */
+void
+TALER_denom_ewv_copy (
+ struct TALER_ExchangeWithdrawValues *bi_dst,
+ const struct TALER_ExchangeWithdrawValues *bi_src);
+
+
+/**
+ * Create private key for a Taler coin.
+ * @param ps planchet secret to derive coin priv key
+ * @param alg_values includes algorithm specific values
+ * @param[out] coin_priv private key to initialize
+ */
+void
+TALER_planchet_setup_coin_priv (
+ const struct TALER_PlanchetMasterSecretP *ps,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ struct TALER_CoinSpendPrivateKeyP *coin_priv);
+
+
+/**
+ * @brief Method to derive withdraw /csr nonce
+ *
+ * @param ps planchet secrets of the coin
+ * @param[out] nonce withdraw nonce included in the request to generate R_0 and R_1
+ */
+void
+TALER_cs_withdraw_nonce_derive (
+ const struct TALER_PlanchetMasterSecretP *ps,
+ struct GNUNET_CRYPTO_CsSessionNonce *nonce);
+
+
+/**
+ * @brief Method to derive /csr nonce
+ * to be used during refresh/melt operation.
+ *
+ * @param rms secret input for the refresh operation
+ * @param idx index of the fresh coin
+ * @param[out] nonce set to nonce included in the request to generate R_0 and R_1
+ */
+void
+TALER_cs_refresh_nonce_derive (
+ const struct TALER_RefreshMasterSecretP *rms,
+ uint32_t idx,
+ struct GNUNET_CRYPTO_CsSessionNonce *nonce);
+
+
+/**
+ * Initialize denomination public-private key pair.
+ *
+ * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int"
+ * argument with the number of bits for 'n' (e.g. 2048) must
+ * be passed.
+ *
+ * @param[out] denom_priv where to write the private key
+ * @param[out] denom_pub where to write the public key
+ * @param cipher which type of cipher to use
+ * @param ... RSA key size (eg. 2048/3072/4096)
+ * @return #GNUNET_OK on success, #GNUNET_NO if parameters were invalid
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv,
+ struct TALER_DenominationPublicKey *denom_pub,
+ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher,
+ ...);
+
+
+/**
+ * Free internals of @a denom_pub, but not @a denom_pub itself.
+ *
+ * @param[in] denom_pub key to free
+ */
+void
+TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub);
+
+
+/**
+ * Free internals of @a ewv, but not @a ewv itself.
+ *
+ * @param[in] ewv input values to free
+ */
+void
+TALER_denom_ewv_free (struct TALER_ExchangeWithdrawValues *ewv);
+
+
+/**
+ * Free internals of @a denom_priv, but not @a denom_priv itself.
+ *
+ * @param[in] denom_priv key to free
+ */
+void
+TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv);
+
+
+/**
+ * Free internals of @a denom_sig, but not @a denom_sig itself.
+ *
+ * @param[in] denom_sig signature to free
+ */
+void
+TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig);
+
+
+/**
+ * Blind coin for blind signing with @a dk using blinding secret @a coin_bks.
+ *
+ * NOTE: As a particular oddity, the @a blinded_planchet is only partially
+ * initialized by this function in the case of CS-denominations. Here, the
+ * 'nonce' must be initialized separately!
+ *
+ * @param dk denomination public key to blind for
+ * @param coin_bks blinding secret to use
+ * @param nonce nonce used to derive session values,
+ * could be NULL for ciphers that do not use it
+ * @param age_commitment_hash hash of the age commitment to be used for the coin. NULL if no commitment is made.
+ * @param coin_pub public key of the coin to blind
+ * @param alg_values algorithm specific values to blind the planchet
+ * @param[out] c_hash resulting hashed coin
+ * @param[out] blinded_planchet planchet data to initialize
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_blind (const struct TALER_DenominationPublicKey *dk,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
+ const struct TALER_AgeCommitmentHash *age_commitment_hash,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ struct TALER_CoinPubHashP *c_hash,
+ struct TALER_BlindedPlanchet *blinded_planchet);
+
+
+/**
+ * Create blinded signature.
+ *
+ * @param[out] denom_sig where to write the signature
+ * @param denom_priv private key to use for signing
+ * @param for_melt true to use the HKDF for melt
+ * @param blinded_planchet the planchet already blinded
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig,
+ const struct TALER_DenominationPrivateKey *denom_priv,
+ bool for_melt,
+ const struct TALER_BlindedPlanchet *blinded_planchet);
+
+
+/**
+ * Unblind blinded signature.
+ *
+ * @param[out] denom_sig where to write the unblinded signature
+ * @param bdenom_sig the blinded signature
+ * @param bks blinding secret to use
+ * @param c_hash hash of the coin's public key for verification of the signature
+ * @param alg_values algorithm specific values
+ * @param denom_pub public key used for signing
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_sig_unblind (
+ struct TALER_DenominationSignature *denom_sig,
+ const struct TALER_BlindedDenominationSignature *bdenom_sig,
+ const union GNUNET_CRYPTO_BlindingSecretP *bks,
+ const struct TALER_CoinPubHashP *c_hash,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ const struct TALER_DenominationPublicKey *denom_pub);
+
+
+/**
+ * Free internals of @a denom_sig, but not @a denom_sig itself.
+ *
+ * @param[in] denom_sig signature to free
+ */
+void
+TALER_blinded_denom_sig_free (
+ struct TALER_BlindedDenominationSignature *denom_sig);
+
+
+/**
+ * Compute the hash of the given @a denom_pub.
+ *
+ * @param denom_pub public key to hash
+ * @param[out] denom_hash resulting hash value
+ */
+void
+TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub,
+ struct TALER_DenominationHashP *denom_hash);
+
+
+/**
+ * Make a (deep) copy of the given @a denom_src to
+ * @a denom_dst.
+ *
+ * @param[out] denom_dst target to copy to
+ * @param denom_src public key to copy
+ */
+void
+TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst,
+ const struct TALER_DenominationPublicKey *denom_src);
+
+
+/**
+ * Make a (deep) copy of the given @a denom_src to
+ * @a denom_dst.
+ *
+ * @param[out] denom_dst target to copy to
+ * @param denom_src public key to copy
+ */
+void
+TALER_denom_sig_copy (struct TALER_DenominationSignature *denom_dst,
+ const struct TALER_DenominationSignature *denom_src);
+
+
+/**
+ * Make a (deep) copy of the given @a denom_src to
+ * @a denom_dst.
+ *
+ * @param[out] denom_dst target to copy to
+ * @param denom_src public key to copy
+ */
+void
+TALER_blinded_denom_sig_copy (
+ struct TALER_BlindedDenominationSignature *denom_dst,
+ const struct TALER_BlindedDenominationSignature *denom_src);
+
+
+/**
+ * Compare two denomination public keys.
+ *
+ * @param denom1 first key
+ * @param denom2 second key
+ * @return 0 if the keys are equal, otherwise -1 or 1
+ */
+int
+TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1,
+ const struct TALER_DenominationPublicKey *denom2);
+
+
+/**
+ * Compare two denomination signatures.
+ *
+ * @param sig1 first signature
+ * @param sig2 second signature
+ * @return 0 if the keys are equal, otherwise -1 or 1
+ */
+int
+TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1,
+ const struct TALER_DenominationSignature *sig2);
+
+
+/**
+ * Compare two blinded denomination signatures.
+ *
+ * @param sig1 first signature
+ * @param sig2 second signature
+ * @return 0 if the keys are equal, otherwise -1 or 1
+ */
+int
+TALER_blinded_denom_sig_cmp (
+ const struct TALER_BlindedDenominationSignature *sig1,
+ const struct TALER_BlindedDenominationSignature *sig2);
+
+
+/**
+ * Compare two blinded planchets.
+ *
+ * @param bp1 first blinded planchet
+ * @param bp2 second blinded planchet
+ * @return 0 if the keys are equal, otherwise -1 or 1
+ */
+int
+TALER_blinded_planchet_cmp (
+ const struct TALER_BlindedPlanchet *bp1,
+ const struct TALER_BlindedPlanchet *bp2);
+
+
+/**
+ * Verify signature made with a denomination public key
+ * over a coin.
+ *
+ * @param denom_pub public denomination key
+ * @param denom_sig signature made with the private key
+ * @param c_hash hash over the coin
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_pub_verify (const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_DenominationSignature *denom_sig,
+ const struct TALER_CoinPubHashP *c_hash);
+
+
+/**
+ * Encrypts KYC attributes for storage in the database.
+ *
+ * @param key encryption key to use
+ * @param attr set of attributes to encrypt
+ * @param[out] enc_attr encrypted attribute data
+ * @param[out] enc_attr_size number of bytes in @a enc_attr
+ */
+void
+TALER_CRYPTO_kyc_attributes_encrypt (
+ const struct TALER_AttributeEncryptionKeyP *key,
+ const json_t *attr,
+ void **enc_attr,
+ size_t *enc_attr_size);
+
+
+/**
+ * Encrypts KYC attributes for storage in the database.
+ *
+ * @param key encryption key to use
+ * @param enc_attr encrypted attribute data
+ * @param enc_attr_size number of bytes in @a enc_attr
+ * @return set of decrypted attributes, NULL on failure
+ */
+json_t *
+TALER_CRYPTO_kyc_attributes_decrypt (
+ const struct TALER_AttributeEncryptionKeyP *key,
+ const void *enc_attr,
+ size_t enc_attr_size);
+
+
+/**
+ * Takes a set of KYC attributes and extracts key
+ * data that we use to detect similar / duplicate
+ * entries in the database.
+ *
+ * @param attr set of KYC attributes
+ * @param[out] kyc_prox set to the proximity hash
+ */
+void
+TALER_CRYPTO_attributes_to_kyc_prox (
+ const json_t *attr,
+ struct GNUNET_ShortHashCode *kyc_prox);
+
+
+/**
* Check if a coin is valid; that is, whether the denomination key exists,
* is not expired, and the signature is correct.
*
@@ -400,36 +1730,46 @@ struct TALER_TrackTransferDetails
* #GNUNET_NO if it is invalid
* #GNUNET_SYSERR if an internal error occurred
*/
-int
+enum GNUNET_GenericReturnValue
TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info,
const struct TALER_DenominationPublicKey *denom_pub);
-GNUNET_NETWORK_STRUCT_BEGIN
-
/**
- * Header for serializations of coin-specific information about the
- * fresh coins we generate. These are the secrets that arise during
- * planchet generation, which is the first stage of creating a new
- * coin.
+ * Compute the hash of a blinded coin.
+ *
+ * @param blinded_planchet blinded planchet
+ * @param denom_hash hash of the denomination public key
+ * @param[out] bch where to write the hash
*/
-struct TALER_PlanchetSecretsP
-{
-
- /**
- * Private key of the coin.
- */
- struct TALER_CoinSpendPrivateKeyP coin_priv;
+void
+TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
+ const struct TALER_DenominationHashP *denom_hash,
+ struct TALER_BlindedCoinHashP *bch);
- /**
- * The blinding key.
- */
- struct TALER_DenominationBlindingKeyP blinding_key;
-};
+/**
+ * Compute the hash of a coin.
+ *
+ * @param coin_pub public key of the coin
+ * @param age_commitment_hash hash of the age commitment vector. NULL, if no age commitment was set
+ * @param[out] coin_h where to write the hash
+ */
+void
+TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_AgeCommitmentHash *age_commitment_hash,
+ struct TALER_CoinPubHashP *coin_h);
-GNUNET_NETWORK_STRUCT_END
+/**
+ * Compute the hash of a payto URI.
+ *
+ * @param payto URI to hash
+ * @param[out] h_payto where to write the hash
+ */
+void
+TALER_payto_hash (const char *payto,
+ struct TALER_PaytoHashP *h_payto);
/**
@@ -443,17 +1783,12 @@ struct TALER_PlanchetDetail
/**
* Hash of the denomination public key.
*/
- struct GNUNET_HashCode denom_pub_hash;
+ struct TALER_DenominationHashP denom_pub_hash;
/**
- * Blinded coin (see GNUNET_CRYPTO_rsa_blind()). Note: is malloc()'ed!
+ * The blinded planchet
*/
- void *coin_ev;
-
- /**
- * Number of bytes in @a coin_ev.
- */
- size_t coin_ev_size;
+ struct TALER_BlindedPlanchet blinded_planchet;
};
@@ -475,6 +1810,10 @@ struct TALER_FreshCoin
*/
struct TALER_CoinSpendPrivateKeyP coin_priv;
+ /**
+ * Optional hash of an age commitment bound to this coin, maybe NULL.
+ */
+ const struct TALER_AgeCommitmentHash *h_age_commitment;
};
@@ -529,6 +1868,19 @@ struct TALER_WireTransferIdentifierRawP
/**
+ * Raw value of a wire transfer subject for a wad.
+ */
+struct TALER_WadIdentifierP
+{
+
+ /**
+ * Wad identifier, in binary encoding.
+ */
+ uint8_t raw[24];
+};
+
+
+/**
* Binary information encoded in Crockford's Base32 in wire transfer
* subjects of transfers from Taler to a merchant. The actual value
* is chosen by the exchange and has no particular semantics, other than
@@ -554,44 +1906,121 @@ GNUNET_NETWORK_STRUCT_END
/**
- * Setup information for a fresh coin, deriving the coin private key
- * and the blinding factor from the @a secret_seed with a KDF salted
- * by the @a coin_num_salt.
+ * Setup information for a fresh coin, deriving the coin planchet secrets from
+ * which we will later derive the private key and the blinding factor. The
+ * planchet secrets derivation is based on the @a secret_seed with a KDF
+ * salted by the @a coin_num_salt.
*
* @param secret_seed seed to use for KDF to derive coin keys
* @param coin_num_salt number of the coin to include in KDF
* @param[out] ps value to initialize
*/
void
-TALER_planchet_setup_refresh (const struct TALER_TransferSecretP *secret_seed,
- uint32_t coin_num_salt,
- struct TALER_PlanchetSecretsP *ps);
+TALER_transfer_secret_to_planchet_secret (
+ const struct TALER_TransferSecretP *secret_seed,
+ uint32_t coin_num_salt,
+ struct TALER_PlanchetMasterSecretP *ps);
+
+
+/**
+ * Derive the @a coin_num transfer private key @a tpriv from a refresh from
+ * the @a rms seed and the @a old_coin_pub of the refresh operation. The
+ * transfer private key derivation is based on the @a ps with a KDF salted by
+ * the @a coin_num.
+ *
+ * @param rms seed to use for KDF to derive transfer keys
+ * @param old_coin_priv private key of the old coin
+ * @param cnc_num cut and choose number to include in KDF
+ * @param[out] tpriv value to initialize
+ */
+void
+TALER_planchet_secret_to_transfer_priv (
+ const struct TALER_RefreshMasterSecretP *rms,
+ const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
+ uint32_t cnc_num,
+ struct TALER_TransferPrivateKeyP *tpriv);
/**
- * Setup information for a fresh coin.
+ * Setup secret seed information for fresh coins to be
+ * withdrawn.
*
* @param[out] ps value to initialize
*/
void
-TALER_planchet_setup_random (struct TALER_PlanchetSecretsP *ps);
+TALER_planchet_master_setup_random (
+ struct TALER_PlanchetMasterSecretP *ps);
/**
- * Prepare a planchet for tipping. Creates and blinds a coin.
+ * Setup secret seed for fresh coins to be refreshed.
+ *
+ * @param[out] rms value to initialize
+ */
+void
+TALER_refresh_master_setup_random (
+ struct TALER_RefreshMasterSecretP *rms);
+
+
+/**
+ * Create a blinding secret @a bks given the client's @a ps and the alg_values
+ * from the exchange.
+ *
+ * @param ps secret to derive blindings from
+ * @param alg_values withdraw values containing cipher and additional CS values
+ * @param[out] bks blinding secrets
+ */
+void
+TALER_planchet_blinding_secret_create (
+ const struct TALER_PlanchetMasterSecretP *ps,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ union GNUNET_CRYPTO_BlindingSecretP *bks);
+
+
+/**
+ * Prepare a planchet for withdrawal. Creates and blinds a coin.
*
* @param dk denomination key for the coin to be created
- * @param ps secret planchet internals (for #TALER_planchet_to_coin)
+ * @param alg_values algorithm specific values
+ * @param bks blinding secrets
+ * @param nonce session nonce used to get @a alg_values
+ * @param coin_priv coin private key
+ * @param ach hash of age commitment to bind to this coin, maybe NULL
* @param[out] c_hash set to the hash of the public key of the coin (needed later)
* @param[out] pd set to the planchet detail for TALER_MERCHANT_tip_pickup() and
- * other withdraw operations
+ * other withdraw operations, `pd->blinded_planchet.cipher` will be set
+ * to cipher from @a dk
* @return #GNUNET_OK on success
*/
-int
-TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
- const struct TALER_PlanchetSecretsP *ps,
- struct GNUNET_HashCode *c_hash,
- struct TALER_PlanchetDetail *pd);
+enum GNUNET_GenericReturnValue
+TALER_planchet_prepare (
+ const struct TALER_DenominationPublicKey *dk,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ const union GNUNET_CRYPTO_BlindingSecretP *bks,
+ const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ const struct TALER_AgeCommitmentHash *ach,
+ struct TALER_CoinPubHashP *c_hash,
+ struct TALER_PlanchetDetail *pd);
+
+
+/**
+ * Frees blinded message inside blinded planchet depending on `blinded_planchet->cipher`.
+ * Does not free the @a blinded_planchet itself!
+ *
+ * @param[in] blinded_planchet blinded planchet
+ */
+void
+TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet);
+
+
+/**
+ * Frees blinded message inside planchet detail @a pd.
+ *
+ * @param[in] pd planchet detail to free
+ */
+void
+TALER_planchet_detail_free (struct TALER_PlanchetDetail *pd);
/**
@@ -600,20 +2029,36 @@ TALER_planchet_prepare (const struct TALER_DenominationPublicKey *dk,
*
* @param dk denomination key, must match what was given to #TALER_planchet_prepare()
* @param blind_sig blind signature from the exchange
- * @param ps secrets from #TALER_planchet_prepare()
+ * @param bks blinding key secret
+ * @param coin_priv private key of the coin
+ * @param ach hash of age commitment that is bound to this coin, maybe NULL
* @param c_hash hash of the coin's public key for verification of the signature
+ * @param alg_values values obtained from the exchange for the withdrawal
* @param[out] coin set to the details of the fresh coin
* @return #GNUNET_OK on success
*/
-int
-TALER_planchet_to_coin (const struct TALER_DenominationPublicKey *dk,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig,
- const struct TALER_PlanchetSecretsP *ps,
- const struct GNUNET_HashCode *c_hash,
- struct TALER_FreshCoin *coin);
+enum GNUNET_GenericReturnValue
+TALER_planchet_to_coin (
+ const struct TALER_DenominationPublicKey *dk,
+ const struct TALER_BlindedDenominationSignature *blind_sig,
+ const union GNUNET_CRYPTO_BlindingSecretP *bks,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ const struct TALER_AgeCommitmentHash *ach,
+ const struct TALER_CoinPubHashP *c_hash,
+ const struct TALER_ExchangeWithdrawValues *alg_values,
+ struct TALER_FreshCoin *coin);
-/* ****************** Refresh crypto primitives ************* */
+/**
+ * Add the hash of the @a bp (in some canonicalized form)
+ * to the @a hash_context.
+ *
+ * @param bp blinded planchet to hash
+ * @param[in,out] hash_context hash context to use
+ */
+void
+TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp,
+ struct GNUNET_HashContext *hash_context);
/**
@@ -676,14 +2121,9 @@ struct TALER_RefreshCoinData
const struct TALER_DenominationPublicKey *dk;
/**
- * The envelope with the blinded coin.
+ * The blinded planchet (details depend on cipher).
*/
- void *coin_ev;
-
- /**
- * Number of bytes in @a coin_ev
- */
- size_t coin_ev_size;
+ struct TALER_BlindedPlanchet blinded_planchet;
};
@@ -711,6 +2151,7 @@ struct TALER_RefreshCommitmentEntry
*
* @param[out] rc set to the value the wallet must commit to
* @param kappa number of transfer public keys involved (must be #TALER_CNC_KAPPA)
+ * @param rms refresh master secret to include, can be NULL!
* @param num_new_coins number of new coins to be created
* @param rcs array of @a kappa commitments
* @param coin_pub public key of the coin to be melted
@@ -719,38 +2160,3306 @@ struct TALER_RefreshCommitmentEntry
void
TALER_refresh_get_commitment (struct TALER_RefreshCommitmentP *rc,
uint32_t kappa,
+ const struct TALER_RefreshMasterSecretP *rms,
uint32_t num_new_coins,
const struct TALER_RefreshCommitmentEntry *rcs,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *amount_with_fee);
+/**
+ * Encrypt contract for transmission to a party that will
+ * merge it into a reserve.
+ *
+ * @param purse_pub public key of the purse
+ * @param contract_priv private key of the contract
+ * @param merge_priv merge capability to include
+ * @param contract_terms contract terms to encrypt
+ * @param[out] econtract set to encrypted contract
+ * @param[out] econtract_size set to number of bytes in @a econtract
+ */
+void
+TALER_CRYPTO_contract_encrypt_for_merge (
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const struct TALER_PurseMergePrivateKeyP *merge_priv,
+ const json_t *contract_terms,
+ void **econtract,
+ size_t *econtract_size);
+
+
+/**
+ * Decrypt contract for the party that will
+ * merge it into a reserve.
+ *
+ * @param purse_pub public key of the purse
+ * @param contract_priv private key of the contract
+ * @param econtract encrypted contract
+ * @param econtract_size number of bytes in @a econtract
+ * @param[out] merge_priv set to merge capability
+ * @return decrypted contract terms, or NULL on failure
+ */
+json_t *
+TALER_CRYPTO_contract_decrypt_for_merge (
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const void *econtract,
+ size_t econtract_size,
+ struct TALER_PurseMergePrivateKeyP *merge_priv);
+
+
+/**
+ * Encrypt contract for transmission to a party that will
+ * pay for it.
+ *
+ * @param purse_pub public key of the purse
+ * @param contract_priv private key of the contract
+ * @param contract_terms contract terms to encrypt
+ * @param[out] econtract set to encrypted contract
+ * @param[out] econtract_size set to number of bytes in @a econtract
+ */
+void
+TALER_CRYPTO_contract_encrypt_for_deposit (
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const json_t *contract_terms,
+ void **econtract,
+ size_t *econtract_size);
+
+
+/**
+ * Decrypt contract for the party that will pay for it.
+ *
+ * @param contract_priv private key of the contract
+ * @param econtract encrypted contract
+ * @param econtract_size number of bytes in @a econtract
+ * @return decrypted contract terms, or NULL on failure
+ */
+json_t *
+TALER_CRYPTO_contract_decrypt_for_deposit (
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const void *econtract,
+ size_t econtract_size);
+
+
+/* **************** AML officer signatures **************** */
+
+/**
+ * Sign AML query. Simple authentication, doesn't actually
+ * sign anything.
+ *
+ * @param officer_priv private key of AML officer
+ * @param[out] officer_sig where to write the signature
+ */
+void
+TALER_officer_aml_query_sign (
+ const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+ struct TALER_AmlOfficerSignatureP *officer_sig);
+
+
+/**
+ * Verify AML query authorization.
+ *
+ * @param officer_pub public key of AML officer
+ * @param officer_sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_officer_aml_query_verify (
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const struct TALER_AmlOfficerSignatureP *officer_sig);
+
+
+/**
+ * Sign AML decision.
+ *
+ * @param justification human-readable justification
+ * @param decision_time when was the decision made
+ * @param new_threshold at what monthly amount threshold
+ * should a revision be triggered
+ * @param h_payto payto URI hash of the account the
+ * decision is about
+ * @param new_state updated AML state
+ * @param kyc_requirements additional KYC requirements to
+ * impose, can be NULL
+ * @param officer_priv private key of AML officer
+ * @param[out] officer_sig where to write the signature
+ */
+void
+TALER_officer_aml_decision_sign (
+ const char *justification,
+ struct GNUNET_TIME_Timestamp decision_time,
+ const struct TALER_Amount *new_threshold,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState new_state,
+ const json_t *kyc_requirements,
+ const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+ struct TALER_AmlOfficerSignatureP *officer_sig);
+
+
+/**
+ * Verify AML decision.
+ *
+ * @param justification human-readable justification
+ * @param decision_time when was the decision made
+ * @param new_threshold at what monthly amount threshold
+ * should a revision be triggered
+ * @param h_payto payto URI hash of the account the
+ * decision is about
+ * @param new_state updated AML state
+ * @param kyc_requirements additional KYC requirements to
+ * impose, can be NULL
+ * @param officer_pub public key of AML officer
+ * @param officer_sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_officer_aml_decision_verify (
+ const char *justification,
+ struct GNUNET_TIME_Timestamp decision_time,
+ const struct TALER_Amount *new_threshold,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState new_state,
+ const json_t *kyc_requirements,
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const struct TALER_AmlOfficerSignatureP *officer_sig);
+
+
+/* **************** Helper-based RSA operations **************** */
+
+/**
+ * Handle for talking to an Denomination key signing helper.
+ */
+struct TALER_CRYPTO_RsaDenominationHelper;
+
+/**
+ * Function called with information about available keys for signing. Usually
+ * only called once per key upon connect. Also called again in case a key is
+ * being revoked, in that case with an @a end_time of zero.
+ *
+ * @param cls closure
+ * @param section_name name of the denomination type in the configuration;
+ * NULL if the key has been revoked or purged
+ * @param start_time when does the key become available for signing;
+ * zero if the key has been revoked or purged
+ * @param validity_duration how long does the key remain available for signing;
+ * zero if the key has been revoked or purged
+ * @param h_rsa hash of the RSA @a denom_pub that is available (or was purged)
+ * @param bs_pub the public key itself, NULL if the key was revoked or purged
+ * @param sm_pub public key of the security module, NULL if the key was revoked or purged
+ * @param sm_sig signature from the security module, NULL if the key was revoked or purged
+ * The signature was already verified against @a sm_pub.
+ */
+typedef void
+(*TALER_CRYPTO_RsaDenominationKeyStatusCallback)(
+ void *cls,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Relative validity_duration,
+ const struct TALER_RsaPubHashP *h_rsa,
+ struct GNUNET_CRYPTO_BlindSignPublicKey *bs_pub,
+ const struct TALER_SecurityModulePublicKeyP *sm_pub,
+ const struct TALER_SecurityModuleSignatureP *sm_sig);
+
+
+/**
+ * Initiate connection to an denomination key helper.
+ *
+ * @param cfg configuration to use
+ * @param section configuration section prefix to use, usually 'taler' or 'donau'
+ * @param dkc function to call with key information
+ * @param dkc_cls closure for @a dkc
+ * @return NULL on error (such as bad @a cfg).
+ */
+struct TALER_CRYPTO_RsaDenominationHelper *
+TALER_CRYPTO_helper_rsa_connect (
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ TALER_CRYPTO_RsaDenominationKeyStatusCallback dkc,
+ void *dkc_cls);
+
+
+/**
+ * Function to call to 'poll' for updates to the available key material.
+ * Should be called whenever it is important that the key material status is
+ * current, like when handling a "/keys" request. This function basically
+ * briefly checks if there are messages from the helper announcing changes to
+ * denomination keys.
+ *
+ * @param dh helper process connection
+ */
+void
+TALER_CRYPTO_helper_rsa_poll (struct TALER_CRYPTO_RsaDenominationHelper *dh);
+
+
+/**
+ * Information needed for an RSA signature request.
+ */
+struct TALER_CRYPTO_RsaSignRequest
+{
+ /**
+ * Hash of the RSA public key.
+ */
+ const struct TALER_RsaPubHashP *h_rsa;
+
+ /**
+ * Message to be (blindly) signed.
+ */
+ const void *msg;
+
+ /**
+ * Number of bytes in @e msg.
+ */
+ size_t msg_size;
+};
+
+
+/**
+ * Request helper @a dh to sign message in @a rsr using the public key
+ * corresponding to the key in @a rsr.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper process connection
+ * @param rsr details about the requested signature
+ * @param[out] bs set to the blind signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_rsa_sign (
+ struct TALER_CRYPTO_RsaDenominationHelper *dh,
+ const struct TALER_CRYPTO_RsaSignRequest *rsr,
+ struct TALER_BlindedDenominationSignature *bs);
+
+
+/**
+ * Request helper @a dh to batch sign messages in @a rsrs using the public key
+ * corresponding to the keys in @a rsrs.
+ *
+ * This operation will block until all the signatures have been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * Note that in case of errors, the @a bss array may still have been partially
+ * filled with signatures, which in this case must be freed by the caller
+ * (this is in contrast to the #TALER_CRYPTO_helper_rsa_sign() API which never
+ * returns any signatures if there was an error).
+ *
+ * @param dh helper process connection
+ * @param rsrs array with details about the requested signatures
+ * @param rsrs_length length of the @a rsrs array
+ * @param[out] bss array set to the blind signatures, must be of length @a rsrs_length!
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_rsa_batch_sign (
+ struct TALER_CRYPTO_RsaDenominationHelper *dh,
+ unsigned int rsrs_length,
+ const struct TALER_CRYPTO_RsaSignRequest rsrs[static rsrs_length],
+ struct TALER_BlindedDenominationSignature bss[static rsrs_length]);
+
+
+/**
+ * Ask the helper to revoke the public key associated with @a h_denom_pub.
+ * Will cause the helper to tell all clients that the key is now unavailable,
+ * and to create a replacement key.
+ *
+ * This operation will block until the revocation request has been
+ * transmitted. Should this process receive a signal (that is not ignored)
+ * while the operation is pending, the operation may fail. If the key is
+ * unknown, this function will also appear to have succeeded. To be sure that
+ * the revocation worked, clients must watch the denomination key status
+ * callback.
+ *
+ * @param dh helper to process connection
+ * @param h_rsa hash of the RSA public key to revoke
+ */
+void
+TALER_CRYPTO_helper_rsa_revoke (
+ struct TALER_CRYPTO_RsaDenominationHelper *dh,
+ const struct TALER_RsaPubHashP *h_rsa);
+
+
+/**
+ * Close connection to @a dh.
+ *
+ * @param[in] dh connection to close
+ */
+void
+TALER_CRYPTO_helper_rsa_disconnect (
+ struct TALER_CRYPTO_RsaDenominationHelper *dh);
+
+
+/* **************** Helper-based CS operations **************** */
+
+/**
+ * Handle for talking to an Denomination key signing helper.
+ */
+struct TALER_CRYPTO_CsDenominationHelper;
+
+/**
+ * Function called with information about available keys for signing. Usually
+ * only called once per key upon connect. Also called again in case a key is
+ * being revoked, in that case with an @a end_time of zero.
+ *
+ * @param cls closure
+ * @param section_name name of the denomination type in the configuration;
+ * NULL if the key has been revoked or purged
+ * @param start_time when does the key become available for signing;
+ * zero if the key has been revoked or purged
+ * @param validity_duration how long does the key remain available for signing;
+ * zero if the key has been revoked or purged
+ * @param h_cs hash of the CS @a denom_pub that is available (or was purged)
+ * @param bsign_pub the public key itself, NULL if the key was revoked or purged
+ * @param sm_pub public key of the security module, NULL if the key was revoked or purged
+ * @param sm_sig signature from the security module, NULL if the key was revoked or purged
+ * The signature was already verified against @a sm_pub.
+ */
+typedef void
+(*TALER_CRYPTO_CsDenominationKeyStatusCallback)(
+ void *cls,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Relative validity_duration,
+ const struct TALER_CsPubHashP *h_cs,
+ struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub,
+ const struct TALER_SecurityModulePublicKeyP *sm_pub,
+ const struct TALER_SecurityModuleSignatureP *sm_sig);
+
+
+/**
+ * Initiate connection to an denomination key helper.
+ *
+ * @param cfg configuration to use
+ * @param section configuration section prefix to use, usually 'taler' or 'donau'
+ * @param dkc function to call with key information
+ * @param dkc_cls closure for @a dkc
+ * @return NULL on error (such as bad @a cfg).
+ */
+struct TALER_CRYPTO_CsDenominationHelper *
+TALER_CRYPTO_helper_cs_connect (
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ TALER_CRYPTO_CsDenominationKeyStatusCallback dkc,
+ void *dkc_cls);
+
+
+/**
+ * Function to call to 'poll' for updates to the available key material.
+ * Should be called whenever it is important that the key material status is
+ * current, like when handling a "/keys" request. This function basically
+ * briefly checks if there are messages from the helper announcing changes to
+ * denomination keys.
+ *
+ * @param dh helper process connection
+ */
+void
+TALER_CRYPTO_helper_cs_poll (struct TALER_CRYPTO_CsDenominationHelper *dh);
+
+
+/**
+ * Information about what we should sign over.
+ */
+struct TALER_CRYPTO_CsSignRequest
+{
+ /**
+ * Hash of the CS public key to use to sign.
+ */
+ const struct TALER_CsPubHashP *h_cs;
+
+ /**
+ * Blinded planchet containing c and the nonce.
+ */
+ const struct GNUNET_CRYPTO_CsBlindedMessage *blinded_planchet;
+
+};
+
+
+/**
+ * Request helper @a dh to sign @a req.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper process connection
+ * @param req information about the key to sign with and the value to sign
+ * @param for_melt true if for melt operation
+ * @param[out] bs set to the blind signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_sign (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CRYPTO_CsSignRequest *req,
+ bool for_melt,
+ struct TALER_BlindedDenominationSignature *bs);
+
+
+/**
+ * Request helper @a dh to sign batch of @a reqs requests.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper process connection
+ * @param reqs information about the keys to sign with and the values to sign
+ * @param reqs_length length of the @a reqs array
+ * @param for_melt true if this is for a melt operation
+ * @param[out] bss array set to the blind signatures, must be of length @a reqs_length!
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_batch_sign (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ unsigned int reqs_length,
+ const struct TALER_CRYPTO_CsSignRequest reqs[static reqs_length],
+ bool for_melt,
+ struct TALER_BlindedDenominationSignature bss[static reqs_length]);
+
+
+/**
+ * Ask the helper to revoke the public key associated with @a h_cs.
+ * Will cause the helper to tell all clients that the key is now unavailable,
+ * and to create a replacement key.
+ *
+ * This operation will block until the revocation request has been
+ * transmitted. Should this process receive a signal (that is not ignored)
+ * while the operation is pending, the operation may fail. If the key is
+ * unknown, this function will also appear to have succeeded. To be sure that
+ * the revocation worked, clients must watch the denomination key status
+ * callback.
+ *
+ * @param dh helper to process connection
+ * @param h_cs hash of the CS public key to revoke
+ */
+void
+TALER_CRYPTO_helper_cs_revoke (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CsPubHashP *h_cs);
+
+
+/**
+ * Information about what we should derive for.
+ */
+struct TALER_CRYPTO_CsDeriveRequest
+{
+ /**
+ * Hash of the CS public key to use to sign.
+ */
+ const struct TALER_CsPubHashP *h_cs;
+
+ /**
+ * Nonce to use for the /csr request.
+ */
+ const struct GNUNET_CRYPTO_CsSessionNonce *nonce;
+};
+
+
+/**
+ * Ask the helper to derive R using the information
+ * from @a cdr.
+ *
+ * This operation will block until the R has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper to process connection
+ * @param cdr derivation input data
+ * @param for_melt true if this is for a melt operation
+ * @param[out] crp set to the pair of R values
+ * @return set to the error code (or #TALER_EC_NONE on success)
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_r_derive (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ const struct TALER_CRYPTO_CsDeriveRequest *cdr,
+ bool for_melt,
+ struct GNUNET_CRYPTO_CSPublicRPairP *crp);
+
+
+/**
+ * Ask the helper to derive R using the information from @a cdrs.
+ *
+ * This operation will block until the R has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param dh helper to process connection
+ * @param cdrs_length length of the @a cdrs array
+ * @param cdrs array with derivation input data
+ * @param for_melt true if this is for a melt operation
+ * @param[out] crps array set to the pair of R values, must be of length @a cdrs_length
+ * @return set to the error code (or #TALER_EC_NONE on success)
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_cs_r_batch_derive (
+ struct TALER_CRYPTO_CsDenominationHelper *dh,
+ unsigned int cdrs_length,
+ const struct TALER_CRYPTO_CsDeriveRequest cdrs[static cdrs_length],
+ bool for_melt,
+ struct GNUNET_CRYPTO_CSPublicRPairP crps[static cdrs_length]);
+
+
+/**
+ * Close connection to @a dh.
+ *
+ * @param[in] dh connection to close
+ */
+void
+TALER_CRYPTO_helper_cs_disconnect (
+ struct TALER_CRYPTO_CsDenominationHelper *dh);
+
+/**
+ * Handle for talking to an online key signing helper.
+ */
+struct TALER_CRYPTO_ExchangeSignHelper;
+
+/**
+ * Function called with information about available keys for signing. Usually
+ * only called once per key upon connect. Also called again in case a key is
+ * being revoked, in that case with an @a end_time of zero.
+ *
+ * @param cls closure
+ * @param start_time when does the key become available for signing;
+ * zero if the key has been revoked or purged
+ * @param validity_duration how long does the key remain available for signing;
+ * zero if the key has been revoked or purged
+ * @param exchange_pub the public key itself, NULL if the key was revoked or purged
+ * @param sm_pub public key of the security module, NULL if the key was revoked or purged
+ * @param sm_sig signature from the security module, NULL if the key was revoked or purged
+ * The signature was already verified against @a sm_pub.
+ */
+typedef void
+(*TALER_CRYPTO_ExchangeKeyStatusCallback)(
+ void *cls,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Relative validity_duration,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_SecurityModulePublicKeyP *sm_pub,
+ const struct TALER_SecurityModuleSignatureP *sm_sig);
+
+
+/**
+ * Initiate connection to an online signing key helper.
+ *
+ * @param cfg configuration to use
+ * @param section configuration section prefix to use, usually 'taler' or 'donau'
+ * @param ekc function to call with key information
+ * @param ekc_cls closure for @a ekc
+ * @return NULL on error (such as bad @a cfg).
+ */
+struct TALER_CRYPTO_ExchangeSignHelper *
+TALER_CRYPTO_helper_esign_connect (
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *section,
+ TALER_CRYPTO_ExchangeKeyStatusCallback ekc,
+ void *ekc_cls);
+
+
+/**
+ * Function to call to 'poll' for updates to the available key material.
+ * Should be called whenever it is important that the key material status is
+ * current, like when handling a "/keys" request. This function basically
+ * briefly checks if there are messages from the helper announcing changes to
+ * exchange online signing keys.
+ *
+ * @param esh helper process connection
+ */
+void
+TALER_CRYPTO_helper_esign_poll (struct TALER_CRYPTO_ExchangeSignHelper *esh);
+
+
+/**
+ * Request helper @a esh to sign @a msg using the current online
+ * signing key.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param esh helper process connection
+ * @param purpose message to sign (must extend beyond the purpose)
+ * @param[out] exchange_pub set to the public key used for the signature upon success
+ * @param[out] exchange_sig set to the signature upon success
+ * @return the error code (or #TALER_EC_NONE on success)
+ */
+enum TALER_ErrorCode
+TALER_CRYPTO_helper_esign_sign_ (
+ struct TALER_CRYPTO_ExchangeSignHelper *esh,
+ const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+ struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct TALER_ExchangeSignatureP *exchange_sig);
+
+
+/**
+ * Request helper @a esh to sign @a msg using the current online
+ * signing key.
+ *
+ * This operation will block until the signature has been obtained. Should
+ * this process receive a signal (that is not ignored) while the operation is
+ * pending, the operation will fail. Note that the helper may still believe
+ * that it created the signature. Thus, signals may result in a small
+ * differences in the signature counters. Retrying in this case may work.
+ *
+ * @param esh helper process connection
+ * @param ps message to sign (MUST begin with a purpose)
+ * @param[out] epub set to the public key used for the signature upon success
+ * @param[out] esig set to the signature upon success
+ * @return the error code (or #TALER_EC_NONE on success)
+ */
+#define TALER_CRYPTO_helper_esign_sign(esh,ps,epub,esig) ( \
+ /* check size is set correctly */ \
+ GNUNET_assert (ntohl ((ps)->purpose.size) == sizeof (*ps)), \
+ /* check 'ps' begins with the purpose */ \
+ GNUNET_static_assert (((void*) (ps)) == \
+ ((void*) &(ps)->purpose)), \
+ TALER_CRYPTO_helper_esign_sign_ (esh, \
+ &(ps)->purpose, \
+ epub, \
+ esig) )
+
+
+/**
+ * Ask the helper to revoke the public key @a exchange_pub .
+ * Will cause the helper to tell all clients that the key is now unavailable,
+ * and to create a replacement key.
+ *
+ * This operation will block until the revocation request has been
+ * transmitted. Should this process receive a signal (that is not ignored)
+ * while the operation is pending, the operation may fail. If the key is
+ * unknown, this function will also appear to have succeeded. To be sure that
+ * the revocation worked, clients must watch the signing key status callback.
+ *
+ * @param esh helper to process connection
+ * @param exchange_pub the public key to revoke
+ */
+void
+TALER_CRYPTO_helper_esign_revoke (
+ struct TALER_CRYPTO_ExchangeSignHelper *esh,
+ const struct TALER_ExchangePublicKeyP *exchange_pub);
+
+
+/**
+ * Close connection to @a esh.
+ *
+ * @param[in] esh connection to close
+ */
+void
+TALER_CRYPTO_helper_esign_disconnect (
+ struct TALER_CRYPTO_ExchangeSignHelper *esh);
+
+
+/* ********************* wallet signing ************************** */
+
+
+/**
+ * Sign a request to create a purse.
+ *
+ * @param purse_expiration when should the purse expire
+ * @param h_contract_terms contract the two parties agree on
+ * @param merge_pub public key defining the merge capability
+ * @param min_age age restriction to apply for deposits into the purse
+ * @param amount total amount in the purse (including fees)
+ * @param purse_priv key identifying the purse
+ * @param[out] purse_sig resulting signature
+ */
+void
+TALER_wallet_purse_create_sign (
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ uint32_t min_age,
+ const struct TALER_Amount *amount,
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Verify a purse creation request.
+ *
+ * @param purse_expiration when should the purse expire
+ * @param h_contract_terms contract the two parties agree on
+ * @param merge_pub public key defining the merge capability
+ * @param min_age age restriction to apply for deposits into the purse
+ * @param amount total amount in the purse (including fees)
+ * @param purse_pub purse’s public key
+ * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_create_verify (
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ uint32_t min_age,
+ const struct TALER_Amount *amount,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Sign a request to delete a purse.
+ *
+ * @param purse_priv key identifying the purse
+ * @param[out] purse_sig resulting signature
+ */
+void
+TALER_wallet_purse_delete_sign (
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Verify a purse deletion request.
+ *
+ * @param purse_pub purse’s public key
+ * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_DELETE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_delete_verify (
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Sign a request to upload an encrypted contract.
+ *
+ * @param econtract encrypted contract
+ * @param econtract_size number of bytes in @a econtract
+ * @param contract_pub public key for the DH-encryption
+ * @param purse_priv key identifying the purse
+ * @param[out] purse_sig resulting signature
+ */
+void
+TALER_wallet_econtract_upload_sign (
+ const void *econtract,
+ size_t econtract_size,
+ const struct TALER_ContractDiffiePublicP *contract_pub,
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Verify a signature over encrypted contract.
+ *
+ * @param econtract encrypted contract
+ * @param econtract_size number of bytes in @a econtract
+ * @param contract_pub public key for the DH-encryption
+ * @param purse_pub purse’s public key
+ * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_econtract_upload_verify (
+ const void *econtract,
+ size_t econtract_size,
+ const struct TALER_ContractDiffiePublicP *contract_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Verify a signature over encrypted contract.
+ *
+ * @param h_econtract hashed encrypted contract
+ * @param contract_pub public key for the DH-encryption
+ * @param purse_pub purse’s public key
+ * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_CREATE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_econtract_upload_verify2 (
+ const struct GNUNET_HashCode *h_econtract,
+ const struct TALER_ContractDiffiePublicP *contract_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Sign a request to inquire about a purse's status.
+ *
+ * @param purse_priv key identifying the purse
+ * @param[out] purse_sig resulting signature
+ */
+void
+TALER_wallet_purse_status_sign (
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Verify a purse status request signature.
+ *
+ * @param purse_pub purse’s public key
+ * @param purse_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_STATUS
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_status_verify (
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig);
+
+
+/**
+ * Sign a request to deposit a coin into a purse.
+ *
+ * @param exchange_base_url URL of the exchange hosting the purse
+ * @param purse_pub purse’s public key
+ * @param amount amount of the coin's value to transfer to the purse
+ * @param h_denom_pub hash of the coin's denomination
+ * @param h_age_commitment hash of the coin's age commitment
+ * @param coin_priv key identifying the coin to be deposited
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_purse_deposit_sign (
+ const char *exchange_base_url,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *amount,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify a purse deposit request.
+ *
+ * @param exchange_base_url URL of the exchange hosting the purse
+ * @param purse_pub purse’s public key
+ * @param amount amount of the coin's value to transfer to the purse
+ * @param h_denom_pub hash of the coin's denomination
+ * @param h_age_commitment hash of the coin's age commitment
+ * @param coin_pub key identifying the coin that is being deposited
+ * @param[out] coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_deposit_verify (
+ const char *exchange_base_url,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *amount,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Sign a request by a purse to merge it into an account.
+ *
+ * @param reserve_uri identifies the location of the reserve
+ * @param merge_timestamp time when the merge happened
+ * @param purse_pub key identifying the purse
+ * @param merge_priv key identifying the merge capability
+ * @param[out] merge_sig resulting signature
+ */
+void
+TALER_wallet_purse_merge_sign (
+ const char *reserve_uri,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergePrivateKeyP *merge_priv,
+ struct TALER_PurseMergeSignatureP *merge_sig);
+
+
+/**
+ * Verify a purse merge request.
+ *
+ * @param reserve_uri identifies the location of the reserve
+ * @param merge_timestamp time when the merge happened
+ * @param purse_pub public key of the purse to merge
+ * @param merge_pub public key of the merge capability
+ * @param merge_sig the signature made with purpose #TALER_SIGNATURE_WALLET_PURSE_MERGE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_purse_merge_verify (
+ const char *reserve_uri,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ const struct TALER_PurseMergeSignatureP *merge_sig);
+
+
+/**
+ * Flags for a merge signature.
+ */
+enum TALER_WalletAccountMergeFlags
+{
+
+ /**
+ * A mode must be set. None is not a legal mode!
+ */
+ TALER_WAMF_MODE_NONE = 0,
+
+ /**
+ * We are merging a fully paid-up purse into a reserve.
+ */
+ TALER_WAMF_MODE_MERGE_FULLY_PAID_PURSE = 1,
+
+ /**
+ * We are creating a fresh purse, from the contingent
+ * of free purses that our account brings.
+ */
+ TALER_WAMF_MODE_CREATE_FROM_PURSE_QUOTA = 2,
+
+ /**
+ * The account owner is willing to pay the purse_fee for the purse to be
+ * created from the account balance.
+ */
+ TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE = 3,
+
+ /**
+ * Bitmask to AND the full flags with to get the mode.
+ */
+ TALER_WAMF_MERGE_MODE_MASK = 3
+
+};
+
+
+/**
+ * Sign a request by an account to merge a purse.
+ *
+ * @param merge_timestamp time when the merge happened
+ * @param purse_pub public key of the purse to merge
+ * @param purse_expiration when should the purse expire
+ * @param h_contract_terms contract the two parties agree on
+ * @param amount total amount in the purse (including fees)
+ * @param purse_fee purse fee the reserve will pay,
+ * only used if @a flags is #TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE
+ * @param min_age age restriction to apply for deposits into the purse
+ * @param flags flags for the operation
+ * @param reserve_priv key identifying the reserve
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_account_merge_sign (
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *purse_fee,
+ uint32_t min_age,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify an account's request to merge a purse.
+ *
+ * @param merge_timestamp time when the merge happened
+ * @param purse_pub public key of the purse to merge
+ * @param purse_expiration when should the purse expire
+ * @param h_contract_terms contract the two parties agree on
+ * @param amount total amount in the purse (including fees)
+ * @param purse_fee purse fee the reserve will pay,
+ * only used if @a flags is #TALER_WAMF_MODE_CREATE_WITH_PURSE_FEE
+ * @param min_age age restriction to apply for deposits into the purse
+ * @param flags flags for the operation
+ * @param reserve_pub account’s public key
+ * @param reserve_sig the signature made with purpose #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_account_merge_verify (
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *purse_fee,
+ uint32_t min_age,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign a request to keep a reserve open.
+ *
+ * @param reserve_payment how much to pay from the
+ * reserve's own balance for opening the reserve
+ * @param request_timestamp when was the request created
+ * @param reserve_expiration desired expiration time for the reserve
+ * @param purse_limit minimum number of purses the client
+ * wants to have concurrently open for this reserve
+ * @param reserve_priv key identifying the reserve
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_reserve_open_sign (
+ const struct TALER_Amount *reserve_payment,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ uint32_t purse_limit,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify a request to keep a reserve open.
+ *
+ * @param reserve_payment how much to pay from the
+ * reserve's own balance for opening the reserve
+ * @param request_timestamp when was the request created
+ * @param reserve_expiration desired expiration time for the reserve
+ * @param purse_limit minimum number of purses the client
+ * wants to have concurrently open for this reserve
+ * @param reserve_pub key identifying the reserve
+ * @param reserve_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_open_verify (
+ const struct TALER_Amount *reserve_payment,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ uint32_t purse_limit,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign to deposit coin to pay for keeping a reserve open.
+ *
+ * @param coin_contribution how much the coin should contribute
+ * @param reserve_sig signature over the reserve open operation
+ * @param coin_priv private key of the coin
+ * @param[out] coin_sig signature by the coin
+ */
+void
+TALER_wallet_reserve_open_deposit_sign (
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify signature that deposits coin to pay for keeping a reserve open.
+ *
+ * @param coin_contribution how much the coin should contribute
+ * @param reserve_sig signature over the reserve open operation
+ * @param coin_pub public key of the coin
+ * @param coin_sig signature by the coin
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_open_deposit_verify (
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Sign a request to close a reserve.
+ *
+ * @param request_timestamp when was the request created
+ * @param h_payto where to send the funds (NULL allowed to send
+ * to origin of the reserve)
+ * @param reserve_priv key identifying the reserve
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_reserve_close_sign (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify wallet request to close an account.
+ *
+ * @param request_timestamp when was the request created
+ * @param h_payto where to send the funds (NULL/all zeros
+ * allowed to send to origin of the reserve)
+ * @param reserve_pub account’s public key
+ * @param reserve_sig the signature made with purpose #TALER_SIGNATURE_WALLET_RESERVE_CLOSE
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_close_verify (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign a request by a wallet to perform a KYC check.
+ *
+ * @param reserve_priv key identifying the wallet/account
+ * @param balance_threshold the balance threshold the wallet is about to cross
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_account_setup_sign (
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_Amount *balance_threshold,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify account setup request.
+ *
+ * @param reserve_pub reserve the setup request was for
+ * @param balance_threshold the balance threshold the wallet is about to cross
+ * @param reserve_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_account_setup_verify (
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *balance_threshold,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign request to the exchange to confirm certain
+ * @a details about the owner of a reserve.
+ *
+ * @param request_timestamp when was the request created
+ * @param details which attributes are requested
+ * @param reserve_priv private key of the reserve
+ * @param[out] reserve_sig where to store the signature
+ */
+void
+TALER_wallet_reserve_attest_request_sign (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const json_t *details,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify request to the exchange to confirm certain
+ * @a details about the owner of a reserve.
+ *
+ * @param request_timestamp when was the request created
+ * @param details which attributes are requested
+ * @param reserve_pub public key of the reserve
+ * @param reserve_sig where to store the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_attest_request_verify (
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const json_t *details,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign a deposit permission. Function for wallets.
+ *
+ * @param amount the amount to be deposited
+ * @param deposit_fee the deposit fee we expect to pay
+ * @param h_wire hash of the merchant’s account details
+ * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
+ * @param wallet_data_hash hash over wallet inputs into the contract (maybe NULL)
+ * @param h_age_commitment hash over the age commitment, if applicable to the denomination (maybe NULL)
+ * @param h_policy hash over the policy extension
+ * @param h_denom_pub hash of the coin denomination's public key
+ * @param coin_priv coin’s private key
+ * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
+ * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
+ * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT
+ */
+void
+TALER_wallet_deposit_sign (
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *deposit_fee,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct GNUNET_HashCode *wallet_data_hash,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct GNUNET_TIME_Timestamp wallet_timestamp,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify a deposit permission.
+ *
+ * @param amount the amount to be deposited
+ * @param deposit_fee the deposit fee we expect to pay
+ * @param h_wire hash of the merchant’s account details
+ * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
+ * @param wallet_data_hash hash over wallet inputs into the contract (maybe NULL)
+ * @param h_age_commitment hash over the age commitment (maybe all zeroes, if not applicable to the denomination)
+ * @param h_policy hash over the policy extension
+ * @param h_denom_pub hash of the coin denomination's public key
+ * @param wallet_timestamp timestamp when the contract was finalized, must not be too far in the future
+ * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
+ * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
+ * @param coin_pub coin’s public key
+ * @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_deposit_verify (
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *deposit_fee,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct GNUNET_HashCode *wallet_data_hash,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct GNUNET_TIME_Timestamp wallet_timestamp,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Sign a melt request.
+ *
+ * @param amount_with_fee the amount to be melted (with fee)
+ * @param melt_fee the melt fee we expect to pay
+ * @param rc refresh session we are committed to
+ * @param h_denom_pub hash of the coin denomination's public key
+ * @param h_age_commitment hash of the age commitment (may be NULL)
+ * @param coin_priv coin’s private key
+ * @param[out] coin_sig set to the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_MELT
+ */
+void
+TALER_wallet_melt_sign (
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_Amount *melt_fee,
+ const struct TALER_RefreshCommitmentP *rc,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify a melt request.
+ *
+ * @param amount_with_fee the amount to be melted (with fee)
+ * @param melt_fee the melt fee we expect to pay
+ * @param rc refresh session we are committed to
+ * @param h_denom_pub hash of the coin denomination's public key
+ * @param h_age_commitment hash of the age commitment (may be NULL)
+ * @param coin_pub coin’s public key
+ * @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_MELT
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_melt_verify (
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_Amount *melt_fee,
+ const struct TALER_RefreshCommitmentP *rc,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Sign link data.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the new coin
+ * @param transfer_pub transfer public key
+ * @param bch blinded coin hash
+ * @param old_coin_priv private key to sign with
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_link_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_TransferPublicKeyP *transfer_pub,
+ const struct TALER_BlindedCoinHashP *bch,
+ const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify link signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the new coin
+ * @param transfer_pub transfer public key
+ * @param h_coin_ev hash of the coin envelope
+ * @param old_coin_pub old coin key that the link signature is for
+ * @param coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_link_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_TransferPublicKeyP *transfer_pub,
+ const struct TALER_BlindedCoinHashP *h_coin_ev,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Sign withdraw request.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin to withdraw
+ * @param amount_with_fee amount to debit the reserve for
+ * @param bch blinded coin hash
+ * @param reserve_priv private key to sign with
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_withdraw_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_BlindedCoinHashP *bch,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify withdraw request.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin to withdraw
+ * @param amount_with_fee amount to debit the reserve for
+ * @param bch blinded coin hash
+ * @param reserve_pub public key of the reserve
+ * @param reserve_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_withdraw_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_BlindedCoinHashP *bch,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Sign age-withdraw request.
+ *
+ * @param h_commitment hash over all n*kappa blinded coins in the commitment for the age-withdraw
+ * @param amount_with_fee amount to debit the reserve for
+ * @param mask the mask that defines the age groups
+ * @param max_age maximum age from which the age group is derived, that the withdrawn coins must be restricted to.
+ * @param reserve_priv private key to sign with
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_age_withdraw_sign (
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+/**
+ * Verify an age-withdraw request.
+ *
+ * @param h_commitment hash all n*kappa blinded coins in the commitment for the age-withdraw
+ * @param amount_with_fee amount to debit the reserve for
+ * @param mask the mask that defines the age groups
+ * @param max_age maximum age from which the age group is derived, that the withdrawn coins must be restricted to.
+ * @param reserve_pub public key of the reserve
+ * @param reserve_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_age_withdraw_verify (
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_Amount *amount_with_fee,
+ const struct TALER_AgeMask *mask,
+ uint8_t max_age,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+/**
+ * Verify exchange melt confirmation.
+ *
+ * @param rc refresh session this is about
+ * @param noreveal_index gamma value chosen by the exchange
+ * @param exchange_pub public signing key used
+ * @param exchange_sig signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_melt_confirmation_verify (
+ const struct TALER_RefreshCommitmentP *rc,
+ uint32_t noreveal_index,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig);
+
+
+/**
+ * Verify recoup signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param coin_pub coin key of the coin to be recouped
+ * @param coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_recoup_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Create recoup signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param coin_priv coin key of the coin to be recouped
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_recoup_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify recoup-refresh signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param coin_pub coin key of the coin to be recouped
+ * @param coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_recoup_refresh_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Create recoup-refresh signature.
+ *
+ * @param h_denom_pub hash of the denomiantion public key of the coin
+ * @param coin_bks blinding factor used when withdrawing the coin
+ * @param coin_priv coin key of the coin to be recouped
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_recoup_refresh_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Verify reserve history request signature.
+ *
+ * @param start_off start of the requested range
+ * @param reserve_pub reserve the history request was for
+ * @param reserve_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_reserve_history_verify (
+ uint64_t start_off,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Create reserve status request signature.
+ *
+ * @param start_off start of the requested range
+ * @param reserve_priv private key of the reserve the history request is for
+ * @param[out] reserve_sig resulting signature
+ */
+void
+TALER_wallet_reserve_history_sign (
+ uint64_t start_off,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Verify coin history request signature.
+ *
+ * @param start_off start of the requested range
+ * @param coin_pub coin the history request was for
+ * @param coin_sig resulting signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_wallet_coin_history_verify (
+ uint64_t start_off,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Create coin status request signature.
+ *
+ * @param start_off start of the requested range
+ * @param coin_priv private key of the coin the history request is for
+ * @param[out] coin_sig resulting signature
+ */
+void
+TALER_wallet_coin_history_sign (
+ uint64_t start_off,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/* ********************* merchant signing ************************** */
+
+
+/**
+ * Create merchant signature approving a refund.
+ *
+ * @param coin_pub coin to be refunded
+ * @param h_contract_terms contract to be refunded
+ * @param rtransaction_id unique ID for this (partial) refund
+ * @param amount amount to be refunded
+ * @param merchant_priv private key to sign with
+ * @param[out] merchant_sig where to write the signature
+ */
+void
+TALER_merchant_refund_sign (
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *amount,
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/**
+ * Verify merchant signature approving a refund.
+ *
+ * @param coin_pub coin to be refunded
+ * @param h_contract_terms contract to be refunded
+ * @param rtransaction_id unique ID for this (partial) refund
+ * @param amount amount to be refunded
+ * @param merchant_pub public key of the merchant
+ * @param merchant_sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_merchant_refund_verify (
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *amount,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/* ********************* exchange deposit signing ************************* */
+
+/**
+ * Sign a deposit.
+ *
+ * @param h_contract_terms hash of contract terms
+ * @param h_wire hash of the merchant account details
+ * @param coin_pub coin to be deposited
+ * @param merchant_priv private key to sign with
+ * @param[out] merchant_sig where to write the signature
+ */
+void
+TALER_merchant_deposit_sign (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/**
+ * Verify a deposit.
+ *
+ * @param merchant merchant public key
+ * @param coin_pub public key of the deposited coin
+ * @param h_contract_terms hash of contract terms
+ * @param h_wire hash of the merchant account details
+ * @param merchant_sig signature of the merchant
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_merchant_deposit_verify (
+ const struct TALER_MerchantPublicKeyP *merchant,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/* ********************* exchange online signing ************************** */
+
+
+/**
+ * Signature of a function that signs the message in @a purpose with the
+ * exchange's signing key.
+ *
+ * The @a purpose data is the beginning of the data of which the signature is
+ * to be created. The `size` field in @a purpose must correctly indicate the
+ * number of bytes of the data structure, including its header. *
+ * @param purpose the message to sign
+ * @param[out] pub set to the current public signing key of the exchange
+ * @param[out] sig signature over purpose using current signing key
+ * @return #TALER_EC_NONE on success
+ */
+typedef enum TALER_ErrorCode
+(*TALER_ExchangeSignCallback)(
+ const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Signature of a function that signs the message in @a purpose with the
+ * exchange's signing key.
+ *
+ * The @a purpose data is the beginning of the data of which the signature is
+ * to be created. The `size` field in @a purpose must correctly indicate the
+ * number of bytes of the data structure, including its header. *
+ * @param cls closure
+ * @param purpose the message to sign
+ * @param[out] pub set to the current public signing key of the exchange
+ * @param[out] sig signature over purpose using current signing key
+ * @return #TALER_EC_NONE on success
+ */
+typedef enum TALER_ErrorCode
+(*TALER_ExchangeSignCallback2)(
+ void *cls,
+ const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create deposit confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
+ * @param h_wire hash of the merchant’s account details
+ * @param h_policy hash over the policy extension, can be NULL
+ * @param exchange_timestamp timestamp when the contract was finalized, must not be too far off
+ * @param wire_deadline date until which the exchange should wire the funds
+ * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
+ * @param total_without_fee the total amount to be deposited after fees over all coins
+ * @param num_coins length of @a coin_sigs array
+ * @param coin_sigs signatures of the deposited coins
+ * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_deposit_confirmation_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
+ struct GNUNET_TIME_Timestamp wire_deadline,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ const struct TALER_Amount *total_without_fee,
+ unsigned int num_coins,
+ const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify deposit confirmation signature.
+ *
+ * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
+ * @param h_wire hash of the merchant’s account details
+ * @param h_policy hash over the policy extension, can be NULL
+ * @param exchange_timestamp timestamp when the contract was finalized, must not be too far off
+ * @param wire_deadline date until which the exchange should wire the funds
+ * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
+ * @param total_without_fee the total amount to be deposited after fees over all coins
+ * @param num_coins length of @a coin_sigs array
+ * @param coin_sigs signatures of the deposited coins
+ * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_deposit_confirmation_verify (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_ExtensionPolicyHashP *h_policy,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
+ struct GNUNET_TIME_Timestamp wire_deadline,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ const struct TALER_Amount *total_without_fee,
+ unsigned int num_coins,
+ const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create refund confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_contract_terms hash of contract being refunded
+ * @param coin_pub public key of the coin receiving the refund
+ * @param merchant public key of the merchant that granted the refund
+ * @param rtransaction_id refund transaction ID used by the merchant
+ * @param refund_amount amount refunded
+ * @param[out] pub where to write the exchange public key
+ * @param[out] sig where to write the exchange signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_refund_confirmation_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *refund_amount,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify refund confirmation signature.
+ *
+ * @param h_contract_terms hash of contract being refunded
+ * @param coin_pub public key of the coin receiving the refund
+ * @param merchant public key of the merchant that granted the refund
+ * @param rtransaction_id refund transaction ID used by the merchant
+ * @param refund_amount amount refunded
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_refund_confirmation_verify (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant,
+ uint64_t rtransaction_id,
+ const struct TALER_Amount *refund_amount,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create refresh melt confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param rc refresh commitment that identifies the melt operation
+ * @param noreveal_index gamma cut-and-choose value chosen by the exchange
+ * @param[out] pub where to write the exchange public key
+ * @param[out] sig where to write the exchange signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_melt_confirmation_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_RefreshCommitmentP *rc,
+ uint32_t noreveal_index,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify refresh melt confirmation signature.
+ *
+ * @param rc refresh commitment that identifies the melt operation
+ * @param noreveal_index gamma cut-and-choose value chosen by the exchange
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_melt_confirmation_verify (
+ const struct TALER_RefreshCommitmentP *rc,
+ uint32_t noreveal_index,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create exchange purse refund confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param amount_without_fee refunded amount
+ * @param refund_fee refund fee charged
+ * @param coin_pub coin that was refunded
+ * @param purse_pub public key of the expired purse
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_purse_refund_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_Amount *refund_fee,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify signature of exchange affirming purse refund
+ * from purse expiration.
+ *
+ * @param amount_without_fee refunded amount
+ * @param refund_fee refund fee charged
+ * @param coin_pub coin that was refunded
+ * @param purse_pub public key of the expired purse
+ * @param pub public key to verify signature against
+ * @param sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_purse_refund_verify (
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_Amount *refund_fee,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create exchange key set signature.
+ *
+ * @param scb function to call to create the signature
+ * @param cls closure for @a scb
+ * @param timestamp time when the key set was issued
+ * @param hc hash over all the keys
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_key_set_sign (
+ TALER_ExchangeSignCallback2 scb,
+ void *cls,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct GNUNET_HashCode *hc,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify key set signature.
+ *
+ * @param timestamp time when the key set was issued
+ * @param hc hash over all the keys
+ * @param pub public key to verify signature against
+ * @param sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_key_set_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct GNUNET_HashCode *hc,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create account KYC setup success signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_payto target of the KYC account
+ * @param kyc JSON data describing which KYC checks
+ * were satisfied
+ * @param timestamp time when the KYC was confirmed
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_account_setup_success_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_PaytoHashP *h_payto,
+ const json_t *kyc,
+ struct GNUNET_TIME_Timestamp timestamp,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify account KYC setup success signature.
+ *
+ * @param h_payto target of the KYC account
+ * @param kyc JSON data describing which KYC checks
+ * were satisfied
+ * @param timestamp time when the KYC was confirmed
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_account_setup_success_verify (
+ const struct TALER_PaytoHashP *h_payto,
+ const json_t *kyc,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Hash normalized @a j JSON object or array and
+ * store the result in @a hc.
+ *
+ * @param j JSON to hash
+ * @param[out] hc where to write the hash
+ */
+void
+TALER_json_hash (const json_t *j,
+ struct GNUNET_HashCode *hc);
+
+
+/**
+ * Update the @a hash_context in the computation of the
+ * h_details for a wire status signature.
+ *
+ * @param[in,out] hash_context context to update
+ * @param h_contract_terms hash of the contract
+ * @param execution_time when was the wire transfer initiated
+ * @param coin_pub deposited coin
+ * @param deposit_value contribution of the coin
+ * @param deposit_fee how high was the deposit fee
+ */
+void
+TALER_exchange_online_wire_deposit_append (
+ struct GNUNET_HashContext *hash_context,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ struct GNUNET_TIME_Timestamp execution_time,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_Amount *deposit_value,
+ const struct TALER_Amount *deposit_fee);
+
+
+/**
+ * Create wire deposit signature.
+ *
+ * @param scb function to call to create the signature
+ * @param total amount the merchant was credited
+ * @param wire_fee fee charged by the exchange for the wire transfer
+ * @param merchant_pub which merchant was credited
+ * @param payto payto://-URI of the merchant account
+ * @param h_details hash over the aggregation details
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_wire_deposit_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_Amount *total,
+ const struct TALER_Amount *wire_fee,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const char *payto,
+ const struct GNUNET_HashCode *h_details,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify wire deposit signature.
+ *
+ * @param total amount the merchant was credited
+ * @param wire_fee fee charged by the exchange for the wire transfer
+ * @param merchant_pub which merchant was credited
+ * @param h_payto hash of the payto://-URI of the merchant account
+ * @param h_details hash over the aggregation details
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_wire_deposit_verify (
+ const struct TALER_Amount *total,
+ const struct TALER_Amount *wire_fee,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct GNUNET_HashCode *h_details,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create wire confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_wire hash of the merchant's account
+ * @param h_contract_terms hash of the contract
+ * @param wtid wire transfer this deposit was aggregated into
+ * @param coin_pub public key of the deposited coin
+ * @param execution_time when was wire transfer initiated
+ * @param coin_contribution what was @a coin_pub's contribution to the wire transfer
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_wire_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct GNUNET_TIME_Timestamp execution_time,
+ const struct TALER_Amount *coin_contribution,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm wire signature.
+ *
+ * @param h_wire hash of the merchant's account
+ * @param h_contract_terms hash of the contract
+ * @param wtid wire transfer this deposit was aggregated into
+ * @param coin_pub public key of the deposited coin
+ * @param execution_time when was wire transfer initiated
+ * @param coin_contribution what was @a coin_pub's contribution to the wire transfer
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_wire_verify (
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct GNUNET_TIME_Timestamp execution_time,
+ const struct TALER_Amount *coin_contribution,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create confirm recoup signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp when was the recoup done
+ * @param recoup_amount how much was recouped
+ * @param coin_pub coin that was recouped
+ * @param reserve_pub reserve that was credited
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *recoup_amount,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm recoup signature.
+ *
+ * @param timestamp when was the recoup done
+ * @param recoup_amount how much was recouped
+ * @param coin_pub coin that was recouped
+ * @param reserve_pub reserve that was credited
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *recoup_amount,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create confirm recoup refresh signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp when was the recoup done
+ * @param recoup_amount how much was recouped
+ * @param coin_pub coin that was recouped
+ * @param old_coin_pub old coin that was credited
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_refresh_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *recoup_amount,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm recoup refresh signature.
+ *
+ * @param timestamp when was the recoup done
+ * @param recoup_amount how much was recouped
+ * @param coin_pub coin that was recouped
+ * @param old_coin_pub old coin that was credited
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_refresh_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *recoup_amount,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create denomination unknown signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp when was the error created
+ * @param h_denom_pub hash of denomination that is unknown
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_unknown_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify denomination unknown signature.
+ *
+ * @param timestamp when was the error created
+ * @param h_denom_pub hash of denomination that is unknown
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_unknown_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create denomination expired signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp when was the error created
+ * @param h_denom_pub hash of denomination that is expired
+ * @param op character string describing the operation for which
+ * the denomination is expired
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_expired_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const char *op,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify denomination expired signature.
+ *
+ * @param timestamp when was the error created
+ * @param h_denom_pub hash of denomination that is expired
+ * @param op character string describing the operation for which
+ * the denomination is expired
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_expired_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const char *op,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create reserve closure signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp time when the reserve was closed
+ * @param closing_amount amount left in the reserve
+ * @param closing_fee closing fee charged
+ * @param payto target of the wire transfer
+ * @param wtid wire transfer subject used
+ * @param reserve_pub public key of the closed reserve
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_reserve_closed_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *closing_amount,
+ const struct TALER_Amount *closing_fee,
+ const char *payto,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify reserve closure signature.
+ *
+ * @param timestamp time when the reserve was closed
+ * @param closing_amount amount left in the reserve
+ * @param closing_fee closing fee charged
+ * @param payto target of the wire transfer
+ * @param wtid wire transfer subject used
+ * @param reserve_pub public key of the closed reserve
+ * @param pub the public key of the exchange to check against
+ * @param sig the signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_reserve_closed_verify (
+ struct GNUNET_TIME_Timestamp timestamp,
+ const struct TALER_Amount *closing_amount,
+ const struct TALER_Amount *closing_fee,
+ const char *payto,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create signature by exchange affirming that a reserve
+ * has had certain attributes verified via KYC.
+ *
+ * @param scb function to call to create the signature
+ * @param attest_timestamp our time
+ * @param expiration_time when does the KYC data expire
+ * @param reserve_pub for which reserve are attributes attested
+ * @param attributes JSON object with attributes being attested to
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_reserve_attest_details_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp attest_timestamp,
+ struct GNUNET_TIME_Timestamp expiration_time,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const json_t *attributes,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify signature by exchange affirming that a reserve
+ * has had certain attributes verified via KYC.
+ *
+ * @param attest_timestamp our time
+ * @param expiration_time when does the KYC data expire
+ * @param reserve_pub for which reserve are attributes attested
+ * @param attributes JSON object with attributes being attested to
+ * @param pub exchange public key
+ * @param sig exchange signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_reserve_attest_details_verify (
+ struct GNUNET_TIME_Timestamp attest_timestamp,
+ struct GNUNET_TIME_Timestamp expiration_time,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const json_t *attributes,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create signature by exchange affirming that a purse was created.
+ *
+ * @param scb function to call to create the signature
+ * @param exchange_time our time
+ * @param purse_expiration when will the purse expire
+ * @param amount_without_fee total amount to be put into the purse (without deposit fees)
+ * @param total_deposited total currently in the purse
+ * @param purse_pub public key of the purse
+ * @param h_contract_terms hash of the contract for the purse
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_purse_created_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp exchange_time,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_Amount *total_deposited,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify exchange signature about a purse creation and balance.
+ *
+ * @param exchange_time our time
+ * @param purse_expiration when will the purse expire
+ * @param amount_without_fee total amount to be put into the purse (without deposit fees)
+ * @param total_deposited total currently in the purse
+ * @param purse_pub public key of the purse
+ * @param h_contract_terms hash of the contract for the purse
+ * @param pub the public key of the exchange to check against
+ * @param sig the signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_purse_created_verify (
+ struct GNUNET_TIME_Timestamp exchange_time,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_Amount *total_deposited,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Sign affirmation that a purse was merged.
+ *
+ * @param scb function to call to create the signature
+ * @param exchange_time our time
+ * @param purse_expiration when does the purse expire
+ * @param amount_without_fee total amount that should be in the purse without deposit fees
+ * @param purse_pub public key of the purse
+ * @param h_contract_terms hash of the contract of the purse
+ * @param reserve_pub reserve the purse will be merged into
+ * @param exchange_url exchange at which the @a reserve_pub lives
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_purse_merged_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp exchange_time,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const char *exchange_url,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify affirmation that a purse will be merged.
+ *
+ * @param exchange_time our time
+ * @param purse_expiration when does the purse expire
+ * @param amount_without_fee total amount that should be in the purse without deposit fees
+ * @param purse_pub public key of the purse
+ * @param h_contract_terms hash of the contract of the purse
+ * @param reserve_pub reserve the purse will be merged into
+ * @param exchange_url exchange at which the @a reserve_pub lives
+ * @param pub the public key of the exchange to check against
+ * @param sig the signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_purse_merged_verify (
+ struct GNUNET_TIME_Timestamp exchange_time,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_Amount *amount_without_fee,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const char *exchange_url,
+ const struct TALER_ExchangePublicKeyP *pub,
+ const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Sign information about the status of a purse.
+ *
+ * @param scb function to call to create the signature
+ * @param merge_timestamp when was the purse merged (can be never)
+ * @param deposit_timestamp when was the purse fully paid up (can be never)
+ * @param balance current balance of the purse
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_purse_status_sign (
+ TALER_ExchangeSignCallback scb,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
+ const struct TALER_Amount *balance,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify signature over information about the status of a purse.
+ *
+ * @param merge_timestamp when was the purse merged (can be never)
+ * @param deposit_timestamp when was the purse fully paid up (can be never)
+ * @param balance current balance of the purse
+ * @param exchange_pub the public key of the exchange to check against
+ * @param exchange_sig the signature to check
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_purse_status_verify (
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ struct GNUNET_TIME_Timestamp deposit_timestamp,
+ const struct TALER_Amount *balance,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig);
+
+
+/**
+ * Create age-withdraw confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_commitment age-withdraw commitment that identifies the n*kappa blinded coins
+ * @param noreveal_index gamma cut-and-choose value chosen by the exchange
+ * @param[out] pub where to write the exchange public key
+ * @param[out] sig where to write the exchange signature
+ * @return #TALER_EC_NONE on success
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_age_withdraw_confirmation_sign (
+ TALER_ExchangeSignCallback scb,
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ uint32_t noreveal_index,
+ struct TALER_ExchangePublicKeyP *pub,
+ struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify an exchange age-withdraw confirmation
+ *
+ * @param h_commitment Commitment over all n*kappa coin candidates from the original request to age-withdraw
+ * @param noreveal_index The index returned by the exchange
+ * @param exchange_pub The public key used for signing
+ * @param exchange_sig The signature from the exchange
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_age_withdraw_confirmation_verify (
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ uint32_t noreveal_index,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_ExchangeSignatureP *exchange_sig);
+
+
+/* ********************* offline signing ************************** */
+
+
+/**
+ * Create AML officer status change signature.
+ *
+ * @param officer_pub public key of the AML officer
+ * @param officer_name name of the officer
+ * @param change_date when to affect the status change
+ * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_aml_officer_status_sign (
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const char *officer_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool is_active,
+ bool read_only,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify AML officer status change signature.
+ *
+ * @param officer_pub public key of the AML officer
+ * @param officer_name name of the officer
+ * @param change_date when to affect the status change
+ * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_aml_officer_status_verify (
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const char *officer_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool is_active,
+ bool read_only,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create auditor addition signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_add_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Timestamp start_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify auditor add signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param auditor_url URL of the auditor
+ * @param start_date when to enable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_auditor_add_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ struct GNUNET_TIME_Timestamp start_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create auditor deletion signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_auditor_del_sign (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify auditor del signature.
+ *
+ * @param auditor_pub public key of the auditor
+ * @param end_date when to disable the auditor (for replay detection)
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_auditor_del_verify (
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create denomination revocation signature.
+ *
+ * @param h_denom_pub hash of public denomination key to revoke
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_denomination_revoke_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify denomination revocation signature.
+ *
+ * @param h_denom_pub hash of public denomination key to revoke
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_denomination_revoke_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create signkey revocation signature.
+ *
+ * @param exchange_pub public signing key to revoke
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_signkey_revoke_sign (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify signkey revocation signature.
+ *
+ * @param exchange_pub public signkey key to revoke
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_signkey_revoke_verify (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create signkey validity signature.
+ *
+ * @param exchange_pub public signing key to validate
+ * @param start_sign starting point of validity for signing
+ * @param end_sign end point (exclusive) for validity for signing
+ * @param end_legal legal end point of signature validity
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_signkey_validity_sign (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Timestamp end_sign,
+ struct GNUNET_TIME_Timestamp end_legal,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify signkey validitity signature.
+ *
+ * @param exchange_pub public signkey key to validate
+ * @param start_sign starting point of validity for signing
+ * @param end_sign end point (exclusive) for validity for signing
+ * @param end_legal legal end point of signature validity
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_signkey_validity_verify (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Timestamp end_sign,
+ struct GNUNET_TIME_Timestamp end_legal,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create denomination key validity signature.
+ *
+ * @param h_denom_pub hash of the denomination's public key
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fees fees for this denomination
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_denom_validity_sign (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct GNUNET_TIME_Timestamp stamp_start,
+ struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
+ struct GNUNET_TIME_Timestamp stamp_expire_deposit,
+ struct GNUNET_TIME_Timestamp stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_DenomFeeSet *fees,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify denomination key validity signature.
+ *
+ * @param h_denom_pub hash of the denomination's public key
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fees fees for this denomination
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_denom_validity_verify (
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct GNUNET_TIME_Timestamp stamp_start,
+ struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
+ struct GNUNET_TIME_Timestamp stamp_expire_deposit,
+ struct GNUNET_TIME_Timestamp stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_DenomFeeSet *fees,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create offline signature about an exchange's partners.
+ *
+ * @param partner_pub master public key of the partner
+ * @param start_date validity period start
+ * @param end_date validity period end
+ * @param wad_frequency how often will we do wad transfers to this partner
+ * @param wad_fee what is the wad fee to this partner
+ * @param partner_base_url what is the base URL of the @a partner_pub exchange
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_partner_details_sign (
+ const struct TALER_MasterPublicKeyP *partner_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify signature about an exchange's partners.
+ *
+ * @param partner_pub master public key of the partner
+ * @param start_date validity period start
+ * @param end_date validity period end
+ * @param wad_frequency how often will we do wad transfers to this partner
+ * @param wad_fee what is the wad fee to this partner
+ * @param partner_base_url what is the base URL of the @a partner_pub exchange
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_partner_details_verify (
+ const struct TALER_MasterPublicKeyP *partner_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create offline signature about wiring profits to a
+ * regular non-escrowed account of the exchange.
+ *
+ * @param wtid (random) wire transfer ID to be used
+ * @param date when was the profit drain approved (not exact time of execution)
+ * @param amount how much should be wired
+ * @param account_section configuration section of the
+ * exchange specifying the account to be debited
+ * @param payto_uri target account to be credited
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_profit_drain_sign (
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Timestamp date,
+ const struct TALER_Amount *amount,
+ const char *account_section,
+ const char *payto_uri,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify offline signature about wiring profits to a
+ * regular non-escrowed account of the exchange.
+ *
+ * @param wtid (random) wire transfer ID to be used
+ * @param date when was the profit drain approved (not exact time of execution)
+ * @param amount how much should be wired
+ * @param account_section configuration section of the
+ * exchange specifying the account to be debited
+ * @param payto_uri target account to be credited
+ * @param master_pub public key to verify signature against
+ * @param master_sig the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_profit_drain_verify (
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Timestamp date,
+ const struct TALER_Amount *amount,
+ const char *account_section,
+ const char *payto_uri,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create security module EdDSA signature.
+ *
+ * @param exchange_pub public signing key to validate
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_priv security module key to sign with
+ * @param[out] secm_sig where to write the signature
+ */
+void
+TALER_exchange_secmod_eddsa_sign (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePrivateKeyP *secm_priv,
+ struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Verify security module EdDSA signature.
+ *
+ * @param exchange_pub public signing key to validate
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_pub public key to verify against
+ * @param secm_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_secmod_eddsa_verify (
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePublicKeyP *secm_pub,
+ const struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Create security module denomination signature.
+ *
+ * @param h_rsa hash of the RSA public key to sign
+ * @param section_name name of the section in the configuration
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_priv security module key to sign with
+ * @param[out] secm_sig where to write the signature
+ */
+void
+TALER_exchange_secmod_rsa_sign (
+ const struct TALER_RsaPubHashP *h_rsa,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePrivateKeyP *secm_priv,
+ struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Verify security module denomination signature.
+ *
+ * @param h_rsa hash of the public key to validate
+ * @param section_name name of the section in the configuration
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_pub public key to verify against
+ * @param secm_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_secmod_rsa_verify (
+ const struct TALER_RsaPubHashP *h_rsa,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePublicKeyP *secm_pub,
+ const struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Create security module denomination signature.
+ *
+ * @param h_cs hash of the CS public key to sign
+ * @param section_name name of the section in the configuration
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_priv security module key to sign with
+ * @param[out] secm_sig where to write the signature
+ */
+void
+TALER_exchange_secmod_cs_sign (
+ const struct TALER_CsPubHashP *h_cs,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePrivateKeyP *secm_priv,
+ struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Verify security module denomination signature.
+ *
+ * @param h_cs hash of the public key to validate
+ * @param section_name name of the section in the configuration
+ * @param start_sign starting point of validity for signing
+ * @param duration how long will the key be in use
+ * @param secm_pub public key to verify against
+ * @param secm_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_secmod_cs_verify (
+ const struct TALER_CsPubHashP *h_cs,
+ const char *section_name,
+ struct GNUNET_TIME_Timestamp start_sign,
+ struct GNUNET_TIME_Relative duration,
+ const struct TALER_SecurityModulePublicKeyP *secm_pub,
+ const struct TALER_SecurityModuleSignatureP *secm_sig);
+
+
+/**
+ * Create denomination key validity signature by the auditor.
+ *
+ * @param auditor_url BASE URL of the auditor's API
+ * @param h_denom_pub hash of the denomination's public key
+ * @param master_pub master public key of the exchange
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fees fees the exchange charges for this denomination
+ * @param auditor_priv private key to sign with
+ * @param[out] auditor_sig where to write the signature
+ */
+void
+TALER_auditor_denom_validity_sign (
+ const char *auditor_url,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ struct GNUNET_TIME_Timestamp stamp_start,
+ struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
+ struct GNUNET_TIME_Timestamp stamp_expire_deposit,
+ struct GNUNET_TIME_Timestamp stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_DenomFeeSet *fees,
+ const struct TALER_AuditorPrivateKeyP *auditor_priv,
+ struct TALER_AuditorSignatureP *auditor_sig);
+
+
+/**
+ * Verify denomination key validity signature from auditor.
+ *
+ * @param auditor_url BASE URL of the auditor's API
+ * @param h_denom_pub hash of the denomination's public key
+ * @param master_pub master public key of the exchange
+ * @param stamp_start when does the exchange begin signing with this key
+ * @param stamp_expire_withdraw when does the exchange end signing with this key
+ * @param stamp_expire_deposit how long does the exchange accept the deposit of coins with this key
+ * @param stamp_expire_legal how long does the exchange preserve information for legal disputes with this key
+ * @param coin_value what is the value of coins signed with this key
+ * @param fees fees the exchange charges for this denomination
+ * @param auditor_pub public key to verify against
+ * @param auditor_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_auditor_denom_validity_verify (
+ const char *auditor_url,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ struct GNUNET_TIME_Timestamp stamp_start,
+ struct GNUNET_TIME_Timestamp stamp_expire_withdraw,
+ struct GNUNET_TIME_Timestamp stamp_expire_deposit,
+ struct GNUNET_TIME_Timestamp stamp_expire_legal,
+ const struct TALER_Amount *coin_value,
+ const struct TALER_DenomFeeSet *fees,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const struct TALER_AuditorSignatureP *auditor_sig);
+
+
/* **************** /wire account offline signing **************** */
/**
- * Compute the hash of the given wire details. The resulting
- * hash is what is signed by the master key.
+ * Create wire fee signature.
+ *
+ * @param payment_method the payment method
+ * @param start_time when do the fees start to apply
+ * @param end_time when do the fees start to apply
+ * @param fees the wire fees
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_wire_fee_sign (
+ const char *payment_method,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_WireFeeSet *fees,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify wire fee signature.
+ *
+ * @param payment_method the payment method
+ * @param start_time when do the fees start to apply
+ * @param end_time when do the fees start to apply
+ * @param fees the wire fees
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_wire_fee_verify (
+ const char *payment_method,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_WireFeeSet *fees,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create global fees signature.
+ *
+ * @param start_time when do the fees start to apply
+ * @param end_time when do the fees start to apply
+ * @param fees the global fees
+ * @param purse_timeout how long do unmerged purses stay around
+ * @param history_expiration how long do we keep the history of an account
+ * @param purse_account_limit how many concurrent purses are free per account holder
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_global_fee_sign (
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify global fees signature.
+ *
+ * @param start_time when do the fees start to apply
+ * @param end_time when do the fees start to apply
+ * @param fees the global fees
+ * @param purse_timeout how long do unmerged purses stay around
+ * @param history_expiration how long do we keep the history of an account
+ * @param purse_account_limit how many concurrent purses are free per account holder
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_global_fee_verify (
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create wire account addition signature.
*
* @param payto_uri bank account
- * @param[out] hc set to the hash
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
+ * @param now timestamp to use for the signature (rounded)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
*/
void
-TALER_exchange_wire_signature_hash (const char *payto_uri,
- struct GNUNET_HashCode *hc);
+TALER_exchange_offline_wire_add_sign (
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ struct GNUNET_TIME_Timestamp now,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify wire account addition signature.
+ *
+ * @param payto_uri bank account
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
+ * @param sign_time timestamp when signature was created
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_wire_add_verify (
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ struct GNUNET_TIME_Timestamp sign_time,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Create wire account removal signature.
+ *
+ * @param payto_uri bank account
+ * @param now timestamp to use for the signature (rounded)
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_wire_del_sign (
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp now,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify wire account deletion signature.
+ *
+ * @param payto_uri bank account
+ * @param sign_time timestamp when signature was created
+ * @param master_pub public key to verify against
+ * @param master_sig the signature the signature
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_wire_del_verify (
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp sign_time,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig);
/**
* Check the signature in @a master_sig.
*
- * @param payto_uri URL that is signed
+ * @param payto_uri URI that is signed
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param master_pub master public key of the exchange
* @param master_sig signature of the exchange
* @return #GNUNET_OK if signature is valid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_exchange_wire_signature_check (
const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
const struct TALER_MasterPublicKeyP *master_pub,
const struct TALER_MasterSignatureP *master_sig);
@@ -759,12 +5468,18 @@ TALER_exchange_wire_signature_check (
* Create a signed wire statement for the given account.
*
* @param payto_uri account specification
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
* @param master_priv private key to sign with
* @param[out] master_sig where to write the signature
*/
void
TALER_exchange_wire_signature_make (
const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
const struct TALER_MasterPrivateKeyP *master_priv,
struct TALER_MasterSignatureP *master_sig);
@@ -780,8 +5495,8 @@ TALER_exchange_wire_signature_make (
*/
void
TALER_merchant_wire_signature_hash (const char *payto_uri,
- const char *salt,
- struct GNUNET_HashCode *hc);
+ const struct TALER_WireSaltP *salt,
+ struct TALER_MerchantWireHashP *hc);
/**
@@ -793,10 +5508,10 @@ TALER_merchant_wire_signature_hash (const char *payto_uri,
* @param merch_sig signature of the merchant
* @return #GNUNET_OK if signature is valid
*/
-int
+enum GNUNET_GenericReturnValue
TALER_merchant_wire_signature_check (
const char *payto_uri,
- const char *salt,
+ const struct TALER_WireSaltP *salt,
const struct TALER_MerchantPublicKeyP *merch_pub,
const struct TALER_MerchantSignatureP *merch_sig);
@@ -812,9 +5527,444 @@ TALER_merchant_wire_signature_check (
void
TALER_merchant_wire_signature_make (
const char *payto_uri,
- const char *salt,
+ const struct TALER_WireSaltP *salt,
const struct TALER_MerchantPrivateKeyP *merch_priv,
struct TALER_MerchantSignatureP *merch_sig);
+/**
+ * Sign a payment confirmation.
+ *
+ * @param h_contract_terms hash of the contact of the merchant with the customer
+ * @param merch_priv private key to sign with
+ * @param[out] merch_sig where to write the signature
+ */
+void
+TALER_merchant_pay_sign (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantPrivateKeyP *merch_priv,
+ struct TALER_MerchantSignatureP *merch_sig);
+
+
+/**
+ * Verify payment confirmation signature.
+ *
+ * @param h_contract_terms hash of the contact of the merchant with the customer
+ * @param merchant_pub public key of the merchant
+ * @param merchant_sig signature to verify
+ * @return #GNUNET_OK if the signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_merchant_pay_verify (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_MerchantSignatureP *merchant_sig);
+
+
+/**
+ * Sign contract sent by the merchant to the wallet.
+ *
+ * @param h_contract_terms hash of the contract terms
+ * @param merch_priv private key to sign with
+ * @param[out] merch_sig where to write the signature
+ */
+void
+TALER_merchant_contract_sign (
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantPrivateKeyP *merch_priv,
+ struct GNUNET_CRYPTO_EddsaSignature *merch_sig);
+
+
+/* **************** /management/extensions offline signing **************** */
+
+/**
+ * Create a signature for the hash of the manifests of extensions
+ *
+ * @param h_manifests hash of the JSON object representing the manifests
+ * @param master_priv private key to sign with
+ * @param[out] master_sig where to write the signature
+ */
+void
+TALER_exchange_offline_extension_manifests_hash_sign (
+ const struct TALER_ExtensionManifestsHashP *h_manifests,
+ const struct TALER_MasterPrivateKeyP *master_priv,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Verify the signature in @a master_sig of the given hash, taken over the JSON
+ * blob representing the manifests of extensions
+ *
+ * @param h_manifest hash of the JSON blob of manifests of extensions
+ * @param master_pub master public key of the exchange
+ * @param master_sig signature of the exchange
+ * @return #GNUNET_OK if signature is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_offline_extension_manifests_hash_verify (
+ const struct TALER_ExtensionManifestsHashP *h_manifest,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const struct TALER_MasterSignatureP *master_sig
+ );
+
+
+/**
+ * @brief Representation of an age commitment: one public key per age group.
+ *
+ * The number of keys must be be the same as the number of bits set in the
+ * corresponding age mask.
+ */
+struct TALER_AgeCommitment
+{
+
+ /**
+ * The age mask defines the age groups that were a parameter during the
+ * generation of this age commitment
+ */
+ struct TALER_AgeMask mask;
+
+ /**
+ * The number of public keys, which must be the same as the number of
+ * groups in the mask.
+ */
+ size_t num;
+
+ /**
+ * The list of @e num public keys. In must have same size as the number of
+ * age groups defined in the mask.
+ *
+ * A hash of this list is the hashed commitment that goes into FDC
+ * calculation during the withdraw and refresh operations for new coins. That
+ * way, the particular age commitment becomes mandatory and bound to a coin.
+ *
+ * The list has been allocated via GNUNET_malloc().
+ */
+ struct TALER_AgeCommitmentPublicKeyP *keys;
+};
+
+
+/**
+ * @brief Proof for a particular age commitment, used in age attestation
+ *
+ * This struct is used in a call to TALER_age_commitment_attest to create an
+ * attestation for a minimum age (if that minimum age is less or equal to the
+ * committed age for this proof). It consists of a list private keys, one per
+ * age group, for which the committed age is either lager or within that
+ * particular group.
+ */
+struct TALER_AgeProof
+{
+ /**
+ * The number of private keys, which must be at most num_pub_keys. One minus
+ * this number corresponds to the largest age group that is supported with
+ * this age commitment.
+ * **Note**, that this and the next field are only relevant on the wallet
+ * side for attestation and derive operations.
+ */
+ size_t num;
+
+ /**
+ * List of @e num private keys.
+ *
+ * Note that the list can be _smaller_ than the corresponding list of public
+ * keys. In that case, the wallet can sign off only for a subset of the age
+ * groups.
+ *
+ * The list has been allocated via GNUNET_malloc.
+ */
+ struct TALER_AgeCommitmentPrivateKeyP *keys;
+};
+
+
+/**
+ * @brief Commitment and Proof for a maximum age
+ *
+ * Calling TALER_age_restriction_commit on an (maximum) age value returns this
+ * data structure. It consists of the proof, which is used to create
+ * attestations for compatible minimum ages, and the commitment, which is used
+ * to verify the attestations and derived commitments.
+ *
+ * The hash value of the commitment is bound to a particular coin with age
+ * restriction.
+ */
+struct TALER_AgeCommitmentProof
+{
+ /**
+ * The commitment is used to verify a particular attestation. Its hash value
+ * is bound to a particular coin with age restriction. This structure is
+ * sent to the merchant in order to verify a particular attestation for a
+ * minimum age.
+ * In itself, it does not convey any information about the maximum age that
+ * went into the call to TALER_age_restriction_commit.
+ */
+ struct TALER_AgeCommitment commitment;
+
+ /**
+ * The proof is used to create an attestation for a (compatible) minimum age.
+ */
+ struct TALER_AgeProof proof;
+};
+
+
+/**
+ * @brief Generates a hash of the public keys in the age commitment.
+ *
+ * @param commitment the age commitment - one public key per age group
+ * @param[out] hash resulting hash
+ */
+void
+TALER_age_commitment_hash (
+ const struct TALER_AgeCommitment *commitment,
+ struct TALER_AgeCommitmentHash *hash);
+
+
+/**
+ * @brief Generates an age commitent for the given age.
+ *
+ * @param mask The age mask the defines the age groups
+ * @param age The actual age for which an age commitment is generated
+ * @param seed The seed that goes into the key generation. MUST be chosen uniformly random.
+ * @param[out] comm_proof The generated age commitment, ->priv and ->pub allocated via GNUNET_malloc() on success
+ */
+void
+TALER_age_restriction_commit (
+ const struct TALER_AgeMask *mask,
+ uint8_t age,
+ const struct GNUNET_HashCode *seed,
+ struct TALER_AgeCommitmentProof *comm_proof);
+
+
+/**
+ * @brief Derives another, equivalent age commitment for a given one.
+ *
+ * @param orig Original age commitment
+ * @param salt Salt to randomly move the points on the elliptic curve in order to generate another, equivalent commitment.
+ * @param[out] derived The resulting age commitment, ->priv and ->pub allocated via GNUNET_malloc() on success.
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_age_commitment_derive (
+ const struct TALER_AgeCommitmentProof *orig,
+ const struct GNUNET_HashCode *salt,
+ struct TALER_AgeCommitmentProof *derived);
+
+
+/**
+ * @brief Provide attestation for a given age, from a given age commitment, if possible.
+ *
+ * @param comm_proof The age commitment to be used for attestation. For successful attestation, it must contain the private key for the corresponding age group.
+ * @param age Age (not age group) for which the an attestation should be done
+ * @param[out] attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicable.
+ * @return #GNUNET_OK on success, #GNUNET_NO when no attestation can be made for that age with the given commitment, #GNUNET_SYSERR otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_age_commitment_attest (
+ const struct TALER_AgeCommitmentProof *comm_proof,
+ uint8_t age,
+ struct TALER_AgeAttestation *attest);
+
+
+/**
+ * @brief Verify the attestation for an given age and age commitment
+ *
+ * @param commitment The age commitment that went into the attestation. Only the public keys are needed.
+ * @param age Age (not age group) for which the an attestation should be done
+ * @param attest Signature of the age with the appropriate key from the age commitment for the corresponding age group, if applicable.
+ * @return #GNUNET_OK when the attestation was successful, #GNUNET_NO no attestation couldn't be verified, #GNUNET_SYSERR otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_age_commitment_verify (
+ const struct TALER_AgeCommitment *commitment,
+ uint8_t age,
+ const struct TALER_AgeAttestation *attest);
+
+
+/**
+ * @brief helper function to free memory of a struct TALER_AgeCommitment
+ *
+ * @param ac the commitment from which all memory should be freed.
+ */
+void
+TALER_age_commitment_free (
+ struct TALER_AgeCommitment *ac);
+
+
+/**
+ * @brief helper function to free memory of a struct TALER_AgeProof
+ *
+ * @param ap the proof of commitment from which all memory should be freed.
+ */
+void
+TALER_age_proof_free (
+ struct TALER_AgeProof *ap);
+
+
+/**
+ * @brief helper function to free memory of a struct TALER_AgeCommitmentProof
+ *
+ * @param acp the commitment and its proof from which all memory should be freed.
+ */
+void
+TALER_age_commitment_proof_free (
+ struct TALER_AgeCommitmentProof *acp);
+
+
+/**
+ * @brief helper function to allocate and copy a struct TALER_AgeCommitmentProof
+ *
+ * @param[in] acp The original age commitment proof
+ * @return The deep copy of @e acp, allocated
+ */
+struct TALER_AgeCommitmentProof *
+TALER_age_commitment_proof_duplicate (
+ const struct TALER_AgeCommitmentProof *acp);
+
+/**
+ * @brief helper function to copy a struct TALER_AgeCommitmentProof
+ *
+ * @param[in] acp The original age commitment proof
+ * @param[out] nacp The struct to copy the data into, with freshly allocated and copied keys.
+ */
+void
+TALER_age_commitment_proof_deep_copy (
+ const struct TALER_AgeCommitmentProof *acp,
+ struct TALER_AgeCommitmentProof *nacp);
+
+/**
+ * @brief For age-withdraw, clients have to prove that the public keys for all
+ * age groups larger than the allowed maximum age group are derived by scalar
+ * multiplication from this Edx25519 public key (in Crockford Base32 encoding):
+ *
+ * DZJRF6HXN520505XDAWM8NMH36QV9J3VH77265WQ09EBQ76QSKCG
+ *
+ * Its private key was chosen randomly and then deleted.
+ */
+extern struct
+#ifndef AGE_RESTRICTION_WITH_ECDSA
+GNUNET_CRYPTO_Edx25519PublicKey
+#else
+GNUNET_CRYPTO_EcdsaPublicKey
+#endif
+TALER_age_commitment_base_public_key;
+
+/**
+ * @brief Similar to TALER_age_restriction_commit, but takes the coin's
+ * private key as seed input and calculates the public keys in the slots larger
+ * than the given age as derived from TALER_age_commitment_base_public_key.
+ *
+ * See https://docs.taler.net/core/api-exchange.html#withdraw-with-age-restriction
+ *
+ * @param secret The master secret of the coin from which we derive the age restriction
+ * @param mask The age mask, defining the age groups
+ * @param max_age The maximum age for this coin.
+ * @param[out] comm_proof The commitment and proof for age restriction for age @a max_age
+ */
+void
+TALER_age_restriction_from_secret (
+ const struct TALER_PlanchetMasterSecretP *secret,
+ const struct TALER_AgeMask *mask,
+ const uint8_t max_age,
+ struct TALER_AgeCommitmentProof *comm_proof);
+
+
+/**
+ * Group of Denominations. These are the common fields of an array of
+ * denominations.
+ *
+ * The corresponding JSON-blob will also contain an array of particular
+ * denominations with only the timestamps, cipher-specific public key and the
+ * master signature.
+ */
+struct TALER_DenominationGroup
+{
+
+ /**
+ * Value of coins in this denomination group.
+ */
+ struct TALER_Amount value;
+
+ /**
+ * Fee structure for all coins in the group.
+ */
+ struct TALER_DenomFeeSet fees;
+
+ /**
+ * Cipher used for the denomination.
+ */
+ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher;
+
+ /**
+ * Age mask for the denomination.
+ */
+ struct TALER_AgeMask age_mask;
+
+};
+
+
+/**
+ * Compute a unique key for the meta data of a denomination group.
+ *
+ * @param dg denomination group to evaluate
+ * @param[out] key key to set
+ */
+void
+TALER_denomination_group_get_key (
+ const struct TALER_DenominationGroup *dg,
+ struct GNUNET_HashCode *key);
+
+
+/**
+ * Token family public key.
+ */
+struct TALER_TokenFamilyPublicKey
+{
+ /**
+ * Type of the signature.
+ */
+ struct GNUNET_CRYPTO_BlindSignPublicKey public_key;
+};
+
+/**
+ * Hash of a public key of a token family.
+ */
+struct TALER_TokenFamilyPublicKeyHash
+{
+ /**
+ * Hash of the token public key.
+ */
+ struct GNUNET_HashCode hash;
+};
+
+/**
+ * Token family private key.
+ */
+struct TALER_TokenFamilyPrivateKey
+{
+ struct GNUNET_CRYPTO_BlindSignPrivateKey private_key;
+};
+
+/**
+ * Token public key.
+ */
+struct TALER_TokenPublicKey
+{
+ struct GNUNET_CRYPTO_EddsaPublicKey public_key;
+};
+
+/**
+ * Signature made using a token private key.
+ */
+struct TALER_TokenSignature
+{
+ struct GNUNET_CRYPTO_EddsaSignature signature;
+};
+
+/**
+ * Blind signature for a token (signed by merchant).
+ */
+struct TALER_TokenBlindSignature
+{
+ struct GNUNET_CRYPTO_BlindedSignature signature;
+};
+
#endif
diff --git a/src/include/taler_curl_lib.h b/src/include/taler_curl_lib.h
index d7c24a13b..f108e6158 100644
--- a/src/include/taler_curl_lib.h
+++ b/src/include/taler_curl_lib.h
@@ -30,7 +30,7 @@
/**
* Should we compress PUT/POST bodies with 'deflate' encoding?
*/
-#define COMPRESS_BODIES 1
+#define TALER_CURL_COMPRESS_BODIES 1
/**
* State used for #TALER_curl_easy_post() and
@@ -47,6 +47,11 @@ struct TALER_CURL_PostContext
* Custom headers.
*/
struct curl_slist *headers;
+
+ /**
+ * Set to true to disable compression of the body.
+ */
+ bool disable_compression;
};
@@ -59,7 +64,7 @@ struct TALER_CURL_PostContext
* @param body JSON body to add to @e ctx
* @return #GNUNET_OK on success #GNUNET_SYSERR on failure
*/
-int
+enum GNUNET_GenericReturnValue
TALER_curl_easy_post (struct TALER_CURL_PostContext *ctx,
CURL *eh,
const json_t *body);
@@ -74,4 +79,17 @@ void
TALER_curl_easy_post_finished (struct TALER_CURL_PostContext *ctx);
+/**
+ * Set a secure redirection policy, allowing a limited
+ * number of redirects and only going from HTTP to HTTPS
+ * but not from HTTPS to HTTP.
+ *
+ * @param[in,out] eh easy handle to modify
+ * @param url URL to base the redirect policy on;
+ * must start with "http://" or "https://"
+ */
+void
+TALER_curl_set_secure_redirect_policy (CURL *eh,
+ const char *url);
+
#endif
diff --git a/src/include/taler_error_codes.h b/src/include/taler_error_codes.h
deleted file mode 100644
index f75464c35..000000000
--- a/src/include/taler_error_codes.h
+++ /dev/null
@@ -1,2550 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2016, 2017, 2019 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file taler_error_codes.h
- * @brief error codes returned by GNU Taler
- *
- * This file defines constants for error codes returned
- * in Taler APIs. We use codes above 1000 to avoid any
- * confusing with HTTP status codes. All constants have the
- * shared prefix "TALER_EC_" to indicate that they are error
- * codes.
- *
- * THIS FILE IS AUTO-GENERATED, DO NOT MODIFY!
- * If you want to add an error code, please add it in the
- * taler-util.git repository. Instructions
- * for this are in the README in taler-util.git.
- */
-#ifndef TALER_ERROR_CODES_H
-#define TALER_ERROR_CODES_H
-
-/**
- * Enumeration with all possible Taler error codes.
- */
-enum TALER_ErrorCode
-{
-
- /**
- * Special code to indicate no error (or no "code" present).
- */
- TALER_EC_NONE = 0,
-
- /**
- * Special code to indicate that a non-integer error code was returned
- * in the JSON response.
- */
- TALER_EC_INVALID = 1,
-
- /**
- * The response we got from the server was not even in JSON format.
- */
- TALER_EC_INVALID_RESPONSE = 2,
-
- /**
- * Generic implementation error: this function was not yet
- * implemented.
- */
- TALER_EC_NOT_IMPLEMENTED = 3,
-
- /**
- * Exchange is badly configured and thus cannot operate.
- */
- TALER_EC_EXCHANGE_BAD_CONFIGURATION = 4,
-
- /**
- * Internal assertion error.
- */
- TALER_EC_INTERNAL_INVARIANT_FAILURE = 5,
-
- /**
- * Operation timed out.
- */
- TALER_EC_TIMEOUT = 6,
-
- /**
- * Exchange failed to allocate memory for building JSON reply.
- */
- TALER_EC_JSON_ALLOCATION_FAILURE = 7,
-
- /**
- * HTTP method invalid for this URL.
- */
- TALER_EC_METHOD_INVALID = 8,
-
- /**
- * Operation specified invalid for this URL (resulting in a "NOT
- * FOUND" for the overall response).
- */
- TALER_EC_OPERATION_INVALID = 9,
-
- /**
- * There is no endpoint defined for the URL provided by the client
- * (returned together with a #MHD_HTTP_NOT_FOUND status code).
- */
- TALER_EC_ENDPOINT_UNKNOWN = 10,
-
- /**
- * The URI is longer than the longest URI the HTTP server is willing
- * to parse. Returned together with an HTTP status code of
- * #MHD_HTTP_URI_TOO_LONG.
- */
- TALER_EC_URI_TOO_LONG = 11,
-
- /**
- * The number of segments included in the URI does not match the
- * number of segments expected by the endpoint. (returned together
- * with a #MHD_HTTP_NOT_FOUND status code).
- */
- TALER_EC_WRONG_NUMBER_OF_SEGMENTS = 12,
-
- /**
- * The start and end-times in the wire fee structure leave a hole.
- * This is not allowed. Generated as an error on the client-side.
- */
- TALER_EC_HOLE_IN_WIRE_FEE_STRUCTURE = 13,
-
- /**
- * The version string given does not follow the expected
- * CURRENT:REVISION:AGE Format. Generated as an error on the client
- * side.
- */
- TALER_EC_VERSION_MALFORMED = 14,
-
- /**
- * The client-side experienced an internal failure. Generated as an
- * error on the client side.
- */
- TALER_EC_CLIENT_INTERNAL_FAILURE = 15,
-
- /**
- * The exchange failed to even just initialize its connection to the
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DB_SETUP_FAILED = 1001,
-
- /**
- * The exchange encountered an error event to just start the database
- * transaction. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DB_START_FAILED = 1002,
-
- /**
- * The exchange encountered an error event to commit the database
- * transaction (hard, unrecoverable error). This response is provided
- * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DB_COMMIT_FAILED_HARD = 1003,
-
- /**
- * The exchange encountered an error event to commit the database
- * transaction, even after repeatedly retrying it there was always a
- * conflicting transaction. (This indicates a repeated serialization
- * error; should only happen if some client maliciously tries to
- * create conflicting concurrent transactions.) This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DB_COMMIT_FAILED_ON_RETRY = 1004,
-
- /**
- * The exchange had insufficient memory to parse the request. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PARSER_OUT_OF_MEMORY = 1005,
-
- /**
- * The JSON in the client's request to the exchange was malformed.
- * (Generic parse error). This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_JSON_INVALID = 1006,
-
- /**
- * The JSON in the client's request to the exchange was malformed.
- * Details about the location of the parse error are provided. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_JSON_INVALID_WITH_DETAILS = 1007,
-
- /**
- * A required parameter in the request to the exchange was missing.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PARAMETER_MISSING = 1008,
-
- /**
- * A parameter in the request to the exchange was malformed. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PARAMETER_MALFORMED = 1009,
-
- /**
- * The exchange failed to obtain the transaction history of the given
- * coin from the database while generating an insufficient funds
- * errors. This can happen during /deposit or /recoup requests. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_COIN_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1010,
-
- /**
- * Internal logic error. Some server-side function failed that really
- * should not. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_INTERNAL_LOGIC_ERROR = 1011,
-
- /**
- * The method specified in a payto:// URI is not one we expected.
- */
- TALER_EC_PAYTO_WRONG_METHOD = 1012,
-
- /**
- * The payto:// URI is malformed.
- */
- TALER_EC_PAYTO_MALFORMED = 1013,
-
- /**
- * We failed to update the database of known coins.
- */
- TALER_EC_DB_COIN_HISTORY_STORE_ERROR = 1014,
-
- /**
- * The public key of given to a /coins/ handler was malformed.
- */
- TALER_EC_COINS_INVALID_COIN_PUB = 1050,
-
- /**
- * The reserve key of given to a /reserves/ handler was malformed.
- */
- TALER_EC_RESERVES_INVALID_RESERVE_PUB = 1051,
-
- /**
- * The public key of given to a /transfers/ handler was malformed.
- */
- TALER_EC_TRANSFERS_INVALID_WTID = 1052,
-
- /**
- * The wire hash of given to a /deposits/ handler was malformed.
- */
- TALER_EC_DEPOSITS_INVALID_H_WIRE = 1053,
-
- /**
- * The merchant key of given to a /deposits/ handler was malformed.
- */
- TALER_EC_DEPOSITS_INVALID_MERCHANT_PUB = 1054,
-
- /**
- * The hash of the contract terms given to a /deposits/ handler was
- * malformed.
- */
- TALER_EC_DEPOSITS_INVALID_H_CONTRACT_TERMS = 1055,
-
- /**
- * The coin public key of given to a /deposits/ handler was malformed.
- */
- TALER_EC_DEPOSITS_INVALID_COIN_PUB = 1056,
-
- /**
- * The body returned by the exchange for a /deposits/ request was
- * malformed. Error created client-side.
- */
- TALER_EC_DEPOSITS_INVALID_BODY_BY_EXCHANGE = 1057,
-
- /**
- * The signature returned by the exchange in a /deposits/ request was
- * malformed. Error created client-side.
- */
- TALER_EC_DEPOSITS_INVALID_SIGNATURE_BY_EXCHANGE = 1058,
-
- /**
- * The given reserve does not have sufficient funds to admit the
- * requested withdraw operation at this time. The response includes
- * the current "balance" of the reserve as well as the transaction
- * "history" that lead to this balance. This response is provided
- * with HTTP status code #MHD_HTTP_CONFLICT.
- */
- TALER_EC_WITHDRAW_INSUFFICIENT_FUNDS = 1100,
-
- /**
- * The exchange has no information about the "reserve_pub" that was
- * given. This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_WITHDRAW_RESERVE_UNKNOWN = 1101,
-
- /**
- * The amount to withdraw together with the fee exceeds the numeric
- * range for Taler amounts. This is not a client failure, as the coin
- * value and fees come from the exchange's configuration. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_AMOUNT_FEE_OVERFLOW = 1102,
-
- /**
- * All of the deposited amounts into this reserve total up to a value
- * that is too big for the numeric range for Taler amounts. This is
- * not a client failure, as the transaction history comes from the
- * exchange's configuration. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_AMOUNT_DEPOSITS_OVERFLOW = 1103,
-
- /**
- * For one of the historic withdrawals from this reserve, the exchange
- * could not find the denomination key. This is not a client failure,
- * as the transaction history comes from the exchange's configuration.
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_HISTORIC_DENOMINATION_KEY_NOT_FOUND = 1104,
-
- /**
- * All of the withdrawals from reserve total up to a value that is too
- * big for the numeric range for Taler amounts. This is not a client
- * failure, as the transaction history comes from the exchange's
- * configuration. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_AMOUNT_WITHDRAWALS_OVERFLOW = 1105,
-
- /**
- * The exchange somehow knows about this reserve, but there seem to
- * have been no wire transfers made. This is not a client failure, as
- * this is a database consistency issue of the exchange. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_RESERVE_WITHOUT_WIRE_TRANSFER = 1106,
-
- /**
- * The exchange failed to create the signature using the denomination
- * key. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_SIGNATURE_FAILED = 1107,
-
- /**
- * The exchange failed to store the withdraw operation in its
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_DB_STORE_ERROR = 1108,
-
- /**
- * The exchange failed to check against historic withdraw data from
- * database (as part of ensuring the idempotency of the operation).
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_DB_FETCH_ERROR = 1109,
-
- /**
- * The exchange is not aware of the denomination key the wallet
- * requested for the withdrawal. This response is provided with HTTP
- * status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_WITHDRAW_DENOMINATION_KEY_NOT_FOUND = 1110,
-
- /**
- * The signature of the reserve is not valid. This response is
- * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_WITHDRAW_RESERVE_SIGNATURE_INVALID = 1111,
-
- /**
- * When computing the reserve history, we ended up with a negative
- * overall balance, which should be impossible. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1112,
-
- /**
- * When computing the reserve history, we ended up with a negative
- * overall balance, which should be impossible. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_RESERVE_HISTORY_IMPOSSIBLE = 1113,
-
- /**
- * Validity period of the coin to be withdrawn is in the future.
- * Returned with an HTTP status of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_WITHDRAW_VALIDITY_IN_FUTURE = 1114,
-
- /**
- * Withdraw period of the coin to be withdrawn is in the past.
- * Returned with an HTTP status of #MHD_HTTP_GONE.
- */
- TALER_EC_WITHDRAW_VALIDITY_IN_PAST = 1115,
-
- /**
- * Withdraw period of the coin to be withdrawn is in the past.
- * Returned with an HTTP status of #MHD_HTTP_GONE.
- */
- TALER_EC_DENOMINATION_KEY_LOST = 1116,
-
- /**
- * The exchange's database entry with the reserve balance summary is
- * inconsistent with its own history of the reserve. Returned with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_WITHDRAW_RESERVE_BALANCE_CORRUPT = 1117,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_WITHDRAW_REPLY_MALFORMED = 1118,
-
- /**
- * The client failed to unblind the blind signature. This error is not
- * used in the protocol but created client-side.
- */
- TALER_EC_WITHDRAW_UNBLIND_FAILURE = 1119,
-
- /**
- * The exchange failed to obtain the transaction history of the given
- * reserve from the database. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_RESERVE_STATUS_DB_ERROR = 1150,
-
- /**
- * The reserve status was requested using a unknown key, to be
- * returned with 404 Not Found.
- */
- TALER_EC_RESERVE_STATUS_UNKNOWN = 1151,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_RESERVE_STATUS_REPLY_MALFORMED = 1152,
-
- /**
- * The respective coin did not have sufficient residual value for the
- * /deposit operation (i.e. due to double spending). The "history" in
- * the respose provides the transaction history of the coin proving
- * this fact. This response is provided with HTTP status code
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS = 1200,
-
- /**
- * The exchange failed to obtain the transaction history of the given
- * coin from the database (this does not happen merely because the
- * coin is seen by the exchange for the first time). This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSIT_HISTORY_DB_ERROR = 1201,
-
- /**
- * The exchange failed to store the /depost information in the
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSIT_STORE_DB_ERROR = 1202,
-
- /**
- * The exchange database is unaware of the denomination key that
- * signed the coin (however, the exchange process is; this is not
- * supposed to happen; it can happen if someone decides to purge the
- * DB behind the back of the exchange process). Hence the deposit is
- * being refused. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSIT_DB_DENOMINATION_KEY_UNKNOWN = 1203,
-
- /**
- * The exchange was trying to lookup the denomination key for the
- * purpose of a DEPOSIT operation. However, the denomination key is
- * unavailable for that purpose. This can be because it is entirely
- * unknown to the exchange or not in the validity period for the
- * deposit operation. Hence the deposit is being refused. This
- * response is provided with HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_DEPOSIT_DENOMINATION_KEY_UNKNOWN = 1204,
-
- /**
- * The signature made by the coin over the deposit permission is not
- * valid. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_COIN_SIGNATURE_INVALID = 1205,
-
- /**
- * The signature of the denomination key over the coin is not valid.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_DENOMINATION_SIGNATURE_INVALID = 1206,
-
- /**
- * The stated value of the coin after the deposit fee is subtracted
- * would be negative. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_NEGATIVE_VALUE_AFTER_FEE = 1207,
-
- /**
- * The stated refund deadline is after the wire deadline. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_REFUND_DEADLINE_AFTER_WIRE_DEADLINE = 1208,
-
- /**
- * The exchange does not recognize the validity of or support the
- * given wire format type. This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_TYPE = 1209,
-
- /**
- * The exchange failed to canonicalize and hash the given wire format.
- * For example, the merchant failed to provide the "salt" or a valid
- * payto:// URI in the wire details. Note that while the exchange
- * will do some basic sanity checking on the wire details, it cannot
- * warrant that the banking system will ultimately be able to route to
- * the specified address, even if this check passed. This response is
- * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_JSON = 1210,
-
- /**
- * The hash of the given wire address does not match the hash
- * specified in the proposal data. This response is provided with
- * HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_CONTRACT_HASH_CONFLICT = 1211,
-
- /**
- * The exchange detected that the given account number is invalid for
- * the selected wire format type. This response is provided with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSIT_INVALID_WIRE_FORMAT_ACCOUNT_NUMBER = 1213,
-
- /**
- * Timestamp included in deposit permission is intolerably far off
- * with respect to the clock of the exchange.
- */
- TALER_EC_DEPOSIT_INVALID_TIMESTAMP = 1218,
-
- /**
- * Validity period of the denomination key is in the future. Returned
- * with an HTTP status of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_DEPOSIT_DENOMINATION_VALIDITY_IN_FUTURE = 1219,
-
- /**
- * Denomination key of the coin is past the deposit deadline.
- * Returned with an HTTP status of #MHD_HTTP_GONE.
- */
- TALER_EC_DEPOSIT_DENOMINATION_EXPIRED = 1220,
-
- /**
- * The signature provided by the exchange is not valid. Error created
- * client-side.
- */
- TALER_EC_DEPOSIT_INVALID_SIGNATURE_BY_EXCHANGE = 1221,
-
- /**
- * The currency specified for the deposit is different from the
- * currency of the coin. This response is provided with HTTP status
- * code #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_DEPOSIT_CURRENCY_MISMATCH = 1222,
-
- /**
- * The respective coin did not have sufficient residual value for the
- * /refresh/melt operation. The "history" in this response provdes
- * the "residual_value" of the coin, which may be less than its
- * "original_value". This response is provided with HTTP status code
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_MELT_INSUFFICIENT_FUNDS = 1300,
-
- /**
- * The respective coin did not have sufficient residual value for the
- * /refresh/melt operation. The "history" in this response provdes
- * the "residual_value" of the coin, which may be less than its
- * "original_value". This response is provided with HTTP status code
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_MELT_DENOMINATION_KEY_NOT_FOUND = 1301,
-
- /**
- * The exchange had an internal error reconstructing the transaction
- * history of the coin that was being melted. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_MELT_COIN_HISTORY_COMPUTATION_FAILED = 1302,
-
- /**
- * The exchange failed to check against historic melt data from
- * database (as part of ensuring the idempotency of the operation).
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_MELT_DB_FETCH_ERROR = 1303,
-
- /**
- * The exchange failed to store session data in the database. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_MELT_DB_STORE_SESSION_ERROR = 1304,
-
- /**
- * The exchange encountered melt fees exceeding the melted coin's
- * contribution. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_MELT_FEES_EXCEED_CONTRIBUTION = 1305,
-
- /**
- * The denomination key signature on the melted coin is invalid. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_MELT_DENOMINATION_SIGNATURE_INVALID = 1306,
-
- /**
- * The signature made with the coin to be melted is invalid. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_MELT_COIN_SIGNATURE_INVALID = 1307,
-
- /**
- * The exchange failed to obtain the transaction history of the given
- * coin from the database while generating an insufficient funds
- * errors. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_MELT_HISTORY_DB_ERROR_INSUFFICIENT_FUNDS = 1308,
-
- /**
- * The denomination of the given coin has past its expiration date and
- * it is also not a valid zombie (that is, was not refreshed with the
- * fresh coin being subjected to recoup).
- */
- TALER_EC_MELT_COIN_EXPIRED_NO_ZOMBIE = 1309,
-
- /**
- * The signature returned by the exchange in a melt request was
- * malformed. Error created client-side.
- */
- TALER_EC_MELT_INVALID_SIGNATURE_BY_EXCHANGE = 1310,
-
- /**
- * The currency specified for the melt amount is different from the
- * currency of the coin. This response is provided with HTTP status
- * code #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_MELT_CURRENCY_MISMATCH = 1311,
-
- /**
- * The exchange is unaware of the denomination key that was used to
- * sign the melted zombie coin. This response is provided with HTTP
- * status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_REFRESH_RECOUP_DENOMINATION_KEY_NOT_FOUND = 1351,
-
- /**
- * Validity period of the denomination key is in the future. Returned
- * with an HTTP status of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_REFRESH_RECOUP_DENOMINATION_VALIDITY_IN_FUTURE = 1352,
-
- /**
- * Denomination key of the coin is past the deposit deadline.
- * Returned with an HTTP status of #MHD_HTTP_GONE.
- */
- TALER_EC_REFRESH_RECOUP_DENOMINATION_EXPIRED = 1353,
-
- /**
- * Denomination key of the coin is past the deposit deadline.
- * Returned with an HTTP status of #MHD_HTTP_GONE.
- */
- TALER_EC_REFRESH_ZOMBIE_DENOMINATION_EXPIRED = 1354,
-
- /**
- * The provided transfer keys do not match up with the original
- * commitment. Information about the original commitment is included
- * in the response. This response is provided with HTTP status code
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_REVEAL_COMMITMENT_VIOLATION = 1370,
-
- /**
- * Failed to produce the blinded signatures over the coins to be
- * returned. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_SIGNING_ERROR = 1371,
-
- /**
- * The exchange is unaware of the refresh session specified in the
- * request. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_SESSION_UNKNOWN = 1372,
-
- /**
- * The exchange failed to retrieve valid session data from the
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_DB_FETCH_SESSION_ERROR = 1373,
-
- /**
- * The exchange failed to retrieve previously revealed data from the
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_DB_FETCH_REVEAL_ERROR = 1374,
-
- /**
- * The exchange failed to retrieve commitment data from the database.
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_DB_COMMIT_ERROR = 1375,
-
- /**
- * The size of the cut-and-choose dimension of the private transfer
- * keys request does not match #TALER_CNC_KAPPA - 1. This response is
- * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_CNC_TRANSFER_ARRAY_SIZE_INVALID = 1376,
-
- /**
- * The number of coins to be created in refresh exceeds the limits of
- * the exchange. private transfer keys request does not match
- * #TALER_CNC_KAPPA - 1. This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_NEW_DENOMS_ARRAY_SIZE_EXCESSIVE = 1377,
-
- /**
- * The number of envelopes given does not match the number of
- * denomination keys given. This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_NEW_DENOMS_ARRAY_SIZE_MISMATCH = 1378,
-
- /**
- * The exchange encountered a numeric overflow totaling up the cost
- * for the refresh operation. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_COST_CALCULATION_OVERFLOW = 1379,
-
- /**
- * The exchange's cost calculation shows that the melt amount is below
- * the costs of the transaction. This response is provided with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_AMOUNT_INSUFFICIENT = 1380,
-
- /**
- * The exchange is unaware of the denomination key that was requested
- * for one of the fresh coins. This response is provided with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_FRESH_DENOMINATION_KEY_NOT_FOUND = 1381,
-
- /**
- * The signature made with the coin over the link data is invalid.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REVEAL_LINK_SIGNATURE_INVALID = 1382,
-
- /**
- * The exchange failed to generate the signature as it could not find
- * the signing key for the denomination. This response is provided
- * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REVEAL_KEYS_MISSING = 1383,
-
- /**
- * The refresh session hash given to a /refreshes/ handler was
- * malformed.
- */
- TALER_EC_REVEAL_INVALID_RCH = 1384,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_REVEAL_REPLY_MALFORMED = 1385,
-
- /**
- * The coin specified in the link request is unknown to the exchange.
- * This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_LINK_COIN_UNKNOWN = 1400,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_LINK_REPLY_MALFORMED = 1401,
-
- /**
- * The exchange knows literally nothing about the coin we were asked
- * to refund. But without a transaction history, we cannot issue a
- * refund. This is kind-of OK, the owner should just refresh it
- * directly without executing the refund. This response is provided
- * with HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_REFUND_COIN_NOT_FOUND = 1500,
-
- /**
- * We could not process the refund request as the coin's transaction
- * history does not permit the requested refund at this time. The
- * "history" in the response proves this. This response is provided
- * with HTTP status code #MHD_HTTP_CONFLICT.
- */
- TALER_EC_REFUND_CONFLICT = 1501,
-
- /**
- * The exchange knows about the coin we were asked to refund, but not
- * about the specific /deposit operation. Hence, we cannot issue a
- * refund (as we do not know if this merchant public key is authorized
- * to do a refund). This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_REFUND_DEPOSIT_NOT_FOUND = 1503,
-
- /**
- * The currency specified for the refund is different from the
- * currency of the coin. This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REFUND_CURRENCY_MISMATCH = 1504,
-
- /**
- * When we tried to check if we already paid out the coin, the
- * exchange's database suddenly disagreed with data it previously
- * provided (internal inconsistency). This response is provided with
- * HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REFUND_DB_INCONSISTENT = 1505,
-
- /**
- * The exchange can no longer refund the customer/coin as the money
- * was already transferred (paid out) to the merchant. (It should be
- * past the refund deadline.) This response is provided with HTTP
- * status code #MHD_HTTP_GONE.
- */
- TALER_EC_REFUND_MERCHANT_ALREADY_PAID = 1506,
-
- /**
- * The amount the exchange was asked to refund exceeds (with fees) the
- * total amount of the deposit (including fees). This response is
- * provided with HTTP status code #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_REFUND_INSUFFICIENT_FUNDS = 1507,
-
- /**
- * The exchange failed to recover information about the denomination
- * key of the refunded coin (even though it recognizes the key).
- * Hence it could not check the fee strucutre. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REFUND_DENOMINATION_KEY_NOT_FOUND = 1508,
-
- /**
- * The refund fee specified for the request is lower than the refund
- * fee charged by the exchange for the given denomination key of the
- * refunded coin. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REFUND_FEE_TOO_LOW = 1509,
-
- /**
- * The exchange failed to store the refund information to its
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REFUND_STORE_DB_ERROR = 1510,
-
- /**
- * The refund fee is specified in a different currency than the refund
- * amount. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REFUND_FEE_CURRENCY_MISMATCH = 1511,
-
- /**
- * The refunded amount is smaller than the refund fee, which would
- * result in a negative refund. This response is provided with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REFUND_FEE_ABOVE_AMOUNT = 1512,
-
- /**
- * The signature of the merchant is invalid. This response is provided
- * with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_REFUND_MERCHANT_SIGNATURE_INVALID = 1513,
-
- /**
- * Merchant backend failed to create the refund confirmation
- * signature. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_REFUND_MERCHANT_SIGNING_FAILED = 1514,
-
- /**
- * The signature returned by the exchange in a refund request was
- * malformed. Error created client-side.
- */
- TALER_EC_REFUND_INVALID_SIGNATURE_BY_EXCHANGE = 1515,
-
- /**
- * The wire format specified in the "sender_account_details" is not
- * understood or not supported by this exchange. Returned with an HTTP
- * status code of #MHD_HTTP_NOT_FOUND. (As we did not find an
- * interpretation of the wire format.)
- */
- TALER_EC_ADMIN_ADD_INCOMING_WIREFORMAT_UNSUPPORTED = 1600,
-
- /**
- * The currency specified in the "amount" parameter is not supported
- * by this exhange. Returned with an HTTP status code of
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_ADMIN_ADD_INCOMING_CURRENCY_UNSUPPORTED = 1601,
-
- /**
- * The exchange failed to store information about the incoming
- * transfer in its database. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ADMIN_ADD_INCOMING_DB_STORE = 1602,
-
- /**
- * The exchange encountered an error (that is not about not finding
- * the wire transfer) trying to lookup a wire transfer identifier in
- * the database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRANSFERS_GET_DB_FETCH_FAILED = 1700,
-
- /**
- * The exchange found internally inconsistent data when resolving a
- * wire transfer identifier in the database. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRANSFERS_GET_DB_INCONSISTENT = 1701,
-
- /**
- * The exchange did not find information about the specified wire
- * transfer identifier in the database. This response is provided
- * with HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_TRANSFERS_GET_WTID_NOT_FOUND = 1702,
-
- /**
- * The exchange did not find information about the wire transfer fees
- * it charged. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRANSFERS_GET_WIRE_FEE_NOT_FOUND = 1703,
-
- /**
- * The exchange found a wire fee that was above the total transfer
- * value (and thus could not have been charged). This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRANSFERS_GET_WIRE_FEE_INCONSISTENT = 1704,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_TRANSFERS_GET_REPLY_MALFORMED = 1705,
-
- /**
- * The exchange found internally inconsistent fee data when resolving
- * a transaction in the database. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSITS_GET_DB_FEE_INCONSISTENT = 1800,
-
- /**
- * The exchange encountered an error (that is not about not finding
- * the transaction) trying to lookup a transaction in the database.
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSITS_GET_DB_FETCH_FAILED = 1801,
-
- /**
- * The exchange did not find information about the specified
- * transaction in the database. This response is provided with HTTP
- * status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_DEPOSITS_GET_NOT_FOUND = 1802,
-
- /**
- * The exchange failed to identify the wire transfer of the
- * transaction (or information about the plan that it was supposed to
- * still happen in the future). This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSITS_GET_WTID_RESOLUTION_ERROR = 1803,
-
- /**
- * The signature of the merchant is invalid. This response is provided
- * with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_DEPOSITS_GET_MERCHANT_SIGNATURE_INVALID = 1804,
-
- /**
- * The given denomination key is not in the "recoup" set of the
- * exchange right now. This response is provided with an HTTP status
- * code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_RECOUP_DENOMINATION_KEY_UNKNOWN = 1850,
-
- /**
- * The given coin signature is invalid for the request. This response
- * is provided with an HTTP status code of #MHD_HTTP_FORBIDDEN.
- */
- TALER_EC_RECOUP_SIGNATURE_INVALID = 1851,
-
- /**
- * The signature of the denomination key over the coin is not valid.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_RECOUP_DENOMINATION_SIGNATURE_INVALID = 1852,
-
- /**
- * The exchange failed to access its own database about reserves. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_RECOUP_DB_FETCH_FAILED = 1853,
-
- /**
- * The exchange could not find the corresponding withdraw operation.
- * The request is denied. This response is provided with an HTTP
- * status code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_RECOUP_WITHDRAW_NOT_FOUND = 1854,
-
- /**
- * The exchange obtained an internally inconsistent transaction
- * history for the given coin. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_RECOUP_HISTORY_DB_ERROR = 1855,
-
- /**
- * The exchange failed to store information about the recoup to be
- * performed in the database. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_RECOUP_DB_PUT_FAILED = 1856,
-
- /**
- * The coin's remaining balance is zero. The request is denied. This
- * response is provided with an HTTP status code of
- * #MHD_HTTP_FORBIDDEN.
- */
- TALER_EC_RECOUP_COIN_BALANCE_ZERO = 1857,
-
- /**
- * The exchange failed to reproduce the coin's blinding. This response
- * is provided with an HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_RECOUP_BLINDING_FAILED = 1858,
-
- /**
- * The coin's remaining balance is zero. The request is denied. This
- * response is provided with an HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR
- */
- TALER_EC_RECOUP_COIN_BALANCE_NEGATIVE = 1859,
-
- /**
- * Validity period of the denomination key is in the future. Returned
- * with an HTTP status of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_RECOUP_DENOMINATION_VALIDITY_IN_FUTURE = 1860,
-
- /**
- * The exchange responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_RECOUP_REPLY_MALFORMED = 1861,
-
- /**
- * The "have" parameter was not a natural number. This response is
- * provied with an HTTP status code of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_KEYS_HAVE_NOT_NUMERIC = 1900,
-
- /**
- * We currently cannot find any keys. This response is provied with an
- * HTTP status code of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_KEYS_MISSING = 1901,
-
- /**
- * This exchange does not allow clients to request /keys for times
- * other than the current (exchange) time. This response is provied
- * with an HTTP status code of #MHD_HTTP_FORBIDDEN.
- */
- TALER_EC_KEYS_TIMETRAVEL_FORBIDDEN = 1902,
-
- /**
- * The keys response was malformed. This error is generated client-
- * side.
- */
- TALER_EC_KEYS_INVALID = 1903,
-
- /**
- * The backend could not find the merchant instance specified in the
- * request. This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_INSTANCE_UNKNOWN = 2000,
-
- /**
- * The backend lacks a wire transfer method configuration option for
- * the given instance.
- */
- TALER_EC_PROPOSAL_INSTANCE_CONFIGURATION_LACKS_WIRE = 2002,
-
- /**
- * The merchant failed to provide a meaningful response to a /pay
- * request. This error is created client-side.
- */
- TALER_EC_PAY_MERCHANT_INVALID_RESPONSE = 2100,
-
- /**
- * The exchange failed to provide a meaningful response to a /deposit
- * request. This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY, or #MHD_HTTP_CONFLICT in case the
- * exchange reports #TALER_EC_DEPOSIT_INSUFFICIENT_FUNDS (aka double
- * spending).
- */
- TALER_EC_PAY_EXCHANGE_FAILED = 2101,
-
- /**
- * The merchant failed to commit the exchanges' response to a /deposit
- * request to its database. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_DB_STORE_PAY_ERROR = 2102,
-
- /**
- * The specified exchange is not supported/trusted by this merchant.
- * This response is provided with HTTP status code
- * #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_PAY_EXCHANGE_REJECTED = 2103,
-
- /**
- * The denomination key used for payment is not listed among the
- * denomination keys of the exchange. This response is provided with
- * HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_DENOMINATION_KEY_NOT_FOUND = 2104,
-
- /**
- * The denomination key used for payment is not audited by an auditor
- * approved by the merchant. This response is provided with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_DENOMINATION_KEY_AUDITOR_FAILURE = 2105,
-
- /**
- * There was an integer overflow totaling up the amounts or deposit
- * fees in the payment. This response is provided with HTTP status
- * code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_AMOUNT_OVERFLOW = 2106,
-
- /**
- * The deposit fees exceed the total value of the payment. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_FEES_EXCEED_PAYMENT = 2107,
-
- /**
- * After considering deposit and wire fees, the payment is
- * insufficient to satisfy the required amount for the contract. The
- * client should revisit the logic used to calculate fees it must
- * cover. This response is provided with HTTP status code
- * #MHD_HTTP_ACCEPTED.
- */
- TALER_EC_PAY_PAYMENT_INSUFFICIENT_DUE_TO_FEES = 2108,
-
- /**
- * Even if we do not consider deposit and wire fees, the payment is
- * insufficient to satisfy the required amount for the contract. This
- * response is provided with HTTP status code #MHD_HTTP_ACCEPTED.
- */
- TALER_EC_PAY_PAYMENT_INSUFFICIENT = 2109,
-
- /**
- * The signature over the contract of one of the coins was invalid.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_COIN_SIGNATURE_INVALID = 2110,
-
- /**
- * We failed to contact the exchange for the /pay request. This
- * response is provided with HTTP status code
- * #MHD_HTTP_REQUEST_TIMEOUT.
- */
- TALER_EC_PAY_EXCHANGE_TIMEOUT = 2111,
-
- /**
- * When we tried to find information about the exchange to issue the
- * deposit, we failed. This usually only happens if the merchant
- * backend is somehow unable to get its own HTTP client logic to work.
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_EXCHANGE_LOOKUP_FAILED = 2112,
-
- /**
- * The refund deadline in the contract is after the transfer deadline.
- * This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR as this should have been caught
- * when the offer was first setup.
- */
- TALER_EC_PAY_REFUND_DEADLINE_PAST_WIRE_TRANSFER_DEADLINE = 2114,
-
- /**
- * The request fails to provide coins for the payment. This response
- * is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_COINS_ARRAY_EMPTY = 2115,
-
- /**
- * The merchant failed to fetch the contract terms from the merchant's
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_DB_FETCH_PAY_ERROR = 2116,
-
- /**
- * The merchant failed to fetch the merchant's previous state with
- * respect to transactions from its database. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_DB_FETCH_TRANSACTION_ERROR = 2117,
-
- /**
- * The merchant failed to store the merchant's state with respect to
- * the transaction in its database. This response is provided with
- * HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_DB_STORE_TRANSACTION_ERROR = 2119,
-
- /**
- * The exchange failed to provide a valid response to the merchant's
- * /keys request. This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENDCY.
- */
- TALER_EC_PAY_EXCHANGE_KEYS_FAILURE = 2120,
-
- /**
- * The payment is too late, the offer has expired. This response is
- * provided with HTTP status code #MHD_HTTP_GONE.
- */
- TALER_EC_PAY_OFFER_EXPIRED = 2121,
-
- /**
- * The "merchant" field is missing in the proposal data. This response
- * is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PAY_MERCHANT_FIELD_MISSING = 2122,
-
- /**
- * Failed computing a hash code (likely server out-of-memory). This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_FAILED_COMPUTE_PROPOSAL_HASH = 2123,
-
- /**
- * Failed to locate merchant's account information matching the wire
- * hash given in the proposal. This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_WIRE_HASH_UNKNOWN = 2124,
-
- /**
- * We got different currencies for the wire fee and the maximum wire
- * fee. This response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_WIRE_FEE_CURRENCY_MISMATCH = 2125,
-
- /**
- * A unknown merchant public key was included in the payment. That
- * happens typically when the wallet sends the payment to the wrong
- * merchant instance. This response is provided with an HTTP status
- * code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_PAY_WRONG_INSTANCE = 2127,
-
- /**
- * The exchange failed to give us a response when we asked for /keys.
- * This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_PAY_EXCHANGE_HAS_NO_KEYS = 2128,
-
- /**
- * The deposit time for the denomination has expired. This response is
- * provided with HTTP status code #MHD_HTTP_GONE.
- */
- TALER_EC_PAY_DENOMINATION_DEPOSIT_EXPIRED = 2129,
-
- /**
- * The proposal is not known to the backend. This response is provided
- * with an HTTP status code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_PAY_PROPOSAL_NOT_FOUND = 2130,
-
- /**
- * The exchange of the deposited coin charges a wire fee that could
- * not be added to the total (total amount too high). This response
- * is provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_EXCHANGE_WIRE_FEE_ADDITION_FAILED = 2131,
-
- /**
- * The contract was not fully paid because of refunds. Note that
- * clients MAY treat this as paid if, for example, contracts must be
- * executed despite of refunds. This response is provided with HTTP
- * status code #MHD_HTTP_PAYMENT_REQUIRED.
- */
- TALER_EC_PAY_REFUNDED = 2132,
-
- /**
- * According to our database, we have refunded more than we were paid
- * (which should not be possible). This response is provided with HTTP
- * status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PAY_REFUNDS_EXCEED_PAYMENTS = 2133,
-
- /**
- * Legacy stuff. Remove me with protocol v1. This response is provided
- * with HTTP status code #MHD_HTTP_PREREQUISTE.
- */
- TALER_EC_PAY_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE = 2134,
-
- /**
- * The merchant failed to contact the exchange. This response is
- * provided with HTTP status code of #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_ABORT_EXCHANGE_KEYS_FAILURE = 2150,
-
- /**
- * The merchant failed to send the exchange the refund request. This
- * response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ABORT_EXCHANGE_REFUND_FAILED = 2151,
-
- /**
- * The merchant failed to find the exchange to process the lookup.
- * This response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ABORT_EXCHANGE_LOOKUP_FAILED = 2152,
-
- /**
- * The merchant failed to store the abort request in its database.
- * This response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ABORT_DB_STORE_ABORT_ERROR = 2153,
-
- /**
- * The merchant failed to repeatedly serialize the transaction. This
- * response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ABORT_DB_STORE_TRANSACTION_ERROR = 2154,
-
- /**
- * The merchant failed in the lookup part of the transaction. This
- * response is provided with HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ABORT_DB_FETCH_TRANSACTION_ERROR = 2155,
-
- /**
- * The merchant could not find the contract. This response is provided
- * with HTTP status code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_ABORT_CONTRACT_NOT_FOUND = 2156,
-
- /**
- * The payment was already completed and thus cannot be aborted
- * anymore. This response is provided with HTTP status code of
- * #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_ABORT_REFUND_REFUSED_PAYMENT_COMPLETE = 2157,
-
- /**
- * The hash provided by the wallet does not match the order. This
- * response is provided with HTTP status code of #MHD_HTTP_FORBIDDEN.
- */
- TALER_EC_ABORT_CONTRACT_HASH_MISSMATCH = 2158,
-
- /**
- * The array of coins cannot be empty. This response is provided with
- * HTTP status code of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_ABORT_COINS_ARRAY_EMPTY = 2159,
-
- /**
- * The merchant experienced a timeout processing the request. This
- * response is provided with HTTP status code of
- * #MHD_HTTP_REQUEST_TIMEOUT.
- */
- TALER_EC_ABORT_EXCHANGE_TIMEOUT = 2160,
-
- /**
- * Integer overflow with specified timestamp argument detected. This
- * response is provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_HISTORY_TIMESTAMP_OVERFLOW = 2200,
-
- /**
- * Failed to retrieve history from merchant database. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_HISTORY_DB_FETCH_ERROR = 2201,
-
- /**
- * The backend could not find the contract specified in the request.
- * This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_POLL_PAYMENT_CONTRACT_NOT_FOUND = 2250,
-
- /**
- * The response provided by the merchant backend was malformed. This
- * error is created client-side.
- */
- TALER_EC_POLL_PAYMENT_REPLY_MALFORMED = 2251,
-
- /**
- * We failed to contact the exchange for the /track/transaction
- * request. This response is provided with HTTP status code
- * #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_TRACK_TRANSACTION_EXCHANGE_TIMEOUT = 2300,
-
- /**
- * We failed to get a valid /keys response from the exchange for the
- * /track/transaction request. This response is provided with HTTP
- * status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSACTION_EXCHANGE_KEYS_FAILURE = 2301,
-
- /**
- * The backend could not find the transaction specified in the
- * request. This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_TRACK_TRANSACTION_TRANSACTION_UNKNOWN = 2302,
-
- /**
- * The backend had a database access error trying to retrieve
- * transaction data from its database. The response is provided with
- * HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSACTION_DB_FETCH_TRANSACTION_ERROR = 2303,
-
- /**
- * The backend had a database access error trying to retrieve payment
- * data from its database. The response is provided with HTTP status
- * code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSACTION_DB_FETCH_PAYMENT_ERROR = 2304,
-
- /**
- * The backend found no applicable deposits in the database. This is
- * odd, as we know about the transaction, but not about deposits we
- * made for the transaction. The response is provided with HTTP
- * status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_TRACK_TRANSACTION_DB_NO_DEPOSITS_ERROR = 2305,
-
- /**
- * We failed to obtain a wire transfer identifier for one of the coins
- * in the transaction. The response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY if the exchange had a hard error, or
- * #MHD_HTTP_ACCEPTED if the exchange signaled that the transfer was
- * in progress.
- */
- TALER_EC_TRACK_TRANSACTION_COIN_TRACE_ERROR = 2306,
-
- /**
- * We failed to obtain the full wire transfer identifier for the
- * transfer one of the coins was aggregated into. The response is
- * provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSACTION_WIRE_TRANSFER_TRACE_ERROR = 2307,
-
- /**
- * We got conflicting reports from the exhange with respect to which
- * transfers are included in which aggregate. The response is provided
- * with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSACTION_CONFLICTING_REPORTS = 2308,
-
- /**
- * We failed to contact the exchange for the /track/transfer request.
- * This response is provided with HTTP status code
- * #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_TRACK_TRANSFER_EXCHANGE_TIMEOUT = 2400,
-
- /**
- * We failed to obtain an acceptable /keys response from the exchange
- * for the /track/transfer request. This response is provided with
- * HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSFER_EXCHANGE_KEYS_FAILURE = 2401,
-
- /**
- * We failed to persist coin wire transfer information in our merchant
- * database. The response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSFER_DB_STORE_COIN_ERROR = 2402,
-
- /**
- * We internally failed to execute the /track/transfer request. The
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSFER_REQUEST_ERROR = 2403,
-
- /**
- * We failed to persist wire transfer information in our merchant
- * database. The response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSFER_DB_STORE_TRANSFER_ERROR = 2404,
-
- /**
- * The exchange returned an error from /track/transfer. The response
- * is provided with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSFER_EXCHANGE_ERROR = 2405,
-
- /**
- * We failed to fetch deposit information from our merchant database.
- * The response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSFER_DB_FETCH_DEPOSIT_ERROR = 2406,
-
- /**
- * We encountered an internal logic error. The response is provided
- * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TRACK_TRANSFER_DB_INTERNAL_LOGIC_ERROR = 2407,
-
- /**
- * The exchange gave conflicting information about a coin which has
- * been wire transferred. The response is provided with HTTP status
- * code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSFER_CONFLICTING_REPORTS = 2408,
-
- /**
- * The merchant backend had problems in creating the JSON response.
- */
- TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR = 2409,
-
- /**
- * The exchange charged a different wire fee than what it originally
- * advertised, and it is higher. The response is provied with an HTTP
- * status of #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TRACK_TRANSFER_JSON_BAD_WIRE_FEE = 2410,
-
- /**
- * The merchant backend cannot create an instance under the given
- * identifier as one already exists. Use PATCH to modify the existing
- * entry. The response is provied with an HTTP status of
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_POST_INSTANCES_ALREADY_EXISTS = 2450,
-
- /**
- * The merchant backend cannot create an instance because the
- * specified bank accounts are somehow invalid. The response is
- * provied with an HTTP status of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_POST_INSTANCES_BAD_PAYTO_URIS = 2451,
-
- /**
- * The merchant backend cannot create an instance because it failed to
- * start the database transaction. The response is provied with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_POST_INSTANCES_DB_START_ERROR = 2452,
-
- /**
- * The merchant backend cannot create an instance because it failed to
- * commit the database transaction. The response is provied with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_POST_INSTANCES_DB_COMMIT_ERROR = 2453,
-
- /**
- * The merchant backend cannot delete an instance because it failed to
- * commit the database transaction. The response is provied with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DELETE_INSTANCES_ID_DB_HARD_FAILURE = 2454,
-
- /**
- * The merchant backend cannot delete the data because it already does
- * not exist. The response is provied with an HTTP status of
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_DELETE_INSTANCES_ID_NO_SUCH_INSTANCE = 2455,
-
- /**
- * The merchant backend cannot update an instance because the
- * specified bank accounts are somehow invalid. The response is
- * provied with an HTTP status of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PATCH_INSTANCES_BAD_PAYTO_URIS = 2456,
-
- /**
- * The merchant backend cannot patch an instance because it failed to
- * start the database transaction. The response is provied with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PATCH_INSTANCES_DB_START_ERROR = 2457,
-
- /**
- * The merchant backend cannot patch an instance because it failed to
- * commit the database transaction. The response is provied with an
- * HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PATCH_INSTANCES_DB_COMMIT_ERROR = 2458,
-
- /**
- * The hash provided in the request of /map/in does not match the
- * contract sent alongside in the same request.
- */
- TALER_EC_MAP_IN_UNMATCHED_HASH = 2500,
-
- /**
- * The backend encountered an error while trying to store the
- * h_contract_terms into the database. The response is provided with
- * HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_STORE_DB_ERROR = 2501,
-
- /**
- * The backend encountered an error while trying to retrieve the
- * proposal data from database. Likely to be an internal error. The
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_LOOKUP_DB_ERROR = 2502,
-
- /**
- * The proposal being looked up is not found on this merchant.
- * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND
- */
- TALER_EC_PROPOSAL_LOOKUP_NOT_FOUND = 2503,
-
- /**
- * The proposal had no timestamp and the backend failed to obtain the
- * local time. Likely to be an internal error. The response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_NO_LOCALTIME = 2504,
-
- /**
- * The order provided to the backend could not be parsed, some
- * required fields were missing or ill-formed. Returned with an HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PROPOSAL_ORDER_PARSE_ERROR = 2505,
-
- /**
- * The backend encountered an error while trying to find the existing
- * proposal in the database. The response is provided with HTTP status
- * code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_STORE_DB_ERROR_HARD = 2506,
-
- /**
- * The backend encountered an error while trying to find the existing
- * proposal in the database. The response is provided with HTTP status
- * code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_STORE_DB_ERROR_SOFT = 2507,
-
- /**
- * The backend encountered an error: the proposal already exists. The
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PROPOSAL_STORE_DB_ERROR_ALREADY_EXISTS = 2508,
-
- /**
- * The order provided to the backend uses an amount in a currency that
- * does not match the backend's configuration. Returned with HTTP
- * status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_PROPOSAL_ORDER_BAD_CURRENCY = 2509,
-
- /**
- * The response provided by the merchant backend was malformed. This
- * error is created client-side.
- */
- TALER_EC_PROPOSAL_REPLY_MALFORMED = 2510,
-
- /**
- * The order provided to the backend could not be deleted, it is not
- * known. Returned with an HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_ORDERS_DELETE_NO_SUCH_ORDER = 2511,
-
- /**
- * The order provided to the backend could not be deleted, our offer
- * is still valid and awaiting payment. Returned with an HTTP status
- * code #MHD_HTTP_CONFLICT.
- */
- TALER_EC_ORDERS_DELETE_AWAITING_PAYMENT = 2512,
-
- /**
- * The order provided to the backend could not be deleted, due to a
- * database error. Returned with an HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_DELETE_DB_HARD_FAILURE = 2513,
-
- /**
- * The order provided to the backend could not be completed, due to a
- * database error trying to fetch product inventory data. Returned
- * with an HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_LOOKUP_PRODUCT_DB_HARD_FAILURE = 2514,
-
- /**
- * The order provided to the backend could not be completed, due to a
- * database serialization error (which should be impossible) trying to
- * fetch product inventory data. Returned with an HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_LOOKUP_PRODUCT_DB_SOFT_FAILURE = 2515,
-
- /**
- * The order provided to the backend could not be completed, because a
- * product to be completed via inventory data is not actually in our
- * inventory. Returned with an HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_ORDERS_LOOKUP_PRODUCT_NOT_FOUND = 2516,
-
- /**
- * We could not obtain a list of all orders because of a database
- * failure. Returned with an HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_GET_DB_LOOKUP_ERROR = 2517,
-
- /**
- * We could not claim the order because of a database failure.
- * Returned with an HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_CLAIM_HARD_DB_ERROR = 2518,
-
- /**
- * We could not claim the order because of a database serialization
- * failure. Returned with an HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_ORDERS_CLAIM_SOFT_DB_ERROR = 2519,
-
- /**
- * We could not claim the order because the backend is unaware of it.
- * Returned with an HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_ORDERS_CLAIM_NOT_FOUND = 2520,
-
- /**
- * We could not claim the order because someone else claimed it first.
- * Returned with an HTTP status code #MHD_HTTP_CONFLICT.
- */
- TALER_EC_ORDERS_ALREADY_CLAIMED = 2521,
-
- /**
- * The merchant backend failed to lookup the products. The response is
- * provied with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_GET_PRODUCTS_DB_LOOKUP_ERROR = 2550,
-
- /**
- * The merchant backend failed to start the transaction. The response
- * is provied with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PRODUCTS_POST_DB_START_ERROR = 2551,
-
- /**
- * The product ID exists. The response is provied with an HTTP status
- * of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_POST_CONFLICT_PRODUCT_EXISTS = 2552,
-
- /**
- * The merchant backend failed to serialize the transaction. The
- * response is provied with an HTTP status of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PRODUCTS_POST_DB_COMMIT_SOFT_ERROR = 2553,
-
- /**
- * The merchant backend failed to commit the transaction. The response
- * is provied with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PRODUCTS_POST_DB_COMMIT_HARD_ERROR = 2554,
-
- /**
- * The merchant backend failed to commit the transaction. The response
- * is provied with an HTTP status of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PRODUCTS_PATCH_DB_COMMIT_HARD_ERROR = 2555,
-
- /**
- * The merchant backend did not find the product to be updated. The
- * response is provied with an HTTP status of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_PRODUCTS_PATCH_UNKNOWN_PRODUCT = 2556,
-
- /**
- * The update would have reduced the total amount of product lost,
- * which is not allowed. The response is provied with an HTTP status
- * of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_PATCH_TOTAL_LOST_REDUCED = 2557,
-
- /**
- * The update would have mean that more stocks were lost than what
- * remains from total inventory after sales, which is not allowed. The
- * response is provied with an HTTP status of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_PATCH_TOTAL_LOST_EXCEEDS_STOCKS = 2558,
-
- /**
- * The update would have reduced the total amount of product in stock,
- * which is not allowed. The response is provied with an HTTP status
- * of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_PATCH_TOTAL_STOCKED_REDUCED = 2559,
-
- /**
- * The lock request is for more products than we have left (unlocked)
- * in stock. The response is provied with an HTTP status of
- * #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_LOCK_INSUFFICIENT_STOCKS = 2560,
-
- /**
- * The lock request is for an unknown product. The response is provied
- * with an HTTP status of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_PRODUCTS_LOCK_UNKNOWN_PRODUCT = 2561,
-
- /**
- * The deletion request resulted in a hard database error. The
- * response is provied with an HTTP status of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_PRODUCTS_DELETE_DB_HARD_FAILURE = 2562,
-
- /**
- * The deletion request was for a product unknown to the backend. The
- * response is provied with an HTTP status of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_PRODUCTS_DELETE_NO_SUCH_PRODUCT = 2563,
-
- /**
- * The deletion request is for a product that is locked. The response
- * is provied with an HTTP status of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_PRODUCTS_DELETE_CONFLICTING_LOCK = 2564,
-
- /**
- * The merchant returned a malformed response. Error created client-
- * side.
- */
- TALER_EC_REFUND_LOOKUP_INVALID_RESPONSE = 2600,
-
- /**
- * The frontend gave an unknown order id to issue the refund to.
- */
- TALER_EC_REFUND_ORDER_ID_UNKNOWN = 2601,
-
- /**
- * The amount to be refunded is inconsistent: either is lower than the
- * previous amount being awarded, or it is too big to be paid back. In
- * this second case, the fault stays on the business dept. side.
- * Returned with an HTTP status of #MHD_HTTP_CONFLICT.
- */
- TALER_EC_REFUND_INCONSISTENT_AMOUNT = 2602,
-
- /**
- * The backend encountered an error while trying to retrieve the
- * payment data from database. Likely to be an internal error.
- */
- TALER_EC_REFUND_LOOKUP_DB_ERROR = 2603,
-
- /**
- * The backend encountered an error while trying to retrieve the
- * payment data from database. Likely to be an internal error.
- */
- TALER_EC_REFUND_MERCHANT_DB_COMMIT_ERROR = 2604,
-
- /**
- * Payments are stored in a single db transaction; this error
- * indicates that one db operation within that transaction failed.
- * This might involve storing of coins or other related db operations,
- * like starting/committing the db transaction or marking a contract
- * as paid.
- */
- TALER_EC_PAY_DB_STORE_PAYMENTS_ERROR = 2605,
-
- /**
- * The backend failed to sign the refund request.
- */
- TALER_EC_PAY_REFUND_SIGNATURE_FAILED = 2606,
-
- /**
- * The merchant backend is not available of any applicable refund(s)
- * for this order. Returned with an HTTP status of
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_REFUND_LOOKUP_NO_REFUND = 2607,
-
- /**
- * The backend knows the instance that was supposed to support the
- * tip, but it was not configured for tipping (i.e. has no exchange
- * associated with it). Likely to be a configuration error. Returned
- * with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_TIP_AUTHORIZE_INSTANCE_DOES_NOT_TIP = 2701,
-
- /**
- * The reserve that was used to fund the tips has expired. Returned
- * with an HTTP status code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_TIP_AUTHORIZE_RESERVE_EXPIRED = 2702,
-
- /**
- * The reserve that was used to fund the tips was not found in the DB.
- * Returned with an HTTP status code of #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_TIP_AUTHORIZE_RESERVE_UNKNOWN = 2703,
-
- /**
- * The backend knows the instance that was supposed to support the
- * tip, and it was configured for tipping. However, the funds
- * remaining are insufficient to cover the tip, and the merchant
- * should top up the reserve. Returned with an HTTP status code of
- * #MHD_HTTP_PRECONDITION FAILED.
- */
- TALER_EC_TIP_AUTHORIZE_INSUFFICIENT_FUNDS = 2704,
-
- /**
- * The backend had trouble accessing the database to persist
- * information about the tip authorization. Returned with an HTTP
- * status code of internal error.
- */
- TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR = 2705,
-
- /**
- * The backend had trouble accessing the database to persist
- * information about the tip authorization. The problem might be
- * fixable by repeating the transaction.
- */
- TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR = 2706,
-
- /**
- * The backend failed to obtain a reserve status from the exchange.
- * This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_STATUS_FAILED_EXCHANGE_DOWN = 2707,
-
- /**
- * The backend got an empty (!) reserve history from the exchange.
- * This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_FAILED_EMPTY = 2708,
-
- /**
- * The backend got an invalid reserve history (fails to start with a
- * deposit) from the exchange. This response is provided with HTTP
- * status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_INVALID_NO_DEPOSIT = 2709,
-
- /**
- * The backend got an 404 response from the exchange when it inquired
- * about the reserve history. The response is provided with HTTP
- * status code #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_TIP_QUERY_RESERVE_UNKNOWN_TO_EXCHANGE = 2710,
-
- /**
- * The backend got a reserve with a currency that does not match the
- * backend's currency. The response is provided with HTTP status code
- * #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_TIP_QUERY_RESERVE_CURRENCY_MISMATCH = 2711,
-
- /**
- * The backend got a reserve history with amounts it cannot process
- * (addition failure in deposits). The response is provided with HTTP
- * status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_DEPOSIT = 2712,
-
- /**
- * The backend got a reserve history with amounts it cannot process
- * (addition failure in withdraw amounts). The response is provided
- * with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_WITHDRAW = 2713,
-
- /**
- * The backend got a reserve history with amounts it cannot process
- * (addition failure in closing amounts). The response is provided
- * with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_CLOSED = 2714,
-
- /**
- * The backend got a reserve history with inconsistent amounts.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_INCONSISTENT = 2715,
-
- /**
- * The backend encountered a database error querying tipping reserves.
- */
- TALER_EC_TIP_QUERY_DB_ERROR = 2716,
-
- /**
- * The backend got an unexpected resever history reply from the
- * exchange. This response is provided with HTTP status code
- * #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_FAILED = 2717,
-
- /**
- * The backend got a reserve history with amounts it cannot process
- * (addition failure in withdraw amounts). The response is provided
- * with HTTP status code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_QUERY_RESERVE_HISTORY_ARITHMETIC_ISSUE_RECOUP = 2718,
-
- /**
- * The backend knows the instance that was supposed to support the
- * tip, but it was not configured for tipping (i.e. has no exchange
- * associated with it). Likely to be a configuration error. Returned
- * with an HTTP status code of #MHD_HTTP_PRECONDITION_FAILED.
- */
- TALER_EC_TIP_QUERY_INSTANCE_DOES_NOT_TIP = 2719,
-
- /**
- * The tip id is unknown. This could happen if the tip id is wrong or
- * the tip authorization expired.
- */
- TALER_EC_TIP_QUERY_TIP_ID_UNKNOWN = 2720,
-
- /**
- * The backend had trouble accessing the database to persist
- * information about enabling tips. Returned with an HTTP status code
- * of internal error.
- */
- TALER_EC_TIP_ENABLE_DB_TRANSACTION_ERROR = 2750,
-
- /**
- * The tip ID is unknown. This could happen if the tip has expired.
- * Returned with an HTTP status code of #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN = 2800,
-
- /**
- * The amount requested exceeds the remaining tipping balance for this
- * tip ID. Returned with an HTTP status code of "Conflict" (as it
- * conflicts with a previous pickup operation).
- */
- TALER_EC_TIP_PICKUP_NO_FUNDS = 2801,
-
- /**
- * We encountered a DB error, repeating the request may work.
- */
- TALER_EC_TIP_PICKUP_DB_ERROR_SOFT = 2802,
-
- /**
- * We encountered a DB error, repeating the request will not help.
- * This is an internal server error.
- */
- TALER_EC_TIP_PICKUP_DB_ERROR_HARD = 2803,
-
- /**
- * The same pickup ID was already used for picking up a different
- * amount. This points to a very strange internal error as the pickup
- * ID is derived from the denomination key which is tied to a
- * particular amount. Hence this should also be an internal server
- * error.
- */
- TALER_EC_TIP_PICKUP_AMOUNT_CHANGED = 2804,
-
- /**
- * We failed to contact the exchange to obtain the denomination keys.
- * Returned with a response code #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_PICKUP_EXCHANGE_DOWN = 2805,
-
- /**
- * We contacted the exchange to obtain any denomination keys, but got
- * no valid keys. Returned with a response code
- * #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_PICKUP_EXCHANGE_LACKED_KEYS = 2806,
-
- /**
- * We contacted the exchange to obtain at least one of the
- * denomination keys specified in the request. Returned with a
- * response code "not found" (404).
- */
- TALER_EC_TIP_PICKUP_EXCHANGE_LACKED_KEY = 2807,
-
- /**
- * We encountered an arithmetic issue totaling up the amount to
- * withdraw. Returned with a response code of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_TIP_PICKUP_EXCHANGE_AMOUNT_OVERFLOW = 2808,
-
- /**
- * The number of planchets specified exceeded the limit. Returned with
- * a response code of #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_TIP_PICKUP_EXCHANGE_TOO_MANY_PLANCHETS = 2809,
-
- /**
- * The merchant failed to initialize the withdraw operaiton. Returned
- * with a response code of #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TIP_PICKUP_WITHDRAW_FAILED = 2810,
-
- /**
- * The merchant failed to initialize the withdraw operaiton. Returned
- * with a response code of #MHD_HTTP_FAILED_DEPENDENCY.
- */
- TALER_EC_TIP_PICKUP_WITHDRAW_FAILED_AT_EXCHANGE = 2811,
-
- /**
- * The client failed to unblind the signature returned by the
- * merchant. Generated client-side.
- */
- TALER_EC_TIP_PICKUP_UNBLIND_FAILURE = 2812,
-
- /**
- * We failed to contract terms from our merchant database. The
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_CHECK_PAYMENT_DB_FETCH_CONTRACT_TERMS_ERROR = 2911,
-
- /**
- * We failed to contract terms from our merchant database. The
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_CHECK_PAYMENT_DB_FETCH_ORDER_ERROR = 2912,
-
- /**
- * The order id we're checking is unknown, likely the frontend did not
- * create the order first.
- */
- TALER_EC_CHECK_PAYMENT_ORDER_ID_UNKNOWN = 2913,
-
- /**
- * Failed computing a hash code (likely server out-of-memory). This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_CHECK_PAYMENT_FAILED_COMPUTE_PROPOSAL_HASH = 2914,
-
- /**
- * Signature "session_sig" failed to verify. This response is provided
- * with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_CHECK_PAYMENT_SESSION_SIGNATURE_INVALID = 2915,
-
- /**
- * The response we received from the merchant is malformed. This error
- * is generated client-side.
- */
- TALER_EC_CHECK_PAYMENT_RESPONSE_MALFORMED = 2916,
-
- /**
- * The signature from the exchange on the deposit confirmation is
- * invalid. Returned with a "400 Bad Request" status code.
- */
- TALER_EC_DEPOSIT_CONFIRMATION_SIGNATURE_INVALID = 3000,
-
- /**
- * The auditor had trouble storing the deposit confirmation in its
- * database. Returned with an HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_DEPOSIT_CONFIRMATION_STORE_DB_ERROR = 3001,
-
- /**
- * The auditor had trouble retrieving the exchange list from its
- * database. Returned with an HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_LIST_EXCHANGES_DB_ERROR = 3002,
-
- /**
- * The auditor had trouble storing an exchange in its database.
- * Returned with an HTTP status code of
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_AUDITOR_EXCHANGE_STORE_DB_ERROR = 3003,
-
- /**
- * The auditor (!) responded with a reply that did not satsify the
- * protocol. This error is not used in the protocol but created
- * client-side.
- */
- TALER_EC_AUDITOR_EXCHANGES_REPLY_MALFORMED = 3004,
-
- /**
- * The exchange failed to compute ECDH. This response is provided
- * with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TEST_ECDH_ERROR = 4000,
-
- /**
- * The EdDSA test signature is invalid. This response is provided
- * with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_TEST_EDDSA_INVALID = 4001,
-
- /**
- * The exchange failed to compute the EdDSA test signature. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TEST_EDDSA_ERROR = 4002,
-
- /**
- * The exchange failed to generate an RSA key. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TEST_RSA_GEN_ERROR = 4003,
-
- /**
- * The exchange failed to compute the public RSA key. This response
- * is provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TEST_RSA_PUB_ERROR = 4004,
-
- /**
- * The exchange failed to compute the RSA signature. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_TEST_RSA_SIGN_ERROR = 4005,
-
- /**
- * The JSON in the server's response was malformed. This response is
- * provided with HTTP status code of 0.
- */
- TALER_EC_SERVER_JSON_INVALID = 5000,
-
- /**
- * A signature in the server's response was malformed. This response
- * is provided with HTTP status code of 0.
- */
- TALER_EC_SERVER_SIGNATURE_INVALID = 5001,
-
- /**
- * Wire transfer attempted with credit and debit party being the same
- * bank account.
- */
- TALER_EC_BANK_SAME_ACCOUNT = 5102,
-
- /**
- * Wire transfer impossible, due to financial limitation of the party
- * that attempted the payment.
- */
- TALER_EC_BANK_UNALLOWED_DEBIT = 5103,
-
- /**
- * Arithmetic operation between two amounts of different currency was
- * attempted.
- */
- TALER_EC_BANK_CURRENCY_MISMATCH = 5104,
-
- /**
- * At least one GET parameter was either missing or invalid for the
- * requested operation.
- */
- TALER_EC_BANK_PARAMETER_MISSING_OR_INVALID = 5105,
-
- /**
- * JSON body sent was invalid for the requested operation.
- */
- TALER_EC_BANK_JSON_INVALID = 5106,
-
- /**
- * Negative number was used (as value and/or fraction) to initiate a
- * Amount object.
- */
- TALER_EC_BANK_NEGATIVE_NUMBER_AMOUNT = 5107,
-
- /**
- * A number too big was used (as value and/or fraction) to initiate a
- * amount object.
- */
- TALER_EC_BANK_NUMBER_TOO_BIG = 5108,
-
- /**
- * Could not login for the requested operation.
- */
- TALER_EC_BANK_LOGIN_FAILED = 5109,
-
- /**
- * The bank account referenced in the requested operation was not
- * found. Returned along "400 Not found".
- */
- TALER_EC_BANK_UNKNOWN_ACCOUNT = 5110,
-
- /**
- * The transaction referenced in the requested operation (typically a
- * reject operation), was not found.
- */
- TALER_EC_BANK_TRANSACTION_NOT_FOUND = 5111,
-
- /**
- * Bank received a malformed amount string.
- */
- TALER_EC_BANK_BAD_FORMAT_AMOUNT = 5112,
-
- /**
- * The client does not own the account credited by the transaction
- * which is to be rejected, so it has no rights do reject it. To be
- * returned along HTTP 403 Forbidden.
- */
- TALER_EC_BANK_REJECT_NO_RIGHTS = 5200,
-
- /**
- * This error code is returned when no known exception types captured
- * the exception, and comes along with a 500 Internal Server Error.
- */
- TALER_EC_BANK_UNMANAGED_EXCEPTION = 5300,
-
- /**
- * This error code is used for all those exceptions that do not really
- * need a specific error code to return to the client, but need to
- * signal the middleware that the bank is not responding with 500
- * Internal Server Error. Used for example when a client is trying to
- * register with a unavailable username.
- */
- TALER_EC_BANK_SOFT_EXCEPTION = 5400,
-
- /**
- * The request UID for a request to transfer funds has already been
- * used, but with different details for the transfer.
- */
- TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED = 5500,
-
- /**
- * The sync service failed to access its database. This response is
- * provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_DB_FETCH_ERROR = 6000,
-
- /**
- * The sync service failed find the record in its database. This
- * response is provided with HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_SYNC_BACKUP_UNKNOWN = 6001,
-
- /**
- * The sync service failed find the account in its database. This
- * response is provided with HTTP status code #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_SYNC_ACCOUNT_UNKNOWN = 6002,
-
- /**
- * The SHA-512 hash provided in the If-None-Match header is malformed.
- * This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_SYNC_BAD_IF_NONE_MATCH = 6003,
-
- /**
- * The SHA-512 hash provided in the If-Match header is malformed or
- * missing. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_SYNC_BAD_IF_MATCH = 6004,
-
- /**
- * The signature provided in the "Sync-Signature" header is malformed
- * or missing. This response is provided with HTTP status code
- * #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_SYNC_BAD_SYNC_SIGNATURE = 6005,
-
- /**
- * The signature provided in the "Sync-Signature" header does not
- * match the account, old or new Etags. This response is provided with
- * HTTP status code #MHD_HTTP_FORBIDDEN.
- */
- TALER_EC_SYNC_INVALID_SIGNATURE = 6007,
-
- /**
- * The "Content-length" field for the upload is either not a number,
- * or too big, or missing. This response is provided with HTTP status
- * code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_SYNC_BAD_CONTENT_LENGTH = 6008,
-
- /**
- * The "Content-length" field for the upload is too big based on the
- * server's terms of service. This response is provided with HTTP
- * status code #MHD_HTTP_PAYLOAD_TOO_LARGE.
- */
- TALER_EC_SYNC_EXCESSIVE_CONTENT_LENGTH = 6009,
-
- /**
- * The server is out of memory to handle the upload. Trying again
- * later may succeed. This response is provided with HTTP status code
- * #MHD_HTTP_PAYLOAD_TOO_LARGE.
- */
- TALER_EC_SYNC_OUT_OF_MEMORY_ON_CONTENT_LENGTH = 6010,
-
- /**
- * The uploaded data does not match the Etag. This response is
- * provided with HTTP status code #MHD_HTTP_BAD_REQUEST.
- */
- TALER_EC_SYNC_INVALID_UPLOAD = 6011,
-
- /**
- * We failed to check for existing upload data in the database. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_DATABASE_FETCH_ERROR = 6012,
-
- /**
- * HTTP server was being shutdown while this operation was pending.
- * This response is provided with HTTP status code
- * #MHD_HTTP_SERVICE_UNAVAILABLE.
- */
- TALER_EC_SYNC_SHUTDOWN = 6013,
-
- /**
- * HTTP server experienced a timeout while awaiting promised payment.
- * This response is provided with HTTP status code
- * #MHD_HTTP_REQUEST_TIMEOUT.
- */
- TALER_EC_SYNC_PAYMENT_TIMEOUT = 6014,
-
- /**
- * Sync could not store order data in its own database. This response
- * is provided with HTTP status code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_PAYMENT_CREATE_DB_ERROR = 6015,
-
- /**
- * Sync could not store payment confirmation in its own database. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_PAYMENT_CONFIRM_DB_ERROR = 6016,
-
- /**
- * Sync could not fetch information about possible existing orders
- * from its own database. This response is provided with HTTP status
- * code #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_PAYMENT_CHECK_ORDER_DB_ERROR = 6017,
-
- /**
- * Sync could not setup the payment request with its own backend. This
- * response is provided with HTTP status code
- * #MHD_HTTP_INTERNAL_SERVER_ERROR.
- */
- TALER_EC_SYNC_PAYMENT_CREATE_BACKEND_ERROR = 6018,
-
- /**
- * The sync service failed find the backup to be updated in its
- * database. This response is provided with HTTP status code
- * #MHD_HTTP_NOT_FOUND.
- */
- TALER_EC_SYNC_PREVIOUS_BACKUP_UNKNOWN = 6019,
-
- /**
- * End of error code range.
- */
- TALER_EC_END = 9999,
-
-};
-
-
-#endif
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index f7fa71443..0597799b5 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -1,23 +1,26 @@
/*
- This file is part of TALER
- Copyright (C) 2014-2020 Taler Systems SA
+ This file is part of TALER
+ Copyright (C) 2014-2024 Taler Systems SA
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU Affero General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
/**
* @file include/taler_exchange_service.h
* @brief C interface of libtalerexchange, a C library to use exchange's HTTP API
+ * This library is not thread-safe, all APIs must only be used from a single thread.
+ * This library calls abort() if it runs out of memory. Be aware of these limitations.
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#ifndef _TALER_EXCHANGE_SERVICE_H
#define _TALER_EXCHANGE_SERVICE_H
@@ -25,31 +28,17 @@
#include <jansson.h>
#include "taler_util.h"
#include "taler_error_codes.h"
+#include "taler_kyclogic_lib.h"
#include <gnunet/gnunet_curl_lib.h>
-/* ********************* /keys *********************** */
-
/**
- * List of possible options to be passed to
- * #TALER_EXCHANGE_connect().
+ * Version of the Taler Exchange API, in hex.
+ * Thus 0.8.4-1 = 0x00080401.
*/
-enum TALER_EXCHANGE_Option
-{
- /**
- * Terminator (end of option list).
- */
- TALER_EXCHANGE_OPTION_END = 0,
-
- /**
- * Followed by a "const json_t *" that was previously returned for
- * this exchange URL by #TALER_EXCHANGE_serialize_data(). Used to
- * resume a connection to an exchange without having to re-download
- * /keys data (or at least only download the deltas).
- */
- TALER_EXCHANGE_OPTION_DATA
+#define TALER_EXCHANGE_API_VERSION 0x00100000
-};
+/* ********************* /keys *********************** */
/**
@@ -70,17 +59,17 @@ struct TALER_EXCHANGE_SigningPublicKey
/**
* Validity start time
*/
- struct GNUNET_TIME_Absolute valid_from;
+ struct GNUNET_TIME_Timestamp valid_from;
/**
* Validity expiration time (how long the exchange may use it).
*/
- struct GNUNET_TIME_Absolute valid_until;
+ struct GNUNET_TIME_Timestamp valid_until;
/**
* Validity expiration time for legal disputes.
*/
- struct GNUNET_TIME_Absolute valid_legal;
+ struct GNUNET_TIME_Timestamp valid_legal;
};
@@ -97,7 +86,7 @@ struct TALER_EXCHANGE_DenomPublicKey
/**
* The hash of the public key.
*/
- struct GNUNET_HashCode h_key;
+ struct TALER_DenominationHashP h_key;
/**
* Exchange's master signature over this denomination record.
@@ -107,18 +96,18 @@ struct TALER_EXCHANGE_DenomPublicKey
/**
* Timestamp indicating when the denomination key becomes valid
*/
- struct GNUNET_TIME_Absolute valid_from;
+ struct GNUNET_TIME_Timestamp valid_from;
/**
* Timestamp indicating when the denomination key can’t be used anymore to
* withdraw new coins.
*/
- struct GNUNET_TIME_Absolute withdraw_valid_until;
+ struct GNUNET_TIME_Timestamp withdraw_valid_until;
/**
* Timestamp indicating when coins of this denomination become invalid.
*/
- struct GNUNET_TIME_Absolute expire_deposit;
+ struct GNUNET_TIME_Timestamp expire_deposit;
/**
* When do signatures with this denomination key become invalid?
@@ -127,7 +116,7 @@ struct TALER_EXCHANGE_DenomPublicKey
* of the evidence. @e expire_legal is expected to be significantly
* larger than @e expire_deposit (by a year or more).
*/
- struct GNUNET_TIME_Absolute expire_legal;
+ struct GNUNET_TIME_Timestamp expire_legal;
/**
* The value of this denomination
@@ -135,30 +124,23 @@ struct TALER_EXCHANGE_DenomPublicKey
struct TALER_Amount value;
/**
- * The applicable fee for withdrawing a coin of this denomination
- */
- struct TALER_Amount fee_withdraw;
-
- /**
- * The applicable fee to spend a coin of this denomination
- */
- struct TALER_Amount fee_deposit;
-
- /**
- * The applicable fee to melt/refresh a coin of this denomination
+ * The applicable fees for this denomination
*/
- struct TALER_Amount fee_refresh;
+ struct TALER_DenomFeeSet fees;
/**
- * The applicable fee to refund a coin of this denomination
+ * Set to true if the private denomination key has been
+ * lost by the exchange and thus the key cannot be
+ * used for withdrawing at this time.
*/
- struct TALER_Amount fee_refund;
+ bool lost;
/**
- * Set to #GNUNET_YES if this denomination key has been
+ * Set to true if this denomination key has been
* revoked by the exchange.
*/
- int revoked;
+ bool revoked;
+
};
@@ -219,6 +201,227 @@ struct TALER_EXCHANGE_AuditorInformation
/**
+ * Global fees and options of an exchange for a given time period.
+ */
+struct TALER_EXCHANGE_GlobalFee
+{
+
+ /**
+ * Signature affirming all of the data.
+ */
+ struct TALER_MasterSignatureP master_sig;
+
+ /**
+ * Starting time of the validity period (inclusive).
+ */
+ struct GNUNET_TIME_Timestamp start_date;
+
+ /**
+ * End time of the validity period (exclusive).
+ */
+ struct GNUNET_TIME_Timestamp end_date;
+
+ /**
+ * Unmerged purses will be timed out after at most this time.
+ */
+ struct GNUNET_TIME_Relative purse_timeout;
+
+ /**
+ * Account history is limited to this timeframe.
+ */
+ struct GNUNET_TIME_Relative history_expiration;
+
+ /**
+ * Fees that apply globally, independent of denomination
+ * and wire method.
+ */
+ struct TALER_GlobalFeeSet fees;
+
+ /**
+ * Number of free purses per account.
+ */
+ uint32_t purse_account_limit;
+};
+
+
+/**
+ * List sorted by @a start_date with fees to be paid for aggregate wire transfers.
+ */
+struct TALER_EXCHANGE_WireAggregateFees
+{
+ /**
+ * This is a linked list.
+ */
+ struct TALER_EXCHANGE_WireAggregateFees *next;
+
+ /**
+ * Fee to be paid whenever the exchange wires funds to the merchant.
+ */
+ struct TALER_WireFeeSet fees;
+
+ /**
+ * Time when this fee goes into effect (inclusive)
+ */
+ struct GNUNET_TIME_Timestamp start_date;
+
+ /**
+ * Time when this fee stops being in effect (exclusive).
+ */
+ struct GNUNET_TIME_Timestamp end_date;
+
+ /**
+ * Signature affirming the above fee structure.
+ */
+ struct TALER_MasterSignatureP master_sig;
+};
+
+
+/**
+ * Information about wire fees by wire method.
+ */
+struct TALER_EXCHANGE_WireFeesByMethod
+{
+ /**
+ * Wire method with the given @e fees.
+ */
+ char *method;
+
+ /**
+ * Linked list of wire fees the exchange charges for
+ * accounts of the wire @e method.
+ */
+ struct TALER_EXCHANGE_WireAggregateFees *fees_head;
+
+};
+
+
+/**
+ * Type of an account restriction.
+ */
+enum TALER_EXCHANGE_AccountRestrictionType
+{
+ /**
+ * Invalid restriction.
+ */
+ TALER_EXCHANGE_AR_INVALID = 0,
+
+ /**
+ * Account must not be used for this operation.
+ */
+ TALER_EXCHANGE_AR_DENY = 1,
+
+ /**
+ * Other account must match given regular expression.
+ */
+ TALER_EXCHANGE_AR_REGEX = 2
+};
+
+/**
+ * Restrictions that apply to using a given exchange bank account.
+ */
+struct TALER_EXCHANGE_AccountRestriction
+{
+
+ /**
+ * Type of the account restriction.
+ */
+ enum TALER_EXCHANGE_AccountRestrictionType type;
+
+ /**
+ * Restriction details depending on @e type.
+ */
+ union
+ {
+ /**
+ * Details if type is #TALER_EXCHANGE_AR_REGEX.
+ */
+ struct
+ {
+ /**
+ * Regular expression that the payto://-URI of the partner account must
+ * follow. The regular expression should follow posix-egrep, but
+ * without support for character classes, GNU extensions,
+ * back-references or intervals. See
+ * https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
+ * for a description of the posix-egrep syntax. Applications may support
+ * regexes with additional features, but exchanges must not use such
+ * regexes.
+ */
+ char *posix_egrep;
+
+ /**
+ * Hint for a human to understand the restriction.
+ */
+ char *human_hint;
+
+ /**
+ * Internationalizations for the @e human_hint. Map from IETF BCP 47
+ * language tax to localized human hints.
+ */
+ json_t *human_hint_i18n;
+ } regex;
+ } details;
+
+};
+
+
+/**
+ * Information about a wire account of the exchange.
+ */
+struct TALER_EXCHANGE_WireAccount
+{
+ /**
+ * payto://-URI of the exchange.
+ */
+ char *payto_uri;
+
+ /**
+ * URL of a conversion service in case using this account is subject to
+ * currency conversion. NULL for no conversion needed.
+ */
+ char *conversion_url;
+
+ /**
+ * Array of restrictions that apply when crediting
+ * this account.
+ */
+ struct TALER_EXCHANGE_AccountRestriction *credit_restrictions;
+
+ /**
+ * Array of restrictions that apply when debiting
+ * this account.
+ */
+ struct TALER_EXCHANGE_AccountRestriction *debit_restrictions;
+
+ /**
+ * Length of the @e credit_restrictions array.
+ */
+ unsigned int credit_restrictions_length;
+
+ /**
+ * Length of the @e debit_restrictions array.
+ */
+ unsigned int debit_restrictions_length;
+
+ /**
+ * Signature of the exchange over the account (was checked by the API).
+ */
+ struct TALER_MasterSignatureP master_sig;
+
+ /**
+ * Display label for the account, can be NULL.
+ */
+ char *bank_label;
+
+ /**
+ * Priority for ordering the account in the display.
+ */
+ int64_t priority;
+
+};
+
+
+/**
* @brief Information about keys from the exchange.
*/
struct TALER_EXCHANGE_Keys
@@ -230,6 +433,11 @@ struct TALER_EXCHANGE_Keys
struct TALER_MasterPublicKeyP master_pub;
/**
+ * Signature over extension configuration data, if any.
+ */
+ struct TALER_MasterSignatureP extensions_sig;
+
+ /**
* Array of the exchange's online signing keys.
*/
struct TALER_EXCHANGE_SigningPublicKey *sign_keys;
@@ -245,6 +453,16 @@ struct TALER_EXCHANGE_Keys
struct TALER_EXCHANGE_AuditorInformation *auditors;
/**
+ * Array with the global fees of the exchange.
+ */
+ struct TALER_EXCHANGE_GlobalFee *global_fees;
+
+ /**
+ * Configuration data for extensions.
+ */
+ json_t *extensions;
+
+ /**
* Supported Taler protocol version by the exchange.
* String in the format current:revision:age using the
* semantics of GNU libtool. See
@@ -253,6 +471,46 @@ struct TALER_EXCHANGE_Keys
char *version;
/**
+ * Supported currency of the exchange.
+ */
+ char *currency;
+
+ /**
+ * What is the base URL of the exchange that returned
+ * these keys?
+ */
+ char *exchange_url;
+
+ /**
+ * Asset type used by the exchange. Typical values
+ * are "fiat" or "crypto" or "regional" or "stock".
+ * Wallets should adjust their UI/UX based on this
+ * value.
+ */
+ char *asset_type;
+
+ /**
+ * Array of amounts a wallet is allowed to hold from
+ * this exchange before it must undergo further KYC checks.
+ */
+ struct TALER_Amount *wallet_balance_limit_without_kyc;
+
+ /**
+ * Array of accounts of the exchange.
+ */
+ struct TALER_EXCHANGE_WireAccount *accounts;
+
+ /**
+ * Array of wire fees by wire method.
+ */
+ struct TALER_EXCHANGE_WireFeesByMethod *fees;
+
+ /**
+ * Currency rendering specification for this exchange.
+ */
+ struct TALER_CurrencySpecification cspec;
+
+ /**
* How long after a reserve went idle will the exchange close it?
* This is an approximate number, not cryptographically signed by
* the exchange (advisory-only, may change anytime).
@@ -262,14 +520,60 @@ struct TALER_EXCHANGE_Keys
/**
* Timestamp indicating the /keys generation.
*/
- struct GNUNET_TIME_Absolute list_issue_date;
+ struct GNUNET_TIME_Timestamp list_issue_date;
+
+ /**
+ * When does this keys data expire?
+ */
+ struct GNUNET_TIME_Timestamp key_data_expiration;
/**
* Timestamp indicating the creation time of the last
* denomination key in /keys.
* Used to fetch /keys incrementally.
*/
- struct GNUNET_TIME_Absolute last_denom_issue_date;
+ struct GNUNET_TIME_Timestamp last_denom_issue_date;
+
+ /**
+ * If age restriction is enabled on the exchange, we get an non-zero age_mask
+ */
+ struct TALER_AgeMask age_mask;
+
+ /**
+ * Absolute STEFAN parameter.
+ */
+ struct TALER_Amount stefan_abs;
+
+ /**
+ * Logarithmic STEFAN parameter.
+ */
+ struct TALER_Amount stefan_log;
+
+ /**
+ * Linear STEFAN parameter.
+ */
+ double stefan_lin;
+
+ /**
+ * Length of @e accounts array.
+ */
+ unsigned int accounts_len;
+
+ /**
+ * Length of @e fees array.
+ */
+ unsigned int fees_len;
+
+ /**
+ * Length of the @e wallet_balance_limit_without_kyc
+ * array.
+ */
+ unsigned int wblwk_length;
+
+ /**
+ * Length of the @e global_fees array.
+ */
+ unsigned int num_global_fees;
/**
* Length of the @e sign_keys array (number of valid entries).
@@ -296,6 +600,16 @@ struct TALER_EXCHANGE_Keys
*/
unsigned int denom_keys_size;
+ /**
+ * Reference counter for this structure.
+ * Freed when it reaches 0.
+ */
+ unsigned int rc;
+
+ /**
+ * Set to true if rewards are allowed at this exchange.
+ */
+ bool rewards_allowed;
};
@@ -392,141 +706,195 @@ struct TALER_EXCHANGE_HttpResponse
/**
+ * Response from /keys.
+ */
+struct TALER_EXCHANGE_KeysResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP status code.
+ */
+ union
+ {
+
+ /**
+ * Details on #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Information about the various keys used by the exchange.
+ */
+ const struct TALER_EXCHANGE_Keys *keys;
+
+ /**
+ * Protocol compatibility information
+ */
+ enum TALER_EXCHANGE_VersionCompatibility compat;
+ } ok;
+ } details;
+
+};
+
+
+/**
* Function called with information about who is auditing
- * a particular exchange and what key the exchange is using.
+ * a particular exchange and what keys the exchange is using.
+ * The ownership over the @a keys object is passed to
+ * the callee, thus it is given explicitly and not
+ * (only) via @a kr.
*
* @param cls closure
- * @param hr HTTP response data
- * @param keys information about the various keys used
- * by the exchange, NULL if /keys failed
- * @param compat protocol compatibility information
+ * @param kr response from /keys
+ * @param[in] keys keys object passed to callback with
+ * reference counter of 1. Must be freed by callee
+ * using #TALER_EXCHANGE_keys_decref(). NULL on failure.
*/
typedef void
-(*TALER_EXCHANGE_CertificationCallback) (
+(*TALER_EXCHANGE_GetKeysCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_EXCHANGE_Keys *keys,
- enum TALER_EXCHANGE_VersionCompatibility compat);
+ const struct TALER_EXCHANGE_KeysResponse *kr,
+ struct TALER_EXCHANGE_Keys *keys);
/**
- * @brief Handle to the exchange. This is where we interact with
- * a particular exchange and keep the per-exchange information.
+ * @brief Handle for a GET /keys request.
*/
-struct TALER_EXCHANGE_Handle;
+struct TALER_EXCHANGE_GetKeysHandle;
/**
- * Initialise a connection to the exchange. Will connect to the
- * exchange and obtain information about the exchange's master public
- * key and the exchange's auditor. The respective information will
- * be passed to the @a cert_cb once available, and all future
- * interactions with the exchange will be checked to be signed
- * (where appropriate) by the respective master key.
+ * Fetch the main /keys resources from an exchange. Does an incremental
+ * fetch if @a last_keys is given. The obtained information will be passed to
+ * the @a cert_cb (possibly after first merging it with @a last_keys to
+ * produce a full picture; expired keys (for deposit) will be removed from @a
+ * last_keys if there are any).
*
* @param ctx the context
* @param url HTTP base URL for the exchange
+ * @param[in,out] last_keys previous keys object, NULL for none
* @param cert_cb function to call with the exchange's certification information,
* possibly called repeatedly if the information changes
* @param cert_cb_cls closure for @a cert_cb
- * @param ... list of additional arguments, terminated by #TALER_EXCHANGE_OPTION_END.
* @return the exchange handle; NULL upon error
*/
-struct TALER_EXCHANGE_Handle *
-TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx,
- const char *url,
- TALER_EXCHANGE_CertificationCallback cert_cb,
- void *cert_cb_cls,
- ...);
+struct TALER_EXCHANGE_GetKeysHandle *
+TALER_EXCHANGE_get_keys (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *last_keys,
+ TALER_EXCHANGE_GetKeysCallback cert_cb,
+ void *cert_cb_cls);
/**
- * Serialize the latest key data from @a exchange to be persisted
- * on disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more
- * efficiently recover the state).
+ * Serialize the latest data from @a keys to be persisted
+ * (for example, to be used as @a last_keys later).
*
- * @param exchange which exchange's key and wire data should be serialized
- * @return NULL on error (i.e. no current data available); otherwise
- * json object owned by the caller
+ * @param kd the key data to serialize
+ * @return NULL on error; otherwise JSON object owned by the caller
*/
json_t *
-TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange);
+TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd);
/**
- * Disconnect from the exchange.
+ * Deserialize keys data stored in @a j.
*
- * @param exchange the exchange handle
+ * @param j JSON keys data previously returned from #TALER_EXCHANGE_keys_to_json()
+ * @return NULL on error (i.e. invalid JSON); otherwise
+ * keys object with reference counter 1 owned by the caller
*/
-void
-TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange);
+struct TALER_EXCHANGE_Keys *
+TALER_EXCHANGE_keys_from_json (const json_t *j);
/**
- * Obtain the keys from the exchange.
+ * Cancel GET /keys operation.
*
- * @param exchange the exchange handle
- * @return the exchange's key set
+ * @param[in] gkh the GET /keys handle
*/
-const struct TALER_EXCHANGE_Keys *
-TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange);
+void
+TALER_EXCHANGE_get_keys_cancel (struct TALER_EXCHANGE_GetKeysHandle *gkh);
/**
- * Set the fake now to be used when requesting "/keys".
+ * Increment reference counter for @a keys
*
- * @param exchange exchange handle.
- * @param now fake now to use. Note: this value will be
- * used _until_ its use will be unset via @a TALER_EXCHANGE_unset_now()
+ * @param[in,out] keys object to increment reference counter for
+ * @return keys, with incremented reference counter
*/
-void
-TALER_EXCHANGE_set_now (struct TALER_EXCHANGE_Handle *exchange,
- struct GNUNET_TIME_Absolute now);
+struct TALER_EXCHANGE_Keys *
+TALER_EXCHANGE_keys_incref (struct TALER_EXCHANGE_Keys *keys);
+
/**
- * Unset the fake now to be used when requesting "/keys".
+ * Decrement reference counter for @a keys.
+ * Frees @a keys if reference counter becomes zero.
*
- * @param exchange exchange handle.
+ * @param[in,out] keys object to decrement reference counter for
*/
void
-TALER_EXCHANGE_unset_now (struct TALER_EXCHANGE_Handle *exchange);
+TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys);
/**
- * Let the user set the last valid denomination time manually.
+ * Use STEFAN curve in @a keys to convert @a brut to @a net. Computes the
+ * expected minimum (!) @a net amount that should for sure arrive in the
+ * target amount at cost of @a brut to the wallet. Note that STEFAN curves by
+ * design over-estimate actual fees and a wallet may be able to achieve the
+ * same @a net amount with less fees --- or if the available coins are
+ * abnormal in structure, it may take more.
*
- * @param exchange the exchange handle.
- * @param last_denom_new new last denomination time.
+ * @param keys exchange key data
+ * @param brut gross amount (actual cost including fees)
+ * @param[out] net net amount (effective amount)
+ * @return #GNUNET_OK on success, #GNUNET_NO if the
+ * resulting @a net is zero (or lower)
*/
-void
-TALER_EXCHANGE_set_last_denom (struct TALER_EXCHANGE_Handle *exchange,
- struct GNUNET_TIME_Absolute last_denom_new);
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_keys_stefan_b2n (
+ const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_Amount *brut,
+ struct TALER_Amount *net);
/**
- * Check if our current response for /keys is valid, and if
- * not, trigger /keys download.
+ * Use STEFAN curve in @a keys to convert @a net to @a brut. Computes the
+ * expected maximum (!) @a brut amount that should be needed in the wallet to
+ * transfer @a net amount to the target account. Note that STEFAN curves by
+ * design over-estimate actual fees and a wallet may be able to achieve the
+ * same @a net amount with less fees --- or if the available coins are
+ * abnormal in structure, it may take more.
*
- * @param exchange exchange to check keys for
- * @param force_download #GNUNET_YES to force download even if /keys is still valid
- * @param pull_all_keys if #GNUNET_YES, then the exchange state is reset to #MHS_INIT,
- * and all denoms will be redownloaded.
- * @return until when the response is current, 0 if we are re-downloading
+ * @param keys exchange key data
+ * @param net net amount (effective amount)
+ * @param[out] brut gross amount (actual cost including fees)
+ * @return #GNUNET_OK on success, #GNUNET_NO if the
+ * resulting @a brut is zero (only if @a net was zero)
*/
-struct GNUNET_TIME_Absolute
-TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange,
- int force_download,
- int pull_all_keys);
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_keys_stefan_n2b (
+ const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_Amount *net,
+ struct TALER_Amount *brut);
/**
- * Obtain the keys from the exchange in the raw JSON format.
+ * Round brutto or netto value computed via STEFAN
+ * curve to decimal places commonly used at the exchange.
*
- * @param exchange the exchange handle
- * @return the exchange's keys in raw JSON
+ * @param keys exchange keys response data
+ * @param[in,out] val value to round
*/
-json_t *
-TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange);
+void
+TALER_EXCHANGE_keys_stefan_round (
+ const struct TALER_EXCHANGE_Keys *keys,
+ struct TALER_Amount *val);
/**
@@ -537,19 +905,10 @@ TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange);
* @param pub claimed current online signing key for the exchange
* @return #GNUNET_OK if @a pub is (according to /keys) a current signing key
*/
-int
-TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_ExchangePublicKeyP *pub);
-
-
-/**
- * Get exchange's base URL.
- *
- * @param exchange exchange handle.
- * @return the base URL from the handle.
- */
-const char *
-TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange);
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_test_signing_key (
+ const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ExchangePublicKeyP *pub);
/**
@@ -567,10 +926,24 @@ TALER_EXCHANGE_get_denomination_key (
/**
+ * Obtain the global fee details from the exchange.
+ *
+ * @param keys the exchange's key set
+ * @param ts time for when to fetch the fees
+ * @return details about the fees, NULL if no fees are known at @a ts
+ */
+const struct TALER_EXCHANGE_GlobalFee *
+TALER_EXCHANGE_get_global_fee (
+ const struct TALER_EXCHANGE_Keys *keys,
+ struct GNUNET_TIME_Timestamp ts);
+
+
+/**
* Create a copy of a denomination public key.
*
* @param key key to copy
- * @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key
+ * @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key()
+ * @deprecated
*/
struct TALER_EXCHANGE_DenomPublicKey *
TALER_EXCHANGE_copy_denomination_key (
@@ -579,9 +952,10 @@ TALER_EXCHANGE_copy_denomination_key (
/**
* Destroy a denomination public key.
- * Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key.
+ * Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key().
*
* @param key key to destroy.
+ * @deprecated
*/
void
TALER_EXCHANGE_destroy_denomination_key (
@@ -598,7 +972,7 @@ TALER_EXCHANGE_destroy_denomination_key (
const struct TALER_EXCHANGE_DenomPublicKey *
TALER_EXCHANGE_get_denomination_key_by_hash (
const struct TALER_EXCHANGE_Keys *keys,
- const struct GNUNET_HashCode *hc);
+ const struct TALER_DenominationHashP *hc);
/**
@@ -615,139 +989,209 @@ TALER_EXCHANGE_get_signing_key_info (
const struct TALER_ExchangePublicKeyP *exchange_pub);
-/* ********************* /wire *********************** */
+/* ********************* wire helpers *********************** */
/**
- * Sorted list of fees to be paid for aggregate wire transfers.
+ * Parse array of @a accounts of the exchange into @a was.
+ *
+ * @param master_pub master public key of the exchange, NULL to not verify signatures
+ * @param accounts array of accounts to parse
+ * @param[out] was where to write the result (already allocated)
+ * @param was_length length of the @a was array, must match the length of @a accounts
+ * @return #GNUNET_OK if parsing @a accounts succeeded
*/
-struct TALER_EXCHANGE_WireAggregateFees
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_parse_accounts (
+ const struct TALER_MasterPublicKeyP *master_pub,
+ const json_t *accounts,
+ unsigned int was_length,
+ struct TALER_EXCHANGE_WireAccount was[static was_length]);
+
+
+/**
+ * Free data within @a was, but not @a was itself.
+ *
+ * @param was array of wire account data
+ * @param was_len length of the @a was array
+ */
+void
+TALER_EXCHANGE_free_accounts (
+ unsigned int was_len,
+ struct TALER_EXCHANGE_WireAccount was[static was_len]);
+
+
+/* ********************* /coins/$COIN_PUB/deposit *********************** */
+
+
+/**
+ * Information needed for a coin to be deposited.
+ */
+struct TALER_EXCHANGE_CoinDepositDetail
{
+
/**
- * This is a linked list.
+ * The amount to be deposited.
*/
- struct TALER_EXCHANGE_WireAggregateFees *next;
+ struct TALER_Amount amount;
/**
- * Fee to be paid whenever the exchange wires funds to the merchant.
+ * Hash over the age commitment of the coin.
*/
- struct TALER_Amount wire_fee;
+ struct TALER_AgeCommitmentHash h_age_commitment;
/**
- * Fee to be paid when the exchange closes a reserve and wires funds
- * back to a customer.
+ * The coin’s public key.
*/
- struct TALER_Amount closing_fee;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
/**
- * Time when this fee goes into effect (inclusive)
+ * The signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT made
+ * by the customer with the coin’s private key.
*/
- struct GNUNET_TIME_Absolute start_date;
+ struct TALER_CoinSpendSignatureP coin_sig;
/**
- * Time when this fee stops being in effect (exclusive).
+ * Exchange’s unblinded signature of the coin.
*/
- struct GNUNET_TIME_Absolute end_date;
+ struct TALER_DenominationSignature denom_sig;
/**
- * Signature affirming the above fee structure.
+ * Hash of the public key of the coin.
*/
- struct TALER_MasterSignatureP master_sig;
+ struct TALER_DenominationHashP h_denom_pub;
};
/**
- * Information about a wire account of the exchange.
+ * Meta information about the contract relevant for a coin's deposit
+ * operation.
*/
-struct TALER_EXCHANGE_WireAccount
+struct TALER_EXCHANGE_DepositContractDetail
{
+
/**
- * payto://-URI of the exchange.
+ * Hash of the contact of the merchant with the customer (further details
+ * are never disclosed to the exchange)
*/
- const char *payto_uri;
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
- * Signature of the exchange over the account (was checked by the API).
+ * The public key of the merchant (used to identify the merchant for refund
+ * requests).
*/
- struct TALER_MasterSignatureP master_sig;
+ struct TALER_MerchantPublicKeyP merchant_pub;
/**
- * Linked list of wire fees the exchange charges for
- * accounts of the wire method matching @e payto_uri.
+ * Salt used to hash the @e merchant_payto_uri.
+ */
+ struct TALER_WireSaltP wire_salt;
+
+ /**
+ * Hash over data provided by the wallet to customize the contract.
+ * All zero if not used.
+ */
+ struct GNUNET_HashCode wallet_data_hash;
+
+ /**
+ * Date until which the merchant can issue a refund to the customer via the
+ * exchange (can be zero if refunds are not allowed); must not be after the
+ * @e wire_deadline.
+ */
+ struct GNUNET_TIME_Timestamp refund_deadline;
+
+ /**
+ * Execution date, until which the merchant would like the exchange to
+ * settle the balance (advisory, the exchange cannot be forced to settle in
+ * the past or upon very short notice, but of course a well-behaved exchange
+ * will limit aggregation based on the advice received).
+ */
+ struct GNUNET_TIME_Timestamp wire_deadline;
+
+ /**
+ * Timestamp when the contract was finalized, must match approximately the
+ * current time of the exchange.
+ */
+ struct GNUNET_TIME_Timestamp wallet_timestamp;
+
+ /**
+ * The merchant’s account details, in the payto://-format supported by the
+ * exchange.
*/
- const struct TALER_EXCHANGE_WireAggregateFees *fees;
+ const char *merchant_payto_uri;
+
+ /**
+ * Policy extension specific details about the deposit relevant to the exchange.
+ */
+ const json_t *policy_details;
};
/**
- * Callbacks of this type are used to serve the result of submitting a
- * wire format inquiry request to a exchange.
- *
- * If the request fails to generate a valid response from the
- * exchange, @a http_status will also be zero.
- *
- * @param cls closure
- * @param hr HTTP response data
- * @param accounts_len length of the @a accounts array
- * @param accounts list of wire accounts of the exchange, NULL on error
+ * @brief A Batch Deposit Handle
*/
-typedef void
-(*TALER_EXCHANGE_WireCallback) (
- void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- unsigned int accounts_len,
- const struct TALER_EXCHANGE_WireAccount *accounts);
+struct TALER_EXCHANGE_BatchDepositHandle;
/**
- * @brief A Wire format inquiry handle
+ * Structure with information about a batch deposit
+ * operation's result.
*/
-struct TALER_EXCHANGE_WireHandle;
+struct TALER_EXCHANGE_BatchDepositResult
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+ union
+ {
-/**
- * Obtain information about a exchange's wire instructions. A
- * exchange may provide wire instructions for creating a reserve. The
- * wire instructions also indicate which wire formats merchants may
- * use with the exchange. This API is typically used by a wallet for
- * wiring funds, and possibly by a merchant to determine supported
- * wire formats.
- *
- * Note that while we return the (main) response verbatim to the
- * caller for further processing, we do already verify that the
- * response is well-formed (i.e. that signatures included in the
- * response are all valid). If the exchange's reply is not
- * well-formed, we return an HTTP status code of zero to @a cb.
- *
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param wire_cb the callback to call when a reply for this request is available
- * @param wire_cb_cls closure for the above callback
- * @return a handle for this request
- */
-struct TALER_EXCHANGE_WireHandle *
-TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange,
- TALER_EXCHANGE_WireCallback wire_cb,
- void *wire_cb_cls);
+ /**
+ * Information returned if the HTTP status is
+ * #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Time when the exchange generated the batch deposit confirmation
+ */
+ struct GNUNET_TIME_Timestamp deposit_timestamp;
+ /**
+ * Deposit confirmation signature provided by the exchange
+ */
+ const struct TALER_ExchangeSignatureP *exchange_sig;
-/**
- * Cancel a wire information request. This function cannot be used
- * on a request handle if a response is already served for it.
- *
- * @param wh the wire information request handle
- */
-void
-TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh);
+ /**
+ * exchange key used to sign @a exchange_sig.
+ */
+ const struct TALER_ExchangePublicKeyP *exchange_pub;
+ /**
+ * Base URL for looking up wire transfers, or
+ * NULL to use the default base URL.
+ */
+ const char *transaction_base_url;
-/* ********************* /coins/$COIN_PUB/deposit *********************** */
+ } ok;
+ /**
+ * Information returned if the HTTP status is
+ * #MHD_HTTP_CONFLICT.
+ */
+ struct
+ {
+ /**
+ * The coin that had a conflict.
+ */
+ struct TALER_CoinSpendPublicKeyP coin_pub;
-/**
- * @brief A Deposit Handle
- */
-struct TALER_EXCHANGE_DepositHandle;
+ } conflict;
+
+ } details;
+};
/**
@@ -755,86 +1199,73 @@ struct TALER_EXCHANGE_DepositHandle;
* deposit permission request to a exchange.
*
* @param cls closure
- * @param hr HTTP response data
- * @param exchange_sig signature provided by the exchange
- * @param exchange_pub exchange key used to sign @a obj, or NULL
+ * @param dr deposit response details
*/
typedef void
-(*TALER_EXCHANGE_DepositResultCallback) (
+(*TALER_EXCHANGE_BatchDepositResultCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ExchangeSignatureP *exchange_sig,
- const struct TALER_ExchangePublicKeyP *exchange_pub);
+ const struct TALER_EXCHANGE_BatchDepositResult *dr);
/**
- * Submit a deposit permission to the exchange and get the exchange's
- * response. This API is typically used by a merchant. Note that
- * while we return the response verbatim to the caller for further
- * processing, we do already verify that the response is well-formed
- * (i.e. that signatures included in the response are all valid). If
- * the exchange's reply is not well-formed, we return an HTTP status code
- * of zero to @a cb.
+ * Submit a batch of deposit permissions to the exchange and get the
+ * exchange's response. This API is typically used by a merchant. Note that
+ * while we return the response verbatim to the caller for further processing,
+ * we do already verify that the response is well-formed (i.e. that signatures
+ * included in the response are all valid). If the exchange's reply is not
+ * well-formed, we return an HTTP status code of zero to @a cb.
*
- * We also verify that the @a coin_sig is valid for this deposit
- * request, and that the @a ub_sig is a valid signature for @a
+ * We also verify that the @a cdds.coin_sig are valid for this deposit
+ * request, and that the @a cdds.ub_sig are a valid signatures for @a
* coin_pub. Also, the @a exchange must be ready to operate (i.e. have
* finished processing the /keys reply). If either check fails, we do
* NOT initiate the transaction with the exchange and instead return NULL.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param amount the amount to be deposited
- * @param wire_deadline execution date, until which the merchant would like the exchange to settle the balance (advisory, the exchange cannot be
- * forced to settle in the past or upon very short notice, but of course a well-behaved exchange will limit aggregation based on the advice received)
- * @param wire_details the merchant’s account details, in a format supported by the exchange
- * @param h_contract_terms hash of the contact of the merchant with the customer (further details are never disclosed to the exchange)
- * @param coin_pub coin’s public key
- * @param denom_pub denomination key with which the coin is signed
- * @param denom_sig exchange’s unblinded signature of the coin
- * @param timestamp timestamp when the contract was finalized, must match approximately the current time of the exchange
- * @param merchant_pub the public key of the merchant (used to identify the merchant for refund requests)
- * @param refund_deadline date until which the merchant can issue a refund to the customer via the exchange (can be zero if refunds are not allowed); must not be after the @a wire_deadline
- * @param coin_sig the signature made with purpose #TALER_SIGNATURE_WALLET_COIN_DEPOSIT made by the customer with the coin’s private key.
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param dcd details about the contract the deposit is for
+ * @param num_cdds length of the @a cdds array
+ * @param cdds array with details about the coins to be deposited
* @param cb the callback to call when a reply for this request is available
* @param cb_cls closure for the above callback
+ * @param[out] ec if NULL is returned, set to the error code explaining why the operation failed
* @return a handle for this request; NULL if the inputs are invalid (i.e.
* signatures fail to verify). In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_DepositHandle *
-TALER_EXCHANGE_deposit (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_Amount *amount,
- struct GNUNET_TIME_Absolute wire_deadline,
- json_t *wire_details,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_DenominationSignature *denom_sig,
- const struct TALER_DenominationPublicKey *denom_pub,
- struct GNUNET_TIME_Absolute timestamp,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- struct GNUNET_TIME_Absolute refund_deadline,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- TALER_EXCHANGE_DepositResultCallback cb,
- void *cb_cls);
+struct TALER_EXCHANGE_BatchDepositHandle *
+TALER_EXCHANGE_batch_deposit (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_EXCHANGE_DepositContractDetail *dcd,
+ unsigned int num_cdds,
+ const struct TALER_EXCHANGE_CoinDepositDetail cdds[static num_cdds],
+ TALER_EXCHANGE_BatchDepositResultCallback cb,
+ void *cb_cls,
+ enum TALER_ErrorCode *ec);
/**
* Change the chance that our deposit confirmation will be given to the
* auditor to 100%.
*
- * @param deposit the deposit permission request handle
+ * @param[in,out] deposit the batch deposit permission request handle
*/
void
-TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit);
+TALER_EXCHANGE_batch_deposit_force_dc (
+ struct TALER_EXCHANGE_BatchDepositHandle *deposit);
/**
- * Cancel a deposit permission request. This function cannot be used
+ * Cancel a batch deposit permission request. This function cannot be used
* on a request handle if a response is already served for it.
*
- * @param deposit the deposit permission request handle
+ * @param[in] deposit the deposit permission request handle
*/
void
-TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit);
+TALER_EXCHANGE_batch_deposit_cancel (
+ struct TALER_EXCHANGE_BatchDepositHandle *deposit);
/* ********************* /coins/$COIN_PUB/refund *********************** */
@@ -844,23 +1275,51 @@ TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit);
*/
struct TALER_EXCHANGE_RefundHandle;
+/**
+ * Response from the /refund API.
+ */
+struct TALER_EXCHANGE_RefundResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status code.
+ */
+ union
+ {
+ /**
+ * Details on #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Exchange key used to sign.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * The actual signature
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+ } ok;
+ } details;
+};
+
/**
* Callbacks of this type are used to serve the result of submitting a
* refund request to an exchange.
*
* @param cls closure
- * @param hr HTTP response data
- * @param sign_key exchange key used to sign @a obj, or NULL
- * @param signature the actual signature, or NULL on error
+ * @param rr refund response
*/
typedef void
(*TALER_EXCHANGE_RefundCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ExchangePublicKeyP *sign_key,
- const struct TALER_ExchangeSignatureP *signature);
-
+ const struct TALER_EXCHANGE_RefundResponse *rr);
/**
* Submit a refund request to the exchange and get the exchange's response.
@@ -874,11 +1333,12 @@ typedef void
* finished processing the /keys reply). If this check fails, we do
* NOT initiate the transaction with the exchange and instead return NULL.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
* @param amount the amount to be refunded; must be larger than the refund fee
* (as that fee is still being subtracted), and smaller than the amount
* (with deposit fee) of the original deposit contribution of this coin
- * @param refund_fee fee applicable to this coin for the refund
* @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded
* @param coin_pub coin’s public key of the coin from the original deposit operation
* @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation);
@@ -892,61 +1352,17 @@ typedef void
* signatures fail to verify). In this case, the callback is not called.
*/
struct TALER_EXCHANGE_RefundHandle *
-TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_Amount *amount,
- const struct TALER_Amount *refund_fee,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t rtransaction_id,
- const struct TALER_MerchantPrivateKeyP *merchant_priv,
- TALER_EXCHANGE_RefundCallback cb,
- void *cb_cls);
-
-
-/**
- * Submit a refund request to the exchange and get the exchange's
- * response. This API is used by a merchant. Note that
- * while we return the response verbatim to the caller for further
- * processing, we do already verify that the response is well-formed
- * (i.e. that signatures included in the response are all valid). If
- * the exchange's reply is not well-formed, we return an HTTP status code
- * of zero to @a cb.
- *
- * The @a exchange must be ready to operate (i.e. have
- * finished processing the /keys reply). If this check fails, we do
- * NOT initiate the transaction with the exchange and instead return NULL.
- *
- * FIXME: We can probably DEPRECATE this API and only use #TALER_EXCHANGE_refund()!
- *
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param amount the amount to be refunded; must be larger than the refund fee
- * (as that fee is still being subtracted), and smaller than the amount
- * (with deposit fee) of the original deposit contribution of this coin
- * @param refund_fee fee applicable to this coin for the refund
- * @param h_contract_terms hash of the contact of the merchant with the customer that is being refunded
- * @param coin_pub coin’s public key of the coin from the original deposit operation
- * @param rtransaction_id transaction id for the transaction between merchant and customer (of refunding operation);
- * this is needed as we may first do a partial refund and later a full refund. If both
- * refunds are also over the same amount, we need the @a rtransaction_id to make the disjoint
- * refund requests different (as requests are idempotent and otherwise the 2nd refund might not work).
- * @param merchant_pub public key of the merchant
- * @param merchant_sig signature affirming the refund from the merchant
- * @param cb the callback to call when a reply for this request is available
- * @param cb_cls closure for the above callback
- * @return a handle for this request; NULL if the inputs are invalid (i.e.
- * signatures fail to verify). In this case, the callback is not called.
- */
-struct TALER_EXCHANGE_RefundHandle *
-TALER_EXCHANGE_refund2 (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_Amount *amount,
- const struct TALER_Amount *refund_fee,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- uint64_t rtransaction_id,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_MerchantSignatureP *merchant_sig,
- TALER_EXCHANGE_RefundCallback cb,
- void *cb_cls);
+TALER_EXCHANGE_refund (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_Amount *amount,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ uint64_t rtransaction_id,
+ const struct TALER_MerchantPrivateKeyP *merchant_priv,
+ TALER_EXCHANGE_RefundCallback cb,
+ void *cb_cls);
/**
@@ -961,16 +1377,549 @@ void
TALER_EXCHANGE_refund_cancel (struct TALER_EXCHANGE_RefundHandle *refund);
-/* ********************* GET /reserves/$RESERVE_PUB *********************** */
+/* ********************* POST /csr-melt *********************** */
/**
- * @brief A /reserves/ GET Handle
+ * @brief A /csr-melt Handle
*/
-struct TALER_EXCHANGE_ReservesGetHandle;
+struct TALER_EXCHANGE_CsRMeltHandle;
+
+
+/**
+ * Details about a response for a CS R request.
+ */
+struct TALER_EXCHANGE_CsRMeltResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response.
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Length of the @e alg_values array.
+ */
+ unsigned int alg_values_len;
+
+ /**
+ * Values contributed by the exchange for the
+ * respective coin's withdraw operation.
+ */
+ const struct TALER_ExchangeWithdrawValues *alg_values;
+ } ok;
+
+ /**
+ * Details if the status is #MHD_HTTP_GONE.
+ */
+ struct
+ {
+ /* FIXME: returning full details is not implemented */
+ } gone;
+
+ } details;
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * CS R request to a exchange.
+ *
+ * @param cls closure
+ * @param csrr response details
+ */
+typedef void
+(*TALER_EXCHANGE_CsRMeltCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_CsRMeltResponse *csrr);
+
+
+/**
+ * Information we pass per coin to a /csr-melt request.
+ */
+struct TALER_EXCHANGE_NonceKey
+{
+ /**
+ * Which denomination key is the /csr-melt request for?
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *pk;
+
+ /**
+ * What is number to derive the client nonce for the
+ * fresh coin?
+ */
+ uint32_t cnc_num;
+};
+
+
+/**
+ * Get a set of CS R values using a /csr-melt request.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param rms master key used for the derivation of the CS values
+ * @param nks_len length of the @a nks array
+ * @param nks array of denominations and nonces
+ * @param res_cb the callback to call when the final result for this request is available
+ * @param res_cb_cls closure for the above callback
+ * @return handle for the operation on success, NULL on error, i.e.
+ * if the inputs are invalid (i.e. denomination key not with this exchange).
+ * In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_CsRMeltHandle *
+TALER_EXCHANGE_csr_melt (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_RefreshMasterSecretP *rms,
+ unsigned int nks_len,
+ struct TALER_EXCHANGE_NonceKey nks[static nks_len],
+ TALER_EXCHANGE_CsRMeltCallback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ *
+ * Cancel a CS R melt request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param csrh the withdraw handle
+ */
+void
+TALER_EXCHANGE_csr_melt_cancel (struct TALER_EXCHANGE_CsRMeltHandle *csrh);
+
+
+/* ********************* POST /csr-withdraw *********************** */
+
+
+/**
+ * @brief A /csr-withdraw Handle
+ */
+struct TALER_EXCHANGE_CsRWithdrawHandle;
+
+
+/**
+ * Details about a response for a CS R request.
+ */
+struct TALER_EXCHANGE_CsRWithdrawResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response.
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Values contributed by the exchange for the
+ * respective coin's withdraw operation.
+ */
+ struct TALER_ExchangeWithdrawValues alg_values;
+
+ } ok;
+
+ /**
+ * Details if the status is #MHD_HTTP_GONE.
+ */
+ struct
+ {
+ /* TODO: returning full details is not implemented */
+ } gone;
+
+ } details;
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * CS R withdraw request to a exchange.
+ *
+ * @param cls closure
+ * @param csrr response details
+ */
+typedef void
+(*TALER_EXCHANGE_CsRWithdrawCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_CsRWithdrawResponse *csrr);
+
+
+/**
+ * Get a CS R using a /csr-withdraw request.
+ *
+ * @param curl_ctx The curl context to use for the requests
+ * @param exchange_url Base-URL to the excnange
+ * @param pk Which denomination key is the /csr request for
+ * @param nonce client nonce for the request
+ * @param res_cb the callback to call when the final result for this request is available
+ * @param res_cb_cls closure for the above callback
+ * @return handle for the operation on success, NULL on error, i.e.
+ * if the inputs are invalid (i.e. denomination key not with this exchange).
+ * In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_CsRWithdrawHandle *
+TALER_EXCHANGE_csr_withdraw (
+ struct GNUNET_CURL_Context *curl_ctx,
+ const char *exchange_url,
+ const struct TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct GNUNET_CRYPTO_CsSessionNonce *nonce,
+ TALER_EXCHANGE_CsRWithdrawCallback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ *
+ * Cancel a CS R withdraw request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param csrh the withdraw handle
+ */
+void
+TALER_EXCHANGE_csr_withdraw_cancel (
+ struct TALER_EXCHANGE_CsRWithdrawHandle *csrh);
+
+
+/* ********************* GET /coins/$COIN_PUB *********************** */
+
+/**
+ * Ways how a coin's balance may change.
+ */
+enum TALER_EXCHANGE_CoinTransactionType
+{
+
+ /**
+ * Reserved for uninitialized / none.
+ */
+ TALER_EXCHANGE_CTT_NONE,
+
+ /**
+ * Deposit into a contract.
+ */
+ TALER_EXCHANGE_CTT_DEPOSIT,
+
+ /**
+ * Spent on melt.
+ */
+ TALER_EXCHANGE_CTT_MELT,
+
+ /**
+ * Refunded by merchant.
+ */
+ TALER_EXCHANGE_CTT_REFUND,
+
+ /**
+ * Debited in recoup (to reserve) operation.
+ */
+ TALER_EXCHANGE_CTT_RECOUP,
+
+ /**
+ * Debited in recoup-and-refresh operation.
+ */
+ TALER_EXCHANGE_CTT_RECOUP_REFRESH,
+
+ /**
+ * Credited in recoup-refresh.
+ */
+ TALER_EXCHANGE_CTT_OLD_COIN_RECOUP,
+
+ /**
+ * Deposited into purse.
+ */
+ TALER_EXCHANGE_CTT_PURSE_DEPOSIT,
+
+ /**
+ * Refund from purse.
+ */
+ TALER_EXCHANGE_CTT_PURSE_REFUND,
+
+ /**
+ * Reserve open payment operation.
+ */
+ TALER_EXCHANGE_CTT_RESERVE_OPEN_DEPOSIT
+
+};
+
+
+/**
+ * @brief Entry in the coin's transaction history.
+ */
+struct TALER_EXCHANGE_CoinHistoryEntry
+{
+
+ /**
+ * Type of the transaction.
+ */
+ enum TALER_EXCHANGE_CoinTransactionType type;
+
+ /**
+ * Amount transferred (in or out).
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * Details depending on @e type.
+ */
+ union
+ {
+
+ struct
+ {
+ struct TALER_MerchantWireHashP h_wire;
+ struct TALER_PrivateContractHashP h_contract_terms;
+ struct TALER_ExtensionPolicyHashP h_policy;
+ bool no_h_policy;
+ struct GNUNET_HashCode wallet_data_hash;
+ bool no_wallet_data_hash;
+ struct GNUNET_TIME_Timestamp wallet_timestamp;
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct GNUNET_TIME_Timestamp refund_deadline;
+ struct TALER_CoinSpendSignatureP sig;
+ struct TALER_AgeCommitmentHash hac;
+ bool no_hac;
+ struct TALER_Amount deposit_fee;
+ } deposit;
+
+ struct
+ {
+ struct TALER_CoinSpendSignatureP sig;
+ struct TALER_RefreshCommitmentP rc;
+ struct TALER_AgeCommitmentHash h_age_commitment;
+ bool no_hac;
+ struct TALER_Amount melt_fee;
+ } melt;
+
+ struct
+ {
+ struct TALER_PrivateContractHashP h_contract_terms;
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct TALER_MerchantSignatureP sig;
+ struct TALER_Amount refund_fee;
+ struct TALER_Amount sig_amount;
+ uint64_t rtransaction_id;
+ } refund;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_TIME_Timestamp timestamp;
+ union GNUNET_CRYPTO_BlindingSecretP coin_bks;
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_ExchangeSignatureP exchange_sig;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ } recoup;
+
+ struct
+ {
+ struct TALER_CoinSpendPublicKeyP old_coin_pub;
+ union GNUNET_CRYPTO_BlindingSecretP coin_bks;
+ struct GNUNET_TIME_Timestamp timestamp;
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_ExchangeSignatureP exchange_sig;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ } recoup_refresh;
+
+ struct
+ {
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_ExchangeSignatureP exchange_sig;
+ struct TALER_CoinSpendPublicKeyP new_coin_pub;
+ struct GNUNET_TIME_Timestamp timestamp;
+ } old_coin_recoup;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ const char *exchange_base_url;
+ bool refunded;
+ struct TALER_AgeCommitmentHash phac;
+ } purse_deposit;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_Amount refund_fee;
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_ExchangeSignatureP exchange_sig;
+ } purse_refund;
+
+ struct
+ {
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ } reserve_open_deposit;
+
+ } details;
+
+};
/**
+ * @brief A /coins/$RID/history Handle
+ */
+struct TALER_EXCHANGE_CoinsHistoryHandle;
+
+
+/**
+ * Parses and verifies a coin's transaction history as
+ * returned by the exchange. Note that in case of
+ * incremental histories, the client must first combine
+ * the incremental histories into one complete history.
+ *
+ * @param keys /keys data of the exchange
+ * @param dk denomination key of the coin
+ * @param history JSON array with the coin's history
+ * @param coin_pub public key of the coin
+ * @param[out] total_in set to total amount credited to the coin in @a history
+ * @param[out] total_out set to total amount debited to the coin in @a history
+ * @param rlen length of the @a rhistory array
+ * @param[out] rhistory array where to write the parsed @a history
+ * @return #GNUNET_OK if @a history is valid,
+ * #GNUNET_SYSERR if not
+ */
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_parse_coin_history (
+ const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_EXCHANGE_DenomPublicKey *dk,
+ const json_t *history,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_Amount *total_in,
+ struct TALER_Amount *total_out,
+ unsigned int rlen,
+ struct TALER_EXCHANGE_CoinHistoryEntry rhistory[static rlen]);
+
+
+/**
+ * Verify that @a coin_sig does NOT appear in the @a history of a coin's
+ * transactions and thus whatever transaction is authorized by @a coin_sig is
+ * a conflict with @a proof.
+ *
+ * @param history coin history to check
+ * @param coin_sig signature that must not be in @a history
+ * @return #GNUNET_OK if @a coin_sig is not in @a history
+ */
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGE_check_coin_signature_conflict (
+ const json_t *history,
+ const struct TALER_CoinSpendSignatureP *coin_sig);
+
+
+/**
+ * Response to a GET /coins/$COIN_PUB/history request.
+ */
+struct TALER_EXCHANGE_CoinHistory
+{
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * Coin transaction history (possibly partial).
+ * Not yet validated, combine with other already
+ * known history data for this coin and then use
+ * #TALER_EXCHANGE_parse_coin_history() to validate
+ * the complete history and obtain it in binary
+ * format.
+ */
+ const json_t *history;
+
+ /**
+ * The hash of the coin denomination's public key
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
+ * Coin balance.
+ */
+ struct TALER_Amount balance;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Signature of functions called with the result of
+ * a coin transaction history request.
+ *
+ * @param cls closure
+ * @param ch transaction history for the coin
+ */
+typedef void
+(*TALER_EXCHANGE_CoinsHistoryCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_CoinHistory *ch);
+
+
+/**
+ * Parses and verifies a coin's transaction history as
+ * returned by the exchange. Note that a client may
+ * have to combine multiple partial coin histories
+ * into one coherent history before calling this function.
+ *
+ * @param ctx context for managing request
+ * @param url base URL of the exchange
+ * @param coin_priv private key of the coin
+ * @param start_off offset from which on to request history
+ * @param cb function to call with results
+ * @param cb_cls closure for @a cb
+ * @return #GNUNET_OK if @a history is valid,
+ * #GNUNET_SYSERR if not
+ */
+struct TALER_EXCHANGE_CoinsHistoryHandle *
+TALER_EXCHANGE_coins_history (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ uint64_t start_off,
+ TALER_EXCHANGE_CoinsHistoryCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_coins_history() operation.
+ *
+ * @param[in] rsh operation to cancel
+ */
+void
+TALER_EXCHANGE_coins_history_cancel (
+ struct TALER_EXCHANGE_CoinsHistoryHandle *rsh);
+
+
+/* ********************* GET /reserves/$RESERVE_PUB *********************** */
+
+/**
* Ways how a reserve's balance may change.
*/
enum TALER_EXCHANGE_ReserveTransactionType
@@ -987,6 +1936,11 @@ enum TALER_EXCHANGE_ReserveTransactionType
TALER_EXCHANGE_RTT_WITHDRAWAL,
/**
+ * Age-Withdrawal from the reserve.
+ */
+ TALER_EXCHANGE_RTT_AGEWITHDRAWAL,
+
+ /**
* /recoup operation.
*/
TALER_EXCHANGE_RTT_RECOUP,
@@ -994,6 +1948,21 @@ enum TALER_EXCHANGE_ReserveTransactionType
/**
* Reserve closed operation.
*/
+ TALER_EXCHANGE_RTT_CLOSING,
+
+ /**
+ * Reserve purse merge operation.
+ */
+ TALER_EXCHANGE_RTT_MERGE,
+
+ /**
+ * Reserve open request operation.
+ */
+ TALER_EXCHANGE_RTT_OPEN,
+
+ /**
+ * Reserve close request operation.
+ */
TALER_EXCHANGE_RTT_CLOSE
};
@@ -1002,7 +1971,7 @@ enum TALER_EXCHANGE_ReserveTransactionType
/**
* @brief Entry in the reserve's transaction history.
*/
-struct TALER_EXCHANGE_ReserveHistory
+struct TALER_EXCHANGE_ReserveHistoryEntry
{
/**
@@ -1035,17 +2004,12 @@ struct TALER_EXCHANGE_ReserveHistory
/**
* Information that uniquely identifies the wire transfer.
*/
- void *wire_reference;
+ uint64_t wire_reference;
/**
* When did the wire transfer happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
-
- /**
- * Number of bytes stored in @e wire_reference.
- */
- size_t wire_reference_size;
+ struct GNUNET_TIME_Timestamp timestamp;
} in_details;
@@ -1067,6 +2031,28 @@ struct TALER_EXCHANGE_ReserveHistory
} withdraw;
/**
+ * Information about withdraw operation.
+ * @e type is #TALER_EXCHANGE_RTT_AGEWITHDRAWAL.
+ */
+ struct
+ {
+ /**
+ * Signature authorizing the withdrawal for outgoing transaction.
+ */
+ json_t *out_authorization_sig;
+
+ /**
+ * Maximum age committed
+ */
+ uint8_t max_age;
+
+ /**
+ * Fee that was charged for the withdrawal.
+ */
+ struct TALER_Amount fee;
+ } age_withdraw;
+
+ /**
* Information provided if the reserve was filled via /recoup.
* @e type is #TALER_EXCHANGE_RTT_RECOUP.
*/
@@ -1092,7 +2078,7 @@ struct TALER_EXCHANGE_ReserveHistory
/**
* When did the /recoup operation happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
} recoup_details;
@@ -1103,7 +2089,7 @@ struct TALER_EXCHANGE_ReserveHistory
struct
{
/**
- * Receiver account information for the outgoing wire transfer.
+ * Receiver account information for the outgoing wire transfer as a payto://-URI.
*/
const char *receiver_account_details;
@@ -1126,7 +2112,7 @@ struct TALER_EXCHANGE_ReserveHistory
/**
* When did the wire transfer happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
/**
* Fee that was charged for the closing.
@@ -1135,6 +2121,173 @@ struct TALER_EXCHANGE_ReserveHistory
} close_details;
+ /**
+ * Information about a merge operation on the reserve.
+ * @e type is #TALER_EXCHANGE_RTT_MERGE.
+ */
+ struct
+ {
+
+ /**
+ * Fee paid for the purse.
+ */
+ struct TALER_Amount purse_fee;
+
+ /**
+ * Hash over the contract.
+ */
+ struct TALER_PrivateContractHashP h_contract_terms;
+
+ /**
+ * Merge capability key.
+ */
+ struct TALER_PurseMergePublicKeyP merge_pub;
+
+ /**
+ * Purse public key.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Signature by the reserve approving the merge.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * When was the merge made.
+ */
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+
+ /**
+ * When was the purse set to expire.
+ */
+ struct GNUNET_TIME_Timestamp purse_expiration;
+
+ /**
+ * Minimum age required for depositing into the purse.
+ */
+ uint32_t min_age;
+
+ /**
+ * Flags of the purse.
+ */
+ enum TALER_WalletAccountMergeFlags flags;
+
+ /**
+ * True if the purse was actually merged, false
+ * if only the @e purse_fee was charged.
+ */
+ bool merged;
+
+ } merge_details;
+
+ /**
+ * Information about an open request operation on the reserve.
+ * @e type is #TALER_EXCHANGE_RTT_OPEN.
+ */
+ struct
+ {
+
+ /**
+ * Signature by the reserve approving the open.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * Amount to be paid from the reserve balance to open
+ * the reserve.
+ */
+ struct TALER_Amount reserve_payment;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_Timestamp request_timestamp;
+
+ /**
+ * For how long should the reserve be kept open.
+ * (Determines amount to be paid.)
+ */
+ struct GNUNET_TIME_Timestamp reserve_expiration;
+
+ /**
+ * How many open purses should be included with the
+ * open reserve?
+ * (Determines amount to be paid.)
+ */
+ uint32_t purse_limit;
+
+ } open_request;
+
+ /**
+ * Information about an close request operation on the reserve.
+ * @e type is #TALER_EXCHANGE_RTT_CLOSE.
+ */
+ struct
+ {
+
+ /**
+ * Signature by the reserve approving the close.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * When was the request created.
+ */
+ struct GNUNET_TIME_Timestamp request_timestamp;
+
+ /**
+ * Hash of the payto://-URI of the target account
+ * for the closure, or all zeros for the reserve
+ * origin account.
+ */
+ struct TALER_PaytoHashP target_account_h_payto;
+
+ } close_request;
+
+
+ } details;
+
+};
+
+
+/**
+ * @brief A /reserves/ GET Handle
+ */
+struct TALER_EXCHANGE_ReservesGetHandle;
+
+
+/**
+ * @brief Reserve summary.
+ */
+struct TALER_EXCHANGE_ReserveSummary
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * Reserve balance.
+ */
+ struct TALER_Amount balance;
+
+ } ok;
+
} details;
};
@@ -1145,18 +2298,12 @@ struct TALER_EXCHANGE_ReserveHistory
* reserve status request to a exchange.
*
* @param cls closure
- * @param hr HTTP response data
- * @param balance current balance in the reserve, NULL on error
- * @param history_length number of entries in the transaction history, 0 on error
- * @param history detailed transaction history, NULL on error
+ * @param rs HTTP response data
*/
typedef void
(*TALER_EXCHANGE_ReservesGetCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_Amount *balance,
- unsigned int history_length,
- const struct TALER_EXCHANGE_ReserveHistory *history);
+ const struct TALER_EXCHANGE_ReserveSummary *rs);
/**
@@ -1168,8 +2315,11 @@ typedef void
* reply is not well-formed, we return an HTTP status code of zero to
* @a cb.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param ctx curl context
+ * @param url exchange base URL
* @param reserve_pub public key of the reserve to inspect
+ * @param timeout how long to wait for an affirmative reply
+ * (enables long polling if the reserve does not yet exist)
* @param cb the callback to call when a reply for this request is available
* @param cb_cls closure for the above callback
* @return a handle for this request; NULL if the inputs are invalid (i.e.
@@ -1177,8 +2327,10 @@ typedef void
*/
struct TALER_EXCHANGE_ReservesGetHandle *
TALER_EXCHANGE_reserves_get (
- struct TALER_EXCHANGE_Handle *exchange,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct GNUNET_TIME_Relative timeout,
TALER_EXCHANGE_ReservesGetCallback cb,
void *cb_cls);
@@ -1194,84 +2346,352 @@ TALER_EXCHANGE_reserves_get_cancel (
struct TALER_EXCHANGE_ReservesGetHandle *rgh);
-/* ********************* POST /reserves/$RESERVE_PUB/withdraw *********************** */
+/**
+ * @brief A /reserves/$RID/history Handle
+ */
+struct TALER_EXCHANGE_ReservesHistoryHandle;
+
+
+/**
+ * @brief Reserve history details.
+ */
+struct TALER_EXCHANGE_ReserveHistory
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_history.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_history is #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * Current reserve balance. May not be the difference between
+ * @e total_in and @e total_out because the @e may be truncated.
+ */
+ struct TALER_Amount balance;
+
+ /**
+ * Total of all inbound transactions in @e history.
+ */
+ struct TALER_Amount total_in;
+
+ /**
+ * Total of all outbound transactions in @e history.
+ */
+ struct TALER_Amount total_out;
+
+ /**
+ * Current etag / last entry in the history.
+ * Useful to filter requests by starting offset.
+ * Offsets are not necessarily contiguous.
+ */
+ uint64_t etag;
+
+ /**
+ * Reserve history.
+ */
+ const struct TALER_EXCHANGE_ReserveHistoryEntry *history;
+
+ /**
+ * Length of the @e history array.
+ */
+ unsigned int history_len;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve history request to a exchange.
+ *
+ * @param cls closure
+ * @param rs HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ReservesHistoryCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ReserveHistory *rs);
/**
- * @brief A /reserves/$RESERVE_PUB/withdraw Handle
+ * Submit a request to obtain the reserve history.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param reserve_priv private key of the reserve to inspect
+ * @param start_off offset of the oldest history entry to exclude from the response
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ * signatures fail to verify). In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_WithdrawHandle;
+struct TALER_EXCHANGE_ReservesHistoryHandle *
+TALER_EXCHANGE_reserves_history (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ uint64_t start_off,
+ TALER_EXCHANGE_ReservesHistoryCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel a reserve history request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param rsh the reserve request handle
+ */
+void
+TALER_EXCHANGE_reserves_history_cancel (
+ struct TALER_EXCHANGE_ReservesHistoryHandle *rsh);
+
+
+/**
+ * Information input into the withdraw process per coin.
+ */
+struct TALER_EXCHANGE_WithdrawCoinInput
+{
+ /**
+ * Denomination of the coin.
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *pk;
+
+ /**
+ * Master key material for the coin.
+ */
+ const struct TALER_PlanchetMasterSecretP *ps;
+
+ /**
+ * Age commitment for the coin.
+ */
+ const struct TALER_AgeCommitmentHash *ach;
+
+};
+
+
+/**
+ * All the details about a coin that are generated during withdrawal and that
+ * may be needed for future operations on the coin.
+ */
+struct TALER_EXCHANGE_PrivateCoinDetails
+{
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+ /**
+ * Value used to blind the key for the signature.
+ * Needed for recoup operations.
+ */
+ union GNUNET_CRYPTO_BlindingSecretP bks;
+
+ /**
+ * Signature over the coin.
+ */
+ struct TALER_DenominationSignature sig;
+
+ /**
+ * Values contributed from the exchange during the
+ * withdraw protocol.
+ */
+ struct TALER_ExchangeWithdrawValues exchange_vals;
+};
+
+
+/**
+ * @brief A /reserves/$RESERVE_PUB/batch-withdraw Handle
+ */
+struct TALER_EXCHANGE_BatchWithdrawHandle;
+
+
+/**
+ * Details about a response for a batch withdraw request.
+ */
+struct TALER_EXCHANGE_BatchWithdrawResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response.
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * Array of coins returned by the batch withdraw operation.
+ */
+ struct TALER_EXCHANGE_PrivateCoinDetails *coins;
+
+ /**
+ * Length of the @e coins array.
+ */
+ unsigned int num_coins;
+ } ok;
+
+ /**
+ * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+
+ /**
+ * Hash of the payto-URI of the account to KYC;
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * Legitimization requirement that the merchant should use
+ * to check for its KYC status, 0 if not known.
+ */
+ uint64_t requirement_row;
+ } unavailable_for_legal_reasons;
+
+ /**
+ * Details if the status is #MHD_HTTP_CONFLICT.
+ */
+ struct
+ {
+ /* TODO: returning full details is not implemented */
+ } conflict;
+
+ /**
+ * Details if the status is #MHD_HTTP_GONE.
+ */
+ struct
+ {
+ /* TODO: returning full details is not implemented */
+ } gone;
+
+ } details;
+};
/**
* Callbacks of this type are used to serve the result of submitting a
- * withdraw request to a exchange.
+ * batch withdraw request to a exchange.
*
* @param cls closure
- * @param hr HTTP response data
- * @param sig signature over the coin, NULL on error
+ * @param wr response details
*/
typedef void
-(*TALER_EXCHANGE_WithdrawCallback) (
+(*TALER_EXCHANGE_BatchWithdrawCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_DenominationSignature *sig);
+ const struct TALER_EXCHANGE_BatchWithdrawResponse *wr);
/**
- * Withdraw a coin from the exchange using a /reserves/$RESERVE_PUB/withdraw
- * request. This API is typically used by a wallet to withdraw from a
- * reserve.
+ * Withdraw multiple coins from the exchange using a /reserves/$RESERVE_PUB/batch-withdraw
+ * request. This API is typically used by a wallet to withdraw many coins from a
+ * reserve. The blind signatures are unblinded and verified before being returned
+ * to the caller at @a res_cb.
*
* Note that to ensure that no money is lost in case of hardware
* failures, the caller must have committed (most of) the arguments to
* disk before calling, and be ready to repeat the request with the
* same arguments in case of failures.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param pk kind of coin to create
+ * @param curl_ctx The curl context to use
+ * @param exchange_url The base-URL of the exchange
+ * @param keys The /keys material from the exchange
* @param reserve_priv private key of the reserve to withdraw from
- * @param ps secrets of the planchet
- * caller must have committed this value to disk before the call (with @a pk)
+ * @param wci_length number of entries in @a wcis
+ * @param wcis inputs that determine the planchets
* @param res_cb the callback to call when the final result for this request is available
* @param res_cb_cls closure for @a res_cb
* @return NULL
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_WithdrawHandle *
-TALER_EXCHANGE_withdraw (
- struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
+struct TALER_EXCHANGE_BatchWithdrawHandle *
+TALER_EXCHANGE_batch_withdraw (
+ struct GNUNET_CURL_Context *curl_ctx,
+ const char *exchange_url,
+ const struct TALER_EXCHANGE_Keys *keys,
const struct TALER_ReservePrivateKeyP *reserve_priv,
- const struct TALER_PlanchetSecretsP *ps,
- TALER_EXCHANGE_WithdrawCallback res_cb,
+ unsigned int wci_length,
+ const struct TALER_EXCHANGE_WithdrawCoinInput wcis[static wci_length],
+ TALER_EXCHANGE_BatchWithdrawCallback res_cb,
void *res_cb_cls);
/**
- * Cancel a withdraw status request. This function cannot be used
- * on a request handle if a response is already served for it.
+ * Cancel a batch withdraw status request. This function cannot be used on a
+ * request handle if a response is already served for it.
*
- * @param wh the withdraw handle
+ * @param wh the batch withdraw handle
*/
void
-TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh);
+TALER_EXCHANGE_batch_withdraw_cancel (
+ struct TALER_EXCHANGE_BatchWithdrawHandle *wh);
/**
+ * Response from a withdraw2 request.
+ */
+struct TALER_EXCHANGE_Withdraw2Response
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * blind signature over the coin
+ */
+ struct TALER_BlindedDenominationSignature blind_sig;
+ } ok;
+ } details;
+
+};
+
+/**
* Callbacks of this type are used to serve the result of submitting a
* withdraw request to a exchange without the (un)blinding factor.
*
* @param cls closure
- * @param hr HTTP response data
- * @param blind_sig blind signature over the coin, NULL on error
+ * @param w2r response data
*/
typedef void
(*TALER_EXCHANGE_Withdraw2Callback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct GNUNET_CRYPTO_RsaSignature *blind_sig);
+ const struct TALER_EXCHANGE_Withdraw2Response *w2r);
/**
@@ -1287,14 +2707,20 @@ struct TALER_EXCHANGE_Withdraw2Handle;
/**
* Withdraw a coin from the exchange using a /reserves/$RESERVE_PUB/withdraw
* request. This API is typically used by a merchant to withdraw a tip
- * where the blinding factor is unknown to the merchant.
+ * where the blinding factor is unknown to the merchant. Note that unlike
+ * the #TALER_EXCHANGE_batch_withdraw() API, this API neither unblinds the signatures
+ * nor can it verify that the exchange signatures are valid, so these tasks
+ * are left to the caller. Wallets probably should use #TALER_EXCHANGE_batch_withdraw()
+ * which integrates these steps.
*
* Note that to ensure that no money is lost in case of hardware
* failures, the caller must have committed (most of) the arguments to
* disk before calling, and be ready to repeat the request with the
* same arguments in case of failures.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param curl_ctx The curl-context to use
+ * @param exchange_url The base-URL of the exchange
+ * @param keys The /keys material from the exchange
* @param pd planchet details of the planchet to withdraw
* @param reserve_priv private key of the reserve to withdraw from
* @param res_cb the callback to call when the final result for this request is available
@@ -1304,11 +2730,14 @@ struct TALER_EXCHANGE_Withdraw2Handle;
* In this case, the callback is not called.
*/
struct TALER_EXCHANGE_Withdraw2Handle *
-TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_PlanchetDetail *pd,
- const struct TALER_ReservePrivateKeyP *reserve_priv,
- TALER_EXCHANGE_Withdraw2Callback res_cb,
- void *res_cb_cls);
+TALER_EXCHANGE_withdraw2 (
+ struct GNUNET_CURL_Context *curl_ctx,
+ const char *exchange_url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_PlanchetDetail *pd,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ TALER_EXCHANGE_Withdraw2Callback res_cb,
+ void *res_cb_cls);
/**
@@ -1321,56 +2750,592 @@ void
TALER_EXCHANGE_withdraw2_cancel (struct TALER_EXCHANGE_Withdraw2Handle *wh);
-/* ********************* /refresh/melt+reveal ***************************** */
+/**
+ * Response from a batch-withdraw request (2nd variant).
+ */
+struct TALER_EXCHANGE_BatchWithdraw2Response
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * array of blind signatures over the coins.
+ */
+ const struct TALER_BlindedDenominationSignature *blind_sigs;
+
+ /**
+ * length of @e blind_sigs
+ */
+ unsigned int blind_sigs_length;
+
+ } ok;
+
+ struct
+ {
+ /**
+ * Hash of the payto-URI of the account to KYC;
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * ID identifying the KYC requirement to withdraw.
+ */
+ uint64_t kyc_requirement_id;
+
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
/**
- * Melt (partially spent) coins to obtain fresh coins that are
- * unlinkable to the original coin(s). Note that melting more
- * than one coin in a single request will make those coins linkable,
- * so the safest operation only melts one coin at a time.
+ * Callbacks of this type are used to serve the result of submitting a batch
+ * withdraw request to a exchange without the (un)blinding factor.
+ *
+ * @param cls closure
+ * @param bw2r response data
+ */
+typedef void
+(*TALER_EXCHANGE_BatchWithdraw2Callback) (
+ void *cls,
+ const struct TALER_EXCHANGE_BatchWithdraw2Response *bw2r);
+
+
+/**
+ * @brief A /reserves/$RESERVE_PUB/batch-withdraw Handle, 2nd variant.
+ * This variant does not do the blinding/unblinding and only
+ * fetches the blind signatures on the already blinded planchets.
+ * Used internally by the `struct TALER_EXCHANGE_BatchWithdrawHandle`
+ * implementation as well as for the tipping logic of merchants.
+ */
+struct TALER_EXCHANGE_BatchWithdraw2Handle;
+
+
+/**
+ * Withdraw a coin from the exchange using a /reserves/$RESERVE_PUB/batch-withdraw
+ * request. This API is typically used by a merchant to withdraw a tip
+ * where the blinding factor is unknown to the merchant.
+ *
+ * Note that to ensure that no money is lost in case of hardware
+ * failures, the caller must have committed (most of) the arguments to
+ * disk before calling, and be ready to repeat the request with the
+ * same arguments in case of failures.
+ *
+ * @param curl_ctx The curl context to use
+ * @param exchange_url The base-URL of the exchange
+ * @param keys The /keys material from the exchange
+ * @param pds array of planchet details of the planchet to withdraw
+ * @param pds_length number of entries in the @a pds array
+ * @param reserve_priv private key of the reserve to withdraw from
+ * @param res_cb the callback to call when the final result for this request is available
+ * @param res_cb_cls closure for @a res_cb
+ * @return NULL
+ * if the inputs are invalid (i.e. denomination key not with this exchange).
+ * In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_BatchWithdraw2Handle *
+TALER_EXCHANGE_batch_withdraw2 (
+ struct GNUNET_CURL_Context *curl_ctx,
+ const char *exchange_url,
+ const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ unsigned int pds_length,
+ const struct TALER_PlanchetDetail pds[static pds_length],
+ TALER_EXCHANGE_BatchWithdraw2Callback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ * Cancel a batch withdraw request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param wh the withdraw handle
+ */
+void
+TALER_EXCHANGE_batch_withdraw2_cancel (
+ struct TALER_EXCHANGE_BatchWithdraw2Handle *wh);
+
+
+/* ********************* /reserve/$RESERVE_PUB/age-withdraw *************** */
+
+/**
+ * @brief Information needed to withdraw (and reveal) age restricted coins.
+ */
+struct TALER_EXCHANGE_AgeWithdrawCoinInput
+{
+ /**
+ * The master secret from which we derive all other relevant values for
+ * the coin: private key, nonces (if applicable) and age restriction
+ */
+ struct TALER_PlanchetMasterSecretP secrets[TALER_CNC_KAPPA];
+
+ /**
+ * The denomination of the coin. Must support age restriction, i.e
+ * its .keys.age_mask MUST not be 0
+ */
+ struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
+};
+
+
+/**
+ * All the details about a coin that are generated during age-withdrawal and
+ * that may be needed for future operations on the coin.
+ */
+struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails
+{
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+ /**
+ * Hash of the public key of the coin.
+ */
+ struct TALER_CoinPubHashP h_coin_pub;
+
+ /**
+ * Value used to blind the key for the signature.
+ * Needed for recoup operations.
+ */
+ union GNUNET_CRYPTO_BlindingSecretP blinding_key;
+
+ /**
+ * The age commitment, proof for the coin, derived from the
+ * Master secret and maximum age in the originating request
+ */
+ struct TALER_AgeCommitmentProof age_commitment_proof;
+
+ /**
+ * The hash of the age commitment
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Values contributed from the exchange during the
+ * withdraw protocol.
+ */
+ struct TALER_ExchangeWithdrawValues alg_values;
+
+ /**
+ * The planchet constructed
+ */
+ struct TALER_PlanchetDetail planchet;
+};
+
+/**
+ * @brief A handle to a /reserves/$RESERVE_PUB/age-withdraw request
+ */
+struct TALER_EXCHANGE_AgeWithdrawHandle;
+
+/**
+ * @brief Details about the response for a age withdraw request.
+ */
+struct TALER_EXCHANGE_AgeWithdrawResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Index that should not be revealed during the age-withdraw reveal
+ * phase.
+ */
+ uint8_t noreveal_index;
+
+ /**
+ * The commitment of the age-withdraw request, needed for the
+ * subsequent call to /age-withdraw/$ACH/reveal
+ */
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+
+ /**
+ * The number of elements in @e coins, each referring to
+ * TALER_CNC_KAPPA elements
+ */
+ size_t num_coins;
+
+ /**
+ * The computed details of the non-revealed @e num_coins coins to keep.
+ */
+ const struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails *coin_details;
+
+ /**
+ * The array of blinded hashes of the non-revealed
+ * @e num_coins coins, needed for the reveal step;
+ */
+ const struct TALER_BlindedCoinHashP *blinded_coin_hs;
+
+ /**
+ * Key used by the exchange to sign the response.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ } ok;
+ } details;
+};
+
+
+typedef void
+(*TALER_EXCHANGE_AgeWithdrawCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_AgeWithdrawResponse *awr);
+
+/**
+ * Submit an age-withdraw request to the exchange and get the exchange's
+ * response.
*
* This API is typically used by a wallet. Note that to ensure that
- * no money is lost in case of hardware failures, is operation does
- * not actually initiate the request. Instead, it generates a buffer
- * which the caller must store before proceeding with the actual call
- * to #TALER_EXCHANGE_melt() that will generate the request.
- *
- * This function does verify that the given request data is internally
- * consistent. However, the @a melts_sigs are NOT verified.
- *
- * Aside from some non-trivial cryptographic operations that might
- * take a bit of CPU time to complete, this function returns
- * its result immediately and does not start any asynchronous
- * processing. This function is also thread-safe.
- *
- * @param melt_priv private keys of the coin to melt
- * @param melt_amount amount specifying how much
- * the coin will contribute to the melt (including fee)
- * @param melt_sig signatures affirming the
- * validity of the public keys corresponding to the
- * @a melt_priv private key
- * @param melt_pk denomination key information
- * record corresponding to the @a melt_sig
- * validity of the keys
- * @param fresh_pks_len length of the @a pks array
- * @param fresh_pks array of @a pks_len denominations of fresh coins to create
- * @param[out] res_size set to the size of the return value, or 0 on error
+ * no money is lost in case of hardware failures, the provided
+ * argument @a rd should be committed to persistent storage
+ * prior to calling this function.
+ *
+ * @param curl_ctx The curl context
+ * @param exchange_url The base url of the exchange
+ * @param keys The denomination keys from the exchange
+ * @param reserve_priv The private key to the reserve
+ * @param num_coins The number of elements in @e coin_inputs
+ * @param coin_inputs The input for the coins to withdraw
+ * @param max_age The maximum age we commit to.
+ * @param res_cb A callback for the result, maybe NULL
+ * @param res_cb_cls A closure for @e res_cb, maybe NULL
+ * @return a handle for this request; NULL if the argument was invalid.
+ * In this case, the callback will not be called.
+ */
+struct TALER_EXCHANGE_AgeWithdrawHandle *
+TALER_EXCHANGE_age_withdraw (
+ struct GNUNET_CURL_Context *curl_ctx,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *exchange_url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ size_t num_coins,
+ const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[static
+ num_coins],
+ uint8_t max_age,
+ TALER_EXCHANGE_AgeWithdrawCallback res_cb,
+ void *res_cb_cls);
+
+/**
+ * Cancel a age-withdraw request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param awh the age-withdraw handle
+ */
+void
+TALER_EXCHANGE_age_withdraw_cancel (
+ struct TALER_EXCHANGE_AgeWithdrawHandle *awh);
+
+
+/**++++++ age-withdraw with pre-blinded planchets ***************************/
+
+/**
+ * @brief Information needed to withdraw (and reveal) age restricted coins.
+ */
+struct TALER_EXCHANGE_AgeWithdrawBlindedInput
+{
+ /**
+ * The denomination of the coin. Must support age restriction, i.e
+ * its .keys.age_mask MUST not be 0
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
+
+ /**
+ * Blinded Planchets
+ */
+ struct TALER_PlanchetDetail planchet_details[TALER_CNC_KAPPA];
+};
+
+/**
+ * Response from an age-withdraw request with pre-blinded planchets
+ */
+struct TALER_EXCHANGE_AgeWithdrawBlindedResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Index that should not be revealed during the age-withdraw reveal phase.
+ * The struct TALER_PlanchetMasterSecretP * from the request
+ * with this index are the ones to keep.
+ */
+ uint8_t noreveal_index;
+
+ /**
+ * The commitment of the call to age-withdraw, needed for the subsequent
+ * call to /age-withdraw/$ACH/reveal.
+ */
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+
+ /**
+ * Key used by the exchange to sign the response.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ } ok;
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting an
+ * age-withdraw request to a exchange with pre-blinded planchets
+ * without the (un)blinding factor.
+ *
+ * @param cls closure
+ * @param awbr response data
+ */
+typedef void
+(*TALER_EXCHANGE_AgeWithdrawBlindedCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AgeWithdrawBlindedResponse *awbr);
+
+
+/**
+ * @brief A /reserves/$RESERVE_PUB/age-withdraw Handle, 2nd variant with
+ * pre-blinded planchets.
+ *
+ * This variant does not do the blinding/unblinding and only
+ * fetches the blind signatures on the already blinded planchets.
+ * Used internally by the `struct TALER_EXCHANGE_BatchWithdrawHandle`
+ * implementation as well as for the reward logic of merchants.
+ */
+struct TALER_EXCHANGE_AgeWithdrawBlindedHandle;
+
+/**
+ * Withdraw age-restricted coins from the exchange using a
+ * /reserves/$RESERVE_PUB/age-withdraw request. This API is typically used
+ * by a merchant to withdraw a reward where the planchets are pre-blinded and
+ * the blinding factor is unknown to the merchant.
+ *
+ * Note that to ensure that no money is lost in case of hardware
+ * failures, the caller must have committed (most of) the arguments to
+ * disk before calling, and be ready to repeat the request with the
+ * same arguments in case of failures.
+ *
+ * @param curl_ctx The curl context to use
+ * @param exchange_url The base-URL of the exchange
+ * @param keys The /keys material from the exchange
+ * @param max_age The maximum age that the coins are committed to.
+ * @param num_input number of entries in the @a blinded_input array
+ * @param blinded_input array of planchet details of the planchet to withdraw
+ * @param reserve_priv private key of the reserve to withdraw from
+ * @param res_cb the callback to call when the final result for this request is available
+ * @param res_cb_cls closure for @a res_cb
* @return NULL
* if the inputs are invalid (i.e. denomination key not with this exchange).
- * Otherwise, pointer to a buffer of @a res_size to store persistently
- * before proceeding to #TALER_EXCHANGE_melt().
- * Non-null results should be freed using GNUNET_free().
+ * In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *
+TALER_EXCHANGE_age_withdraw_blinded (
+ struct GNUNET_CURL_Context *curl_ctx,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *exchange_url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ uint8_t max_age,
+ unsigned int num_input,
+ const struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[static
+ num_input],
+ TALER_EXCHANGE_AgeWithdrawBlindedCallback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ * Cancel an age-withdraw request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param awbh the age-withdraw handle
+ */
+void
+TALER_EXCHANGE_age_withdraw_blinded_cancel (
+ struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh);
+
+
+/* ********************* /age-withdraw/$ACH/reveal ************************ */
+
+/**
+ * @brief A handle to a /age-withdraw/$ACH/reveal request
+ */
+struct TALER_EXCHANGE_AgeWithdrawRevealHandle;
+
+/**
+ * The response from a /age-withdraw/$ACH/reveal request
+ */
+struct TALER_EXCHANGE_AgeWithdrawRevealResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response
+ */
+ union
+ {
+ /**
+ * Details if the status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Number of signatures returned.
+ */
+ unsigned int num_sigs;
+
+ /**
+ * Array of @e num_coins blinded denomination signatures, giving each
+ * coin its value and validity. The array give these coins in the same
+ * order (and should have the same length) in which the original
+ * age-withdraw request specified the respective denomination keys.
+ */
+ const struct TALER_BlindedDenominationSignature *blinded_denom_sigs;
+
+ } ok;
+ } details;
+
+};
+
+typedef void
+(*TALER_EXCHANGE_AgeWithdrawRevealCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_AgeWithdrawRevealResponse *awr);
+
+/**
+ * Submit an age-withdraw-reveal request to the exchange and get the exchange's
+ * response.
+ *
+ * This API is typically used by a wallet. Note that to ensure that
+ * no money is lost in case of hardware failures, the provided
+ * argument @a rd should be committed to persistent storage
+ * prior to calling this function.
+ *
+ * @param curl_ctx The curl context
+ * @param exchange_url The base url of the exchange
+ * @param num_coins The number of elements in @e coin_inputs and @e alg_values
+ * @param coin_inputs The input for the coins to withdraw, same as in the previous call to /age-withdraw
+ * @param noreveal_index The index into each of the kappa coin candidates, that should not be revealed to the exchange
+ * @param h_commitment The commmitment from the previous call to /age-withdraw
+ * @param reserve_pub The public key of the reserve the original call to /age-withdraw was made to
+ * @param res_cb A callback for the result, maybe NULL
+ * @param res_cb_cls A closure for @e res_cb, maybe NULL
+ * @return a handle for this request; NULL if the argument was invalid.
+ * In this case, the callback will not be called.
+ */
+struct TALER_EXCHANGE_AgeWithdrawRevealHandle *
+TALER_EXCHANGE_age_withdraw_reveal (
+ struct GNUNET_CURL_Context *curl_ctx,
+ const char *exchange_url,
+ size_t num_coins,
+ const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[static
+ num_coins],
+ uint8_t noreveal_index,
+ const struct TALER_AgeWithdrawCommitmentHashP *h_commitment,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ TALER_EXCHANGE_AgeWithdrawRevealCallback res_cb,
+ void *res_cb_cls);
+
+
+/**
+ * @brief Cancel an age-withdraw-reveal request
+ *
+ * @param awrh Handle to an age-withdraw-reqveal request
+ */
+void
+TALER_EXCHANGE_age_withdraw_reveal_cancel (
+ struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh);
+
+
+/* ********************* /refresh/melt+reveal ***************************** */
+
+
+/**
+ * Information needed to melt (partially spent) coins to obtain fresh coins
+ * that are unlinkable to the original coin(s). Note that melting more than
+ * one coin in a single request will make those coins linkable, so we only melt
+ * one coin at a time.
*/
-char *
-TALER_EXCHANGE_refresh_prepare (
- const struct TALER_CoinSpendPrivateKeyP *melt_priv,
- const struct TALER_Amount *melt_amount,
- const struct TALER_DenominationSignature *melt_sig,
- const struct TALER_EXCHANGE_DenomPublicKey *melt_pk,
- unsigned int fresh_pks_len,
- const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks,
- size_t *res_size);
+struct TALER_EXCHANGE_RefreshData
+{
+ /**
+ * private key of the coin to melt
+ */
+ struct TALER_CoinSpendPrivateKeyP melt_priv;
+
+ /**
+ * age commitment and proof that went into the original coin,
+ * might be NULL.
+ */
+ const struct TALER_AgeCommitmentProof *melt_age_commitment_proof;
+
+ /**
+ * Hash of age commitment and proof that went into the original coin,
+ * might be NULL.
+ */
+ const struct TALER_AgeCommitmentHash *melt_h_age_commitment;
+
+ /**
+ * amount specifying how much the coin will contribute to the melt
+ * (including fee)
+ */
+ struct TALER_Amount melt_amount;
+
+ /**
+ * signatures affirming the validity of the public keys corresponding to the
+ * @e melt_priv private key
+ */
+ struct TALER_DenominationSignature melt_sig;
+
+ /**
+ * denomination key information record corresponding to the @e melt_sig
+ * validity of the keys
+ */
+ struct TALER_EXCHANGE_DenomPublicKey melt_pk;
+
+ /**
+ * array of @e pks_len denominations of fresh coins to create
+ */
+ const struct TALER_EXCHANGE_DenomPublicKey *fresh_pks;
+
+ /**
+ * length of the @e pks array
+ */
+ unsigned int fresh_pks_len;
+};
/* ********************* /coins/$COIN_PUB/melt ***************************** */
@@ -1382,23 +3347,79 @@ struct TALER_EXCHANGE_MeltHandle;
/**
+ * Information we obtain per coin during melting.
+ */
+struct TALER_EXCHANGE_MeltBlindingDetail
+{
+ /**
+ * Exchange values contributed to the refresh operation
+ */
+ struct TALER_ExchangeWithdrawValues alg_value;
+
+};
+
+
+/**
+ * Response returned to a /melt request.
+ */
+struct TALER_EXCHANGE_MeltResponse
+{
+ /**
+ * Full HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Parsed response details, variant depending on the
+ * @e hr.http_status.
+ */
+ union
+ {
+ /**
+ * Results for status #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * Information returned per coin.
+ */
+ const struct TALER_EXCHANGE_MeltBlindingDetail *mbds;
+
+ /**
+ * Key used by the exchange to sign the response.
+ */
+ struct TALER_ExchangePublicKeyP sign_key;
+
+ /**
+ * Length of the @a mbds array with the exchange values
+ * and blinding keys we are using.
+ */
+ unsigned int num_mbds;
+
+ /**
+ * Gamma value chosen by the exchange.
+ */
+ uint32_t noreveal_index;
+ } ok;
+
+ } details;
+};
+
+
+/**
* Callbacks of this type are used to notify the application about the result
* of the /coins/$COIN_PUB/melt stage. If successful, the @a noreveal_index
* should be committed to disk prior to proceeding
* #TALER_EXCHANGE_refreshes_reveal().
*
* @param cls closure
- * @param hr HTTP response data
- * @param noreveal_index choice by the exchange in the cut-and-choose protocol,
- * UINT32_MAX on error
- * @param sign_key exchange key used to sign @a full_response, or NULL
+ * @param mr response details
*/
typedef void
(*TALER_EXCHANGE_MeltCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- uint32_t noreveal_index,
- const struct TALER_ExchangePublicKeyP *sign_key);
+ const struct TALER_EXCHANGE_MeltResponse *mr);
/**
@@ -1407,26 +3428,28 @@ typedef void
*
* This API is typically used by a wallet. Note that to ensure that
* no money is lost in case of hardware failures, the provided
- * argument should have been constructed using
- * #TALER_EXCHANGE_refresh_prepare and committed to persistent storage
+ * argument @a rd should be committed to persistent storage
* prior to calling this function.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param refresh_data_length size of the @a refresh_data (returned
- * in the `res_size` argument from #TALER_EXCHANGE_refresh_prepare())
- * @param refresh_data the refresh data as returned from
- #TALER_EXCHANGE_refresh_prepare())
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param rms the fresh secret that defines the refresh operation
+ * @param rd the refresh data specifying the characteristics of the operation
* @param melt_cb the callback to call with the result
* @param melt_cb_cls closure for @a melt_cb
* @return a handle for this request; NULL if the argument was invalid.
* In this case, neither callback will be called.
*/
struct TALER_EXCHANGE_MeltHandle *
-TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange,
- size_t refresh_data_length,
- const char *refresh_data,
- TALER_EXCHANGE_MeltCallback melt_cb,
- void *melt_cb_cls);
+TALER_EXCHANGE_melt (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_RefreshMasterSecretP *rms,
+ const struct TALER_EXCHANGE_RefreshData *rd,
+ TALER_EXCHANGE_MeltCallback melt_cb,
+ void *melt_cb_cls);
/**
@@ -1443,26 +3466,92 @@ TALER_EXCHANGE_melt_cancel (struct TALER_EXCHANGE_MeltHandle *mh);
/**
+ * Information about a coin obtained via /refreshes/$RCH/reveal.
+ */
+struct TALER_EXCHANGE_RevealedCoinInfo
+{
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+ /**
+ * Master secret of this coin.
+ */
+ struct TALER_PlanchetMasterSecretP ps;
+
+ /**
+ * Age commitment and its hash of the coin, might be NULL.
+ */
+ struct TALER_AgeCommitmentProof *age_commitment_proof;
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Blinding keys used to blind the fresh coin.
+ */
+ union GNUNET_CRYPTO_BlindingSecretP bks;
+
+ /**
+ * Signature affirming the validity of the coin.
+ */
+ struct TALER_DenominationSignature sig;
+
+};
+
+
+/**
+ * Result of a /refreshes/$RCH/reveal request.
+ */
+struct TALER_EXCHANGE_RevealResult
+{
+ /**
+ * HTTP status.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Parsed response details, variant depending on the
+ * @e hr.http_status.
+ */
+ union
+ {
+ /**
+ * Results for status #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Array of @e num_coins values about the coins obtained via the refresh
+ * operation. The array give the coins in the same order (and should
+ * have the same length) in which the original melt request specified the
+ * respective denomination keys.
+ */
+ const struct TALER_EXCHANGE_RevealedCoinInfo *coins;
+
+ /**
+ * Number of coins returned.
+ */
+ unsigned int num_coins;
+ } ok;
+
+ } details;
+
+};
+
+
+/**
* Callbacks of this type are used to return the final result of
* submitting a refresh request to a exchange. If the operation was
* successful, this function returns the signatures over the coins
- * that were remelted. The @a coin_privs and @a sigs arrays give the
- * coins in the same order (and should have the same length) in which
- * the original request specified the respective denomination keys.
+ * that were remelted.
*
* @param cls closure
- * @param hr HTTP response data
- * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
- * @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
- * @param sigs array of signature over @a num_coins coins, NULL on error
+ * @param rr result of the reveal operation
*/
typedef void
(*TALER_EXCHANGE_RefreshesRevealCallback)(
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- unsigned int num_coins,
- const struct TALER_PlanchetSecretsP *coin_privs,
- const struct TALER_DenominationSignature *sigs);
+ const struct TALER_EXCHANGE_RevealResult *rr);
/**
@@ -1480,11 +3569,12 @@ struct TALER_EXCHANGE_RefreshesRevealHandle;
* arguments should have been committed to persistent storage
* prior to calling this function.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
- * @param refresh_data_length size of the @a refresh_data (returned
- * in the `res_size` argument from #TALER_EXCHANGE_refresh_prepare())
- * @param refresh_data the refresh data as returned from
- #TALER_EXCHANGE_refresh_prepare())
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param rms the fresh secret that defines the refresh operation
+ * @param rd the refresh data that characterizes the refresh operation
+ * @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, must match value in @a rd
+ * @param alg_values array @a num_coins of exchange values contributed to the refresh operation
* @param noreveal_index response from the exchange to the
* #TALER_EXCHANGE_melt() invocation
* @param reveal_cb the callback to call with the final result of the
@@ -1495,9 +3585,12 @@ struct TALER_EXCHANGE_RefreshesRevealHandle;
*/
struct TALER_EXCHANGE_RefreshesRevealHandle *
TALER_EXCHANGE_refreshes_reveal (
- struct TALER_EXCHANGE_Handle *exchange,
- size_t refresh_data_length,
- const char *refresh_data,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_RefreshMasterSecretP *rms,
+ const struct TALER_EXCHANGE_RefreshData *rd,
+ unsigned int num_coins,
+ const struct TALER_ExchangeWithdrawValues alg_values[static num_coins],
uint32_t noreveal_index,
TALER_EXCHANGE_RefreshesRevealCallback reveal_cb,
void *reveal_cb_cls);
@@ -1524,26 +3617,90 @@ struct TALER_EXCHANGE_LinkHandle;
/**
+ * Information about a coin obtained via /link.
+ */
+struct TALER_EXCHANGE_LinkedCoinInfo
+{
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+ /**
+ * Age commitment and its hash, if applicable.
+ */
+ bool has_age_commitment;
+ struct TALER_AgeCommitmentProof age_commitment_proof;
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Master secret of this coin.
+ */
+ struct TALER_PlanchetMasterSecretP ps;
+
+ /**
+ * Signature affirming the validity of the coin.
+ */
+ struct TALER_DenominationSignature sig;
+
+ /**
+ * Denomination public key of the coin.
+ */
+ struct TALER_DenominationPublicKey pub;
+};
+
+
+/**
+ * Result of a /link request.
+ */
+struct TALER_EXCHANGE_LinkResult
+{
+ /**
+ * HTTP status.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Parsed response details, variant depending on the
+ * @e hr.http_status.
+ */
+ union
+ {
+ /**
+ * Results for status #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Array of @e num_coins values about the
+ * coins obtained via linkage.
+ */
+ const struct TALER_EXCHANGE_LinkedCoinInfo *coins;
+
+ /**
+ * Number of coins returned.
+ */
+ unsigned int num_coins;
+ } ok;
+
+ } details;
+
+};
+
+
+/**
* Callbacks of this type are used to return the final result of submitting a
* /coins/$COIN_PUB/link request to a exchange. If the operation was
* successful, this function returns the signatures over the coins that were
* created when the original coin was melted.
*
* @param cls closure
- * @param hr HTTP response data
- * @param num_coins number of fresh coins created, length of the @a sigs and @a coin_privs arrays, 0 if the operation failed
- * @param coin_privs array of @a num_coins private keys for the coins that were created, NULL on error
- * @param sigs array of signature over @a num_coins coins, NULL on error
- * @param pubs array of public keys for the @a sigs, NULL on error
+ * @param lr result of the /link operation
*/
typedef void
(*TALER_EXCHANGE_LinkCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- unsigned int num_coins,
- const struct TALER_CoinSpendPrivateKeyP *coin_privs,
- const struct TALER_DenominationSignature *sigs,
- const struct TALER_DenominationPublicKey *pubs);
+ const struct TALER_EXCHANGE_LinkResult *lr);
/**
@@ -1552,18 +3709,23 @@ typedef void
* This API is typically not used by anyone, it is more a threat against those
* trying to receive a funds transfer by abusing the refresh protocol.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param ctx CURL context
+ * @param url exchange base URL
* @param coin_priv private key to request link data for
+ * @param age_commitment_proof age commitment to the corresponding coin, might be NULL
* @param link_cb the callback to call with the useful result of the
* refresh operation the @a coin_priv was involved in (if any)
* @param link_cb_cls closure for @a link_cb
* @return a handle for this request
*/
struct TALER_EXCHANGE_LinkHandle *
-TALER_EXCHANGE_link (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_CoinSpendPrivateKeyP *coin_priv,
- TALER_EXCHANGE_LinkCallback link_cb,
- void *link_cb_cls);
+TALER_EXCHANGE_link (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_CoinSpendPrivateKeyP *coin_priv,
+ const struct TALER_AgeCommitmentProof *age_commitment_proof,
+ TALER_EXCHANGE_LinkCallback link_cb,
+ void *link_cb_cls);
/**
@@ -1585,38 +3747,101 @@ struct TALER_EXCHANGE_TransfersGetHandle;
/**
+ * Information the exchange returns per wire transfer.
+ */
+struct TALER_EXCHANGE_TransferData
+{
+
+ /**
+ * exchange key used to sign
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * exchange signature over the transfer data
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+
+ /**
+ * hash of the payto:// URI the transfer went to
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * time when the exchange claims to have performed the wire transfer
+ */
+ struct GNUNET_TIME_Timestamp execution_time;
+
+ /**
+ * Actual amount of the wire transfer, excluding the wire fee.
+ */
+ struct TALER_Amount total_amount;
+
+ /**
+ * wire fee that was charged by the exchange
+ */
+ struct TALER_Amount wire_fee;
+
+ /**
+ * length of the @e details array
+ */
+ unsigned int details_length;
+
+ /**
+ * array with details about the combined transactions
+ */
+ const struct TALER_TrackTransferDetails *details;
+
+};
+
+
+/**
+ * Response for a GET /transfers request.
+ */
+struct TALER_EXCHANGE_TransfersGetResponse
+{
+ /**
+ * HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on HTTP status code.
+ */
+ union
+ {
+ /**
+ * Details if status code is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ struct TALER_EXCHANGE_TransferData td;
+ } ok;
+
+ } details;
+};
+
+
+/**
* Function called with detailed wire transfer data, including all
* of the coin transactions that were combined into the wire transfer.
*
* @param cls closure
- * @param hr HTTP response data
- * @param sign_key exchange key used to sign @a json, or NULL
- * @param h_wire hash of the wire transfer address the transfer went to, or NULL on error
- * @param execution_time time when the exchange claims to have performed the wire transfer
- * @param total_amount total amount of the wire transfer, or NULL if the exchange could
- * not provide any @a wtid (set only if @a http_status is #MHD_HTTP_OK)
- * @param wire_fee wire fee that was charged by the exchange
- * @param details_length length of the @a details array
- * @param details array with details about the combined transactions
+ * @param tgr response data
*/
typedef void
(*TALER_EXCHANGE_TransfersGetCallback)(
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ExchangePublicKeyP *sign_key,
- const struct GNUNET_HashCode *h_wire,
- struct GNUNET_TIME_Absolute execution_time,
- const struct TALER_Amount *total_amount,
- const struct TALER_Amount *wire_fee,
- unsigned int details_length,
- const struct TALER_TrackTransferDetails *details);
+ const struct TALER_EXCHANGE_TransfersGetResponse *tgr);
/**
* Query the exchange about which transactions were combined
* to create a wire transfer.
*
- * @param exchange exchange to query
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
* @param wtid raw wire transfer identifier to get information about
* @param cb callback to call
* @param cb_cls closure for @a cb
@@ -1624,7 +3849,9 @@ typedef void
*/
struct TALER_EXCHANGE_TransfersGetHandle *
TALER_EXCHANGE_transfers_get (
- struct TALER_EXCHANGE_Handle *exchange,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_EXCHANGE_TransfersGetCallback cb,
void *cb_cls);
@@ -1651,24 +3878,102 @@ struct TALER_EXCHANGE_DepositGetHandle;
/**
+ * Data returned for a successful GET /deposits/ request.
+ */
+struct TALER_EXCHANGE_GetDepositResponse
+{
+
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details about the response.
+ */
+ union
+ {
+
+ /**
+ * Response if the status was #MHD_HTTP_OK
+ */
+ struct TALER_EXCHANGE_DepositData
+ {
+ /**
+ * exchange key used to sign, all zeros if exchange did not
+ * yet execute the transaction
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * signature from the exchange over the deposit data, all zeros if exchange did not
+ * yet execute the transaction
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+
+ /**
+ * wire transfer identifier used by the exchange, all zeros if exchange did not
+ * yet execute the transaction
+ */
+ struct TALER_WireTransferIdentifierRawP wtid;
+
+ /**
+ * actual execution time for the wire transfer
+ */
+ struct GNUNET_TIME_Timestamp execution_time;
+
+ /**
+ * contribution to the total amount by this coin, all zeros if exchange did not
+ * yet execute the transaction
+ */
+ struct TALER_Amount coin_contribution;
+
+ } ok;
+
+ /**
+ * Response if the status was #MHD_HTTP_ACCEPTED
+ */
+ struct
+ {
+
+ /**
+ * planned execution time for the wire transfer
+ */
+ struct GNUNET_TIME_Timestamp execution_time;
+
+ /**
+ * KYC legitimization requirement that the merchant should use to check
+ * for its KYC status.
+ */
+ uint64_t requirement_row;
+
+ /**
+ * Current AML state for the account. May explain why transfers are
+ * not happening.
+ */
+ enum TALER_AmlDecisionState aml_decision;
+
+ /**
+ * Set to 'true' if the KYC check is already finished and
+ * the exchange is merely waiting for the @e execution_time.
+ */
+ bool kyc_ok;
+ } accepted;
+
+ } details;
+};
+
+
+/**
* Function called with detailed wire transfer data.
*
* @param cls closure
- * @param hr HTTP response data
- * @param sign_key exchange key used to sign @a json, or NULL
- * @param wtid wire transfer identifier used by the exchange, NULL if exchange did not
- * yet execute the transaction
- * @param execution_time actual or planned execution time for the wire transfer
- * @param coin_contribution contribution to the total amount by this coin (can be NULL)
+ * @param dr details about the deposit response
*/
typedef void
(*TALER_EXCHANGE_DepositGetCallback)(
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ExchangePublicKeyP *sign_key,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- struct GNUNET_TIME_Absolute execution_time,
- const struct TALER_Amount *coin_contribution);
+ const struct TALER_EXCHANGE_GetDepositResponse *dr);
/**
@@ -1676,22 +3981,28 @@ typedef void
* which aggregate wire transfer the deposit operation identified by @a coin_pub,
* @a merchant_priv and @a h_contract_terms contributed to.
*
- * @param exchange the exchange to query
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
* @param merchant_priv the merchant's private key
* @param h_wire hash of merchant's wire transfer details
* @param h_contract_terms hash of the proposal data
* @param coin_pub public key of the coin
+ * @param timeout timeout to use for long-polling, 0 for no long polling
* @param cb function to call with the result
* @param cb_cls closure for @a cb
* @return handle to abort request
*/
struct TALER_EXCHANGE_DepositGetHandle *
TALER_EXCHANGE_deposits_get (
- struct TALER_EXCHANGE_Handle *exchange,
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
const struct TALER_MerchantPrivateKeyP *merchant_priv,
- const struct GNUNET_HashCode *h_wire,
- const struct GNUNET_HashCode *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct GNUNET_TIME_Relative timeout,
TALER_EXCHANGE_DepositGetCallback cb,
void *cb_cls);
@@ -1707,132 +4018,3310 @@ TALER_EXCHANGE_deposits_get_cancel (
struct TALER_EXCHANGE_DepositGetHandle *dwh);
+/* ********************* /recoup *********************** */
+
+
+/**
+ * @brief A /recoup Handle
+ */
+struct TALER_EXCHANGE_RecoupHandle;
+
+
/**
- * Convenience function. Verifies a coin's transaction history as
- * returned by the exchange.
+ * Response from a recoup request.
+ */
+struct TALER_EXCHANGE_RecoupResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * public key of the reserve receiving the recoup
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ } ok;
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to return the final result of
+ * submitting a recoup request to a exchange. If the operation was
+ * successful, this function returns the @a reserve_pub of the
+ * reserve that was credited.
*
- * @param dk fee structure for the coin, NULL to skip verifying fees
- * @param currency expected currency for the coin
- * @param coin_pub public key of the coin
- * @param history history of the coin in json encoding
- * @param[out] total how much of the coin has been spent according to @a history
- * @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not
+ * @param cls closure
+ * @param rr response data
*/
-int
-TALER_EXCHANGE_verify_coin_history (
- const struct TALER_EXCHANGE_DenomPublicKey *dk,
- const char *currency,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- json_t *history,
- struct TALER_Amount *total);
+typedef void
+(*TALER_EXCHANGE_RecoupResultCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_RecoupResponse *rr);
/**
- * Parse history given in JSON format and return it in binary
- * format.
+ * Ask the exchange to pay back a coin due to the exchange triggering
+ * the emergency recoup protocol for a given denomination. The value
+ * of the coin will be refunded to the original customer (without fees).
*
- * @param exchange connection to the exchange we can use
- * @param history JSON array with the history
- * @param reserve_pub public key of the reserve to inspect
- * @param currency currency we expect the balance to be in
- * @param[out] balance final balance
- * @param history_length number of entries in @a history
- * @param[out] rhistory array of length @a history_length, set to the
- * parsed history entries
- * @return #GNUNET_OK if history was valid and @a rhistory and @a balance
- * were set,
- * #GNUNET_SYSERR if there was a protocol violation in @a history
- */
-int
-TALER_EXCHANGE_parse_reserve_history (
- struct TALER_EXCHANGE_Handle *exchange,
- const json_t *history,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const char *currency,
- struct TALER_Amount *balance,
- unsigned int history_length,
- struct TALER_EXCHANGE_ReserveHistory *rhistory);
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param pk kind of coin to pay back
+ * @param denom_sig signature over the coin by the exchange using @a pk
+ * @param exchange_vals contribution from the exchange on the withdraw
+ * @param ps secret internals of the original planchet
+ * @param recoup_cb the callback to call when the final result for this request is available
+ * @param recoup_cb_cls closure for @a recoup_cb
+ * @return NULL
+ * if the inputs are invalid (i.e. denomination key not with this exchange).
+ * In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_RecoupHandle *
+TALER_EXCHANGE_recoup (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct TALER_DenominationSignature *denom_sig,
+ const struct TALER_ExchangeWithdrawValues *exchange_vals,
+ const struct TALER_PlanchetMasterSecretP *ps,
+ TALER_EXCHANGE_RecoupResultCallback recoup_cb,
+ void *recoup_cb_cls);
/**
- * Free memory (potentially) allocated by #TALER_EXCHANGE_parse_reserve_history().
+ * Cancel a recoup request. This function cannot be used on a
+ * request handle if the callback was already invoked.
*
- * @param rhistory result to free
- * @param len number of entries in @a rhistory
+ * @param ph the recoup handle
*/
void
-TALER_EXCHANGE_free_reserve_history (
- struct TALER_EXCHANGE_ReserveHistory *rhistory,
- unsigned int len);
+TALER_EXCHANGE_recoup_cancel (struct TALER_EXCHANGE_RecoupHandle *ph);
-/* ********************* /recoup *********************** */
+/* ********************* /recoup-refresh *********************** */
/**
- * @brief A /recoup Handle
+ * @brief A /recoup-refresh Handle
*/
-struct TALER_EXCHANGE_RecoupHandle;
+struct TALER_EXCHANGE_RecoupRefreshHandle;
+
+
+/**
+ * Response from a /recoup-refresh request.
+ */
+struct TALER_EXCHANGE_RecoupRefreshResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * public key of the dirty coin that was credited
+ */
+ struct TALER_CoinSpendPublicKeyP old_coin_pub;
+
+ } ok;
+ } details;
+
+};
/**
* Callbacks of this type are used to return the final result of
- * submitting a refresh request to a exchange. If the operation was
- * successful, this function returns the signatures over the coins
- * that were remelted. The @a coin_privs and @a sigs arrays give the
- * coins in the same order (and should have the same length) in which
- * the original request specified the respective denomination keys.
+ * submitting a recoup-refresh request to a exchange.
*
* @param cls closure
- * @param hr HTTP response data
- * @param amount amount the exchange will wire back for this coin,
- * on error the total balance remaining, or NULL
- * @param timestamp what time did the exchange receive the /recoup request
- * @param reserve_pub public key of the reserve receiving the recoup, NULL if refreshed or on error
- * @param old_coin_pub public key of the dirty coin, NULL if not refreshed or on error
+ * @param rrr response data
*/
typedef void
-(*TALER_EXCHANGE_RecoupResultCallback) (
+(*TALER_EXCHANGE_RecoupRefreshResultCallback) (
void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_CoinSpendPublicKeyP *old_coin_pub);
+ const struct TALER_EXCHANGE_RecoupRefreshResponse *rrr);
/**
* Ask the exchange to pay back a coin due to the exchange triggering
* the emergency recoup protocol for a given denomination. The value
- * of the coin will be refunded to the original customer (without fees).
+ * of the coin will be refunded to the original coin that the
+ * revoked coin was refreshed from. The original coin is then
+ * considered a zombie.
*
- * @param exchange the exchange handle; the exchange must be ready to operate
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
* @param pk kind of coin to pay back
* @param denom_sig signature over the coin by the exchange using @a pk
- * @param ps secret internals of the original planchet
- * @param was_refreshed #GNUNET_YES if the coin in @a ps was refreshed
+ * @param exchange_vals contribution from the exchange on the withdraw
+ * @param rms melt secret of the refreshing operation
+ * @param ps coin-specific secrets derived for this coin during the refreshing operation
+ * @param idx index of the fresh coin in the refresh operation that is now being recouped
* @param recoup_cb the callback to call when the final result for this request is available
* @param recoup_cb_cls closure for @a recoup_cb
* @return NULL
* if the inputs are invalid (i.e. denomination key not with this exchange).
* In this case, the callback is not called.
*/
-struct TALER_EXCHANGE_RecoupHandle *
-TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange,
- const struct TALER_EXCHANGE_DenomPublicKey *pk,
- const struct TALER_DenominationSignature *denom_sig,
- const struct TALER_PlanchetSecretsP *ps,
- int was_refreshed,
- TALER_EXCHANGE_RecoupResultCallback recoup_cb,
- void *recoup_cb_cls);
+struct TALER_EXCHANGE_RecoupRefreshHandle *
+TALER_EXCHANGE_recoup_refresh (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_EXCHANGE_DenomPublicKey *pk,
+ const struct TALER_DenominationSignature *denom_sig,
+ const struct TALER_ExchangeWithdrawValues *exchange_vals,
+ const struct TALER_RefreshMasterSecretP *rms,
+ const struct TALER_PlanchetMasterSecretP *ps,
+ unsigned int idx,
+ TALER_EXCHANGE_RecoupRefreshResultCallback recoup_cb,
+ void *recoup_cb_cls);
/**
- * Cancel a recoup request. This function cannot be used on a
- * request handle if the callback was already invoked.
+ * Cancel a recoup-refresh request. This function cannot be used on a request
+ * handle if the callback was already invoked.
*
* @param ph the recoup handle
*/
void
-TALER_EXCHANGE_recoup_cancel (struct TALER_EXCHANGE_RecoupHandle *ph);
+TALER_EXCHANGE_recoup_refresh_cancel (
+ struct TALER_EXCHANGE_RecoupRefreshHandle *ph);
+
+
+/* ********************* /kyc* *********************** */
+
+/**
+ * Handle for a ``/kyc-check`` operation.
+ */
+struct TALER_EXCHANGE_KycCheckHandle;
+
+
+/**
+ * KYC status response details.
+ */
+struct TALER_EXCHANGE_KycStatus
+{
+ /**
+ * HTTP status code returned by the exchange.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, if any.
+ */
+ enum TALER_ErrorCode ec;
+
+ union
+ {
+
+ /**
+ * KYC is OK, affirmation returned by the exchange.
+ */
+ struct
+ {
+
+ /**
+ * Details about which KYC check(s) were passed.
+ */
+ const json_t *kyc_details;
+
+ /**
+ * Time of the affirmation.
+ */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ /**
+ * The signing public key used for @e exchange_sig.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * Signature of purpose
+ * #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS affirming
+ * the successful KYC process.
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
+ } ok;
+
+ /**
+ * KYC is required.
+ */
+ struct
+ {
+
+ /**
+ * URL the user should open in a browser if
+ * the KYC process is to be run. Returned if
+ * @e http_status is #MHD_HTTP_ACCEPTED.
+ */
+ const char *kyc_url;
+
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
+ } accepted;
+
+ /**
+ * KYC is OK, but account needs positive AML decision.
+ */
+ struct
+ {
+
+ /**
+ * AML status for the account.
+ */
+ enum TALER_AmlDecisionState aml_status;
+
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+/**
+ * Function called with the result of a KYC check.
+ *
+ * @param cls closure
+ * @param ks the account's KYC status details
+ */
+typedef void
+(*TALER_EXCHANGE_KycStatusCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_KycStatus *ks);
+
+
+/**
+ * Run interaction with exchange to check KYC status
+ * of a merchant.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param keys keys of the exchange
+ * @param requirement_row number identifying the KYC requirement
+ * @param h_payto hash of the payto:// URI at @a payment_target
+ * @param ut type of the entity performing the KYC check
+ * @param timeout how long to wait for a positive KYC status
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
+ */
+struct TALER_EXCHANGE_KycCheckHandle *
+TALER_EXCHANGE_kyc_check (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ uint64_t requirement_row,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_KYCLOGIC_KycUserType ut,
+ struct GNUNET_TIME_Relative timeout,
+ TALER_EXCHANGE_KycStatusCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel KYC check operation.
+ *
+ * @param kyc handle for operation to cancel
+ */
+void
+TALER_EXCHANGE_kyc_check_cancel (struct TALER_EXCHANGE_KycCheckHandle *kyc);
+
+
+/**
+ * KYC proof response details.
+ */
+struct TALER_EXCHANGE_KycProofResponse
+{
+ /**
+ * HTTP status code returned by the exchange.
+ */
+ unsigned int http_status;
+
+ union
+ {
+
+ /**
+ * KYC is OK, affirmation returned by the exchange.
+ */
+ struct
+ {
+
+ /**
+ * Where to redirect the client next.
+ */
+ const char *redirect_url;
+
+ } found;
+
+ } details;
+
+};
+
+/**
+ * Function called with the result of a KYC check.
+ *
+ * @param cls closure
+ * @param kpr the account's KYC status details
+ */
+typedef void
+(*TALER_EXCHANGE_KycProofCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_KycProofResponse *kpr);
+
+
+/**
+ * Handle for a /kyc-proof operation.
+ */
+struct TALER_EXCHANGE_KycProofHandle;
+
+
+/**
+ * Run interaction with exchange to provide proof of KYC status.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param h_payto hash of payto URI identifying the target account
+ * @param logic name of the KYC logic to run
+ * @param args additional args to pass, can be NULL
+ * or a string to append to the URL. Must then begin with '&'.
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
+ */
+struct TALER_EXCHANGE_KycProofHandle *
+TALER_EXCHANGE_kyc_proof (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *logic,
+ const char *args,
+ TALER_EXCHANGE_KycProofCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel KYC proof operation.
+ *
+ * @param kph handle for operation to cancel
+ */
+void
+TALER_EXCHANGE_kyc_proof_cancel (struct TALER_EXCHANGE_KycProofHandle *kph);
+
+
+/**
+ * Handle for a ``/kyc-wallet`` operation.
+ */
+struct TALER_EXCHANGE_KycWalletHandle;
+
+
+/**
+ * KYC status response details.
+ */
+struct TALER_EXCHANGE_WalletKycResponse
+{
+
+ /**
+ * HTTP status code returned by the exchange.
+ */
+ unsigned int http_status;
+
+ /**
+ * Taler error code, if any.
+ */
+ enum TALER_ErrorCode ec;
+
+ /**
+ * Variants depending on @e http_status.
+ */
+ union
+ {
+
+ /**
+ * In case @e http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+ /**
+ * Wallet's KYC requirement row.
+ */
+ uint64_t requirement_row;
+
+ /**
+ * Hash of the payto-URI identifying the wallet to KYC.
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+/**
+ * Function called with the result for a wallet looking
+ * up its KYC payment target.
+ *
+ * @param cls closure
+ * @param ks the wallets KYC payment target details
+ */
+typedef void
+(*TALER_EXCHANGE_KycWalletCallback)(
+ void *cls,
+ const struct TALER_EXCHANGE_WalletKycResponse *ks);
+
+
+/**
+ * Run interaction with exchange to find out the wallet's KYC
+ * identifier.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param reserve_priv wallet private key to check
+ * @param balance balance (or balance threshold) crossed by the wallet
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return NULL on error
+ */
+struct TALER_EXCHANGE_KycWalletHandle *
+TALER_EXCHANGE_kyc_wallet (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_Amount *balance,
+ TALER_EXCHANGE_KycWalletCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel KYC wallet operation
+ *
+ * @param kwh handle for operation to cancel
+ */
+void
+TALER_EXCHANGE_kyc_wallet_cancel (struct TALER_EXCHANGE_KycWalletHandle *kwh);
+
+
+/* ********************* /management *********************** */
+
+
+/**
+ * @brief Future Exchange's signature key
+ */
+struct TALER_EXCHANGE_FutureSigningPublicKey
+{
+ /**
+ * The signing public key
+ */
+ struct TALER_ExchangePublicKeyP key;
+
+ /**
+ * Signature by the security module affirming it owns this key.
+ */
+ struct TALER_SecurityModuleSignatureP signkey_secmod_sig;
+
+ /**
+ * Validity start time
+ */
+ struct GNUNET_TIME_Timestamp valid_from;
+
+ /**
+ * Validity expiration time (how long the exchange may use it).
+ */
+ struct GNUNET_TIME_Timestamp valid_until;
+
+ /**
+ * Validity expiration time for legal disputes.
+ */
+ struct GNUNET_TIME_Timestamp valid_legal;
+};
+
+
+/**
+ * @brief Public information about a future exchange's denomination key
+ */
+struct TALER_EXCHANGE_FutureDenomPublicKey
+{
+ /**
+ * The public key
+ */
+ struct TALER_DenominationPublicKey key;
+
+ /**
+ * Signature by the security module affirming it owns this key.
+ */
+ struct TALER_SecurityModuleSignatureP denom_secmod_sig;
+
+ /**
+ * Timestamp indicating when the denomination key becomes valid
+ */
+ struct GNUNET_TIME_Timestamp valid_from;
+
+ /**
+ * Timestamp indicating when the denomination key can’t be used anymore to
+ * withdraw new coins.
+ */
+ struct GNUNET_TIME_Timestamp withdraw_valid_until;
+
+ /**
+ * Timestamp indicating when coins of this denomination become invalid.
+ */
+ struct GNUNET_TIME_Timestamp expire_deposit;
+
+ /**
+ * When do signatures with this denomination key become invalid?
+ * After this point, these signatures cannot be used in (legal)
+ * disputes anymore, as the Exchange is then allowed to destroy its side
+ * of the evidence. @e expire_legal is expected to be significantly
+ * larger than @e expire_deposit (by a year or more).
+ */
+ struct GNUNET_TIME_Timestamp expire_legal;
+
+ /**
+ * The value of this denomination
+ */
+ struct TALER_Amount value;
+
+ /**
+ * The applicable fee for withdrawing a coin of this denomination
+ */
+ struct TALER_Amount fee_withdraw;
+
+ /**
+ * The applicable fee to spend a coin of this denomination
+ */
+ struct TALER_Amount fee_deposit;
+
+ /**
+ * The applicable fee to melt/refresh a coin of this denomination
+ */
+ struct TALER_Amount fee_refresh;
+
+ /**
+ * The applicable fee to refund a coin of this denomination
+ */
+ struct TALER_Amount fee_refund;
+
+};
+
+
+/**
+ * @brief Information about future keys from the exchange.
+ */
+struct TALER_EXCHANGE_FutureKeys
+{
+
+ /**
+ * Array of the exchange's online signing keys.
+ */
+ struct TALER_EXCHANGE_FutureSigningPublicKey *sign_keys;
+
+ /**
+ * Array of the exchange's denomination keys.
+ */
+ struct TALER_EXCHANGE_FutureDenomPublicKey *denom_keys;
+
+ /**
+ * Public key of the signkey security module.
+ */
+ struct TALER_SecurityModulePublicKeyP signkey_secmod_public_key;
+
+ /**
+ * Public key of the RSA denomination security module.
+ */
+ struct TALER_SecurityModulePublicKeyP denom_secmod_public_key;
+
+ /**
+ * Public key of the CS denomination security module.
+ */
+ struct TALER_SecurityModulePublicKeyP denom_secmod_cs_public_key;
+
+ /**
+ * Offline master public key used by this exchange.
+ */
+ struct TALER_MasterPublicKeyP master_pub;
+
+ /**
+ * Length of the @e sign_keys array (number of valid entries).
+ */
+ unsigned int num_sign_keys;
+
+ /**
+ * Length of the @e denom_keys array.
+ */
+ unsigned int num_denom_keys;
+
+};
+
+
+/**
+ * Response from a /management/keys request.
+ */
+struct TALER_EXCHANGE_ManagementGetKeysResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Response details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details if HTTP status is #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * information about the various keys used
+ * by the exchange
+ */
+ struct TALER_EXCHANGE_FutureKeys keys;
+
+ } ok;
+ } details;
+
+};
+
+
+/**
+ * Function called with information about future keys.
+ *
+ * @param cls closure
+ * @param mgr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementGetKeysCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementGetKeysResponse *mgr);
+
+
+/**
+ * @brief Handle for a GET /management/keys request.
+ */
+struct TALER_EXCHANGE_ManagementGetKeysHandle;
+
+
+/**
+ * Request future keys from the exchange. The obtained information will be
+ * passed to the @a cb.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param cb function to call with the exchange's future keys result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementGetKeysHandle *
+TALER_EXCHANGE_get_management_keys (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ TALER_EXCHANGE_ManagementGetKeysCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_get_management_keys() operation.
+ *
+ * @param gh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_get_management_keys_cancel (
+ struct TALER_EXCHANGE_ManagementGetKeysHandle *gh);
+
+
+/**
+ * @brief Public information about a signature on an exchange's online signing key
+ */
+struct TALER_EXCHANGE_SigningKeySignature
+{
+ /**
+ * The signing public key
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * Signature over this signing key by the exchange's master signature.
+ * Of purpose #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY
+ */
+ struct TALER_MasterSignatureP master_sig;
+
+};
+
+
+/**
+ * @brief Public information about a signature on an exchange's denomination key
+ */
+struct TALER_EXCHANGE_DenominationKeySignature
+{
+ /**
+ * The hash of the denomination's public key
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
+ * Signature over this denomination key by the exchange's master signature.
+ * Of purpose #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
+ */
+ struct TALER_MasterSignatureP master_sig;
+
+};
+
+
+/**
+ * Information needed for a POST /management/keys operation.
+ */
+struct TALER_EXCHANGE_ManagementPostKeysData
+{
+
+ /**
+ * Array of the master signatures for the exchange's online signing keys.
+ */
+ struct TALER_EXCHANGE_SigningKeySignature *sign_sigs;
+
+ /**
+ * Array of the master signatures for the exchange's denomination keys.
+ */
+ struct TALER_EXCHANGE_DenominationKeySignature *denom_sigs;
+
+ /**
+ * Length of the @e sign_keys array (number of valid entries).
+ */
+ unsigned int num_sign_sigs;
+
+ /**
+ * Length of the @e denom_keys array.
+ */
+ unsigned int num_denom_sigs;
+};
+
+
+/**
+ * Response from a POST /management/keys request.
+ */
+struct TALER_EXCHANGE_ManagementPostKeysResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+
+/**
+ * Function called with information about the post keys operation result.
+ *
+ * @param cls closure
+ * @param mr response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementPostKeysCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementPostKeysResponse *mr);
+
+
+/**
+ * @brief Handle for a POST /management/keys request.
+ */
+struct TALER_EXCHANGE_ManagementPostKeysHandle;
+
+
+/**
+ * Provide master-key signatures to the exchange.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param pkd signature data to POST
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementPostKeysHandle *
+TALER_EXCHANGE_post_management_keys (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_EXCHANGE_ManagementPostKeysData *pkd,
+ TALER_EXCHANGE_ManagementPostKeysCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_post_management_keys() operation.
+ *
+ * @param ph handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_post_management_keys_cancel (
+ struct TALER_EXCHANGE_ManagementPostKeysHandle *ph);
+
+
+/**
+ * Information needed for a POST /management/extensions operation.
+ *
+ * It represents the interface ExchangeKeysResponse as defined in
+ * https://docs.taler.net/design-documents/006-extensions.html#exchange
+ */
+struct TALER_EXCHANGE_ManagementPostExtensionsData
+{
+ const json_t *extensions;
+ struct TALER_MasterSignatureP extensions_sig;
+};
+
+
+/**
+ * Response from a POST /management/extensions request.
+ */
+struct TALER_EXCHANGE_ManagementPostExtensionsResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+
+/**
+ * Function called with information about the post extensions operation result.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementPostExtensionsCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementPostExtensionsResponse *hr);
+
+/**
+ * @brief Handle for a POST /management/extensions request.
+ */
+struct TALER_EXCHANGE_ManagementPostExtensionsHandle;
+
+
+/**
+ * Uploads the configurations of enabled extensions to the exchange, signed
+ * with the master key.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param ped signature data to POST
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementPostExtensionsHandle *
+TALER_EXCHANGE_management_post_extensions (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_EXCHANGE_ManagementPostExtensionsData *ped,
+ TALER_EXCHANGE_ManagementPostExtensionsCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_post_extensions() operation.
+ *
+ * @param ph handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_post_extensions_cancel (
+ struct TALER_EXCHANGE_ManagementPostExtensionsHandle *ph);
+
+
+/**
+ * Response from a POST /management/drain request.
+ */
+struct TALER_EXCHANGE_ManagementDrainResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+
+/**
+ * Function called with information about the drain profits result.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementDrainProfitsCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementDrainResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/drain request.
+ */
+struct TALER_EXCHANGE_ManagementDrainProfitsHandle;
+
+
+/**
+ * Uploads the drain profits request.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param wtid wire transfer identifier to use
+ * @param amount total to transfer
+ * @param date when was the request created
+ * @param account_section configuration section identifying account to debit
+ * @param payto_uri RFC 8905 URI of the account to credit
+ * @param master_sig signature affirming the operation
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementDrainProfitsHandle *
+TALER_EXCHANGE_management_drain_profits (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_Amount *amount,
+ struct GNUNET_TIME_Timestamp date,
+ const char *account_section,
+ const char *payto_uri,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementDrainProfitsCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_drain_profits() operation.
+ *
+ * @param dp handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_drain_profits_cancel (
+ struct TALER_EXCHANGE_ManagementDrainProfitsHandle *dp);
+
+
+/**
+ * Response from a POST /management/denominations/$DENOM/revoke request.
+ */
+struct TALER_EXCHANGE_ManagementRevokeDenominationResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+
+/**
+ * Function called with information about the post revocation operation result.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/denominations/$H_DENOM_PUB/revoke request.
+ */
+struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle;
+
+
+/**
+ * Inform the exchange that a denomination key was revoked.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param h_denom_pub hash of the denomination public key that was revoked
+ * @param master_sig signature affirming the revocation
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *
+TALER_EXCHANGE_management_revoke_denomination_key (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_revoke_denomination_key() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_revoke_denomination_key_cancel (
+ struct TALER_EXCHANGE_ManagementRevokeDenominationKeyHandle *rh);
+
+
+/**
+ * Response from a POST /management/signkeys/$SK/revoke request.
+ */
+struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+/**
+ * Function called with information about the post revocation operation result.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementRevokeSigningKeyCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/signkeys/$H_DENOM_PUB/revoke request.
+ */
+struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle;
+
+
+/**
+ * Inform the exchange that a signing key was revoked.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param exchange_pub the public signing key that was revoked
+ * @param master_sig signature affirming the revocation
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *
+TALER_EXCHANGE_management_revoke_signing_key (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementRevokeSigningKeyCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_revoke_signing_key() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_revoke_signing_key_cancel (
+ struct TALER_EXCHANGE_ManagementRevokeSigningKeyHandle *rh);
+
+
+/**
+ * Response from a POST /management/aml-officers request.
+ */
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse
+{
+ /**
+ * HTTP response data
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+};
+
+/**
+ * Function called with information about the change to
+ * an AML officer status.
+ *
+ * @param cls closure
+ * @param hr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *hr);
+
+
+/**
+ * @brief Handle for a POST /management/aml-officers/$OFFICER_PUB request.
+ */
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer;
+
+
+/**
+ * Inform the exchange that the status of an AML officer has changed.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param officer_pub the public signing key of the officer
+ * @param officer_name name of the officer
+ * @param change_date when to affect the status change
+ * @param is_active true to enable the officer
+ * @param read_only true to only allow read-only access
+ * @param master_sig signature affirming the change
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *
+TALER_EXCHANGE_management_update_aml_officer (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_AmlOfficerPublicKeyP *officer_pub,
+ const char *officer_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool is_active,
+ bool read_only,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_update_aml_officer() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_update_aml_officer_cancel (
+ struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *rh);
+
+
+/**
+ * Summary data about an AML decision.
+ */
+struct TALER_EXCHANGE_AmlDecisionSummary
+{
+ /**
+ * What is the current monthly threshold.
+ */
+ struct TALER_Amount threshold;
+
+ /**
+ * Account the decision was made for.
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ /**
+ * RowID of this decision.
+ */
+ uint64_t rowid;
+
+ /**
+ * Current decision state.
+ */
+ enum TALER_AmlDecisionState current_state;
+};
+
+
+/**
+ * Information about AML decisions returned by the exchange.
+ */
+struct TALER_EXCHANGE_AmlDecisionsResponse
+{
+ /**
+ * HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP response code.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success (#MHD_HTTP_OK).
+ */
+ struct
+ {
+
+ /**
+ * Array of AML decision summaries returned by the exchange.
+ */
+ const struct TALER_EXCHANGE_AmlDecisionSummary *decisions;
+
+ /**
+ * Length of the @e decisions array.
+ */
+ unsigned int decisions_length;
+
+ } ok;
+
+ } details;
+};
+
+
+/**
+ * Function called with summary information about
+ * AML decisions.
+ *
+ * @param cls closure
+ * @param adr response data
+ */
+typedef void
+(*TALER_EXCHANGE_LookupAmlDecisionsCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AmlDecisionsResponse *adr);
+
+
+/**
+ * @brief Handle for a POST /aml/$OFFICER_PUB/decisions/$STATUS request.
+ */
+struct TALER_EXCHANGE_LookupAmlDecisions;
+
+
+/**
+ * Inform the exchange that an AML decision has been taken.
+ *
+ * @param ctx the context
+ * @param exchange_url HTTP base URL for the exchange
+ * @param start row number starting point (exclusive rowid)
+ * @param delta number of records to return, negative for descending, positive for ascending from start
+ * @param state type of AML decisions to return
+ * @param officer_priv private key of the deciding AML officer
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_LookupAmlDecisions *
+TALER_EXCHANGE_lookup_aml_decisions (
+ struct GNUNET_CURL_Context *ctx,
+ const char *exchange_url,
+ uint64_t start,
+ int delta,
+ enum TALER_AmlDecisionState state,
+ const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+ TALER_EXCHANGE_LookupAmlDecisionsCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_lookup_aml_decisions() operation.
+ *
+ * @param lh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_lookup_aml_decisions_cancel (
+ struct TALER_EXCHANGE_LookupAmlDecisions *lh);
+
+
+/**
+ * Detailed data about an AML decision.
+ */
+struct TALER_EXCHANGE_AmlDecisionDetail
+{
+ /**
+ * When was the decision made.
+ */
+ struct GNUNET_TIME_Timestamp decision_time;
+
+ /**
+ * New threshold set by this decision.
+ */
+ struct TALER_Amount new_threshold;
+
+ /**
+ * Who made the decision?
+ */
+ struct TALER_AmlOfficerPublicKeyP decider_pub;
+
+ /**
+ * Justification given for the decision.
+ */
+ const char *justification;
+
+ /**
+ * New decision state.
+ */
+ enum TALER_AmlDecisionState new_state;
+};
+
+
+/**
+ * Detailed data collected during a KYC process for the account.
+ */
+struct TALER_EXCHANGE_KycHistoryDetail
+{
+ /**
+ * Configuration section name of the KYC provider that contributed the data.
+ */
+ const char *provider_section;
+
+ /**
+ * The collected KYC data.
+ */
+ const json_t *attributes;
+
+ /**
+ * When was the data collection made.
+ */
+ struct GNUNET_TIME_Timestamp collection_time;
+
+};
+
+
+/**
+ * Information about AML decision details returned by the exchange.
+ */
+struct TALER_EXCHANGE_AmlDecisionResponse
+{
+ /**
+ * HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP response code.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success (#MHD_HTTP_OK).
+ */
+ struct
+ {
+
+ /**
+ * Array of AML decision details returned by the exchange.
+ */
+ const struct TALER_EXCHANGE_AmlDecisionDetail *aml_history;
+
+ /**
+ * Length of the @e aml_history array.
+ */
+ unsigned int aml_history_length;
+
+ /**
+ * Array of KYC data collections returned by the exchange.
+ */
+ const struct TALER_EXCHANGE_KycHistoryDetail *kyc_attributes;
+
+ /**
+ * Length of the @e kyc_attributes array.
+ */
+ unsigned int kyc_attributes_length;
+
+ } ok;
+
+ } details;
+};
+
+
+/**
+ * Function called with summary information about
+ * AML decisions.
+ *
+ * @param cls closure
+ * @param adr response data
+ */
+typedef void
+(*TALER_EXCHANGE_LookupAmlDecisionCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AmlDecisionResponse *adr);
+
+
+/**
+ * @brief Handle for a POST /aml/$OFFICER_PUB/decision/$H_PAYTO request.
+ */
+struct TALER_EXCHANGE_LookupAmlDecision;
+
+
+/**
+ * Inform the exchange that an AML decision has been taken.
+ *
+ * @param ctx the context
+ * @param exchange_url HTTP base URL for the exchange
+ * @param h_payto which account to return the decision history for
+ * @param officer_priv private key of the deciding AML officer
+ * @param history true to return the full history, otherwise only the last decision
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_LookupAmlDecision *
+TALER_EXCHANGE_lookup_aml_decision (
+ struct GNUNET_CURL_Context *ctx,
+ const char *exchange_url,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+ bool history,
+ TALER_EXCHANGE_LookupAmlDecisionCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_lookup_aml_decision() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_lookup_aml_decision_cancel (
+ struct TALER_EXCHANGE_LookupAmlDecision *rh);
+
+
+/**
+ * @brief Handle for a POST /aml-decision/$OFFICER_PUB request.
+ */
+struct TALER_EXCHANGE_AddAmlDecision;
+
+
+/**
+ * Response when making an AML decision.
+ */
+struct TALER_EXCHANGE_AddAmlDecisionResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+
+/**
+ * Function called with information about storing an
+ * an AML decision.
+ *
+ * @param cls closure
+ * @param adr response data
+ */
+typedef void
+(*TALER_EXCHANGE_AddAmlDecisionCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AddAmlDecisionResponse *adr);
+
+/**
+ * Inform the exchange that an AML decision has been taken.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param justification human-readable justification
+ * @param decision_time when was the decision made
+ * @param new_threshold at what monthly amount threshold
+ * should a revision be triggered
+ * @param h_payto payto URI hash of the account the
+ * decision is about
+ * @param new_state updated AML state
+ * @param kyc_requirements JSON array of KYC requirements being imposed, NULL for none
+ * @param officer_priv private key of the deciding AML officer
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_AddAmlDecision *
+TALER_EXCHANGE_add_aml_decision (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const char *justification,
+ struct GNUNET_TIME_Timestamp decision_time,
+ const struct TALER_Amount *new_threshold,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState new_state,
+ const json_t *kyc_requirements,
+ const struct TALER_AmlOfficerPrivateKeyP *officer_priv,
+ TALER_EXCHANGE_AddAmlDecisionCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_add_aml_decision() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_add_aml_decision_cancel (
+ struct TALER_EXCHANGE_AddAmlDecision *rh);
+
+
+/**
+ * Response when adding a partner exchange.
+ */
+struct TALER_EXCHANGE_ManagementAddPartnerResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+/**
+ * Function called with information about the change to
+ * an AML officer status.
+ *
+ * @param cls closure
+ * @param apr response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementAddPartnerCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementAddPartnerResponse *apr);
+
+
+/**
+ * @brief Handle for a POST /management/partners/$PARTNER_PUB request.
+ */
+struct TALER_EXCHANGE_ManagementAddPartner;
+
+
+/**
+ * Inform the exchange that the status of a partnering
+ * exchange was defined.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param partner_pub the offline signing key of the partner
+ * @param start_date validity period start
+ * @param end_date validity period end
+ * @param wad_frequency how often will we do wad transfers to this partner
+ * @param wad_fee what is the wad fee to this partner
+ * @param partner_base_url what is the base URL of the @a partner_pub exchange
+ * @param master_sig the signature the signature
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementAddPartner *
+TALER_EXCHANGE_management_add_partner (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_MasterPublicKeyP *partner_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementAddPartnerCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_add_partner() operation.
+ *
+ * @param rh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_add_partner_cancel (
+ struct TALER_EXCHANGE_ManagementAddPartner *rh);
+
+
+/**
+ * Response when enabling an auditor.
+ */
+struct TALER_EXCHANGE_ManagementAuditorEnableResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+/**
+ * Function called with information about the auditor setup operation result.
+ *
+ * @param cls closure
+ * @param aer response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementAuditorEnableCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementAuditorEnableResponse *aer);
+
+
+/**
+ * @brief Handle for a POST /management/auditors request.
+ */
+struct TALER_EXCHANGE_ManagementAuditorEnableHandle;
+
+
+/**
+ * Inform the exchange that an auditor should be enable or enabled.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param auditor_pub the public signing key of the auditor
+ * @param auditor_url base URL of the auditor
+ * @param auditor_name human readable name for the auditor
+ * @param validity_start when was this decided?
+ * @param master_sig signature affirming the auditor addition
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementAuditorEnableHandle *
+TALER_EXCHANGE_management_enable_auditor (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp validity_start,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementAuditorEnableCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_enable_auditor() operation.
+ *
+ * @param ah handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_enable_auditor_cancel (
+ struct TALER_EXCHANGE_ManagementAuditorEnableHandle *ah);
+
+/**
+ * Response when disabling an auditor.
+ */
+struct TALER_EXCHANGE_ManagementAuditorDisableResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+/**
+ * Function called with information about the auditor disable operation result.
+ *
+ * @param cls closure
+ * @param adr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementAuditorDisableCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementAuditorDisableResponse *adr);
+
+
+/**
+ * @brief Handle for a POST /management/auditors/$AUDITOR_PUB/disable request.
+ */
+struct TALER_EXCHANGE_ManagementAuditorDisableHandle;
+
+
+/**
+ * Inform the exchange that an auditor should be disabled.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param auditor_pub the public signing key of the auditor
+ * @param validity_end when was this decided?
+ * @param master_sig signature affirming the auditor addition
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementAuditorDisableHandle *
+TALER_EXCHANGE_management_disable_auditor (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Timestamp validity_end,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementAuditorDisableCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_disable_auditor() operation.
+ *
+ * @param ah handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_disable_auditor_cancel (
+ struct TALER_EXCHANGE_ManagementAuditorDisableHandle *ah);
+
+
+/**
+ * Response from an exchange account/enable operation.
+ */
+struct TALER_EXCHANGE_ManagementWireEnableResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+
+/**
+ * Function called with information about the wire enable operation result.
+ *
+ * @param cls closure
+ * @param wer HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementWireEnableCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer);
+
+
+/**
+ * @brief Handle for a POST /management/wire request.
+ */
+struct TALER_EXCHANGE_ManagementWireEnableHandle;
+
+
+/**
+ * Inform the exchange that a wire account should be enabled.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param payto_uri RFC 8905 URI of the exchange's bank account
+ * @param conversion_url URL of the conversion service, or NULL if none
+ * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec
+ * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec
+ * @param validity_start when was this decided?
+ * @param master_sig1 signature affirming the wire addition
+ * of purpose #TALER_SIGNATURE_MASTER_ADD_WIRE
+ * @param master_sig2 signature affirming the validity of the account for clients;
+ * of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
+ * @param bank_label label to use when showing the account, can be NULL
+ * @param priority priority for ordering the bank accounts
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementWireEnableHandle *
+TALER_EXCHANGE_management_enable_wire (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ struct GNUNET_TIME_Timestamp validity_start,
+ const struct TALER_MasterSignatureP *master_sig1,
+ const struct TALER_MasterSignatureP *master_sig2,
+ const char *bank_label,
+ int64_t priority,
+ TALER_EXCHANGE_ManagementWireEnableCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_enable_wire() operation.
+ *
+ * @param wh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_enable_wire_cancel (
+ struct TALER_EXCHANGE_ManagementWireEnableHandle *wh);
+
+
+/**
+ * Response from an exchange account/disable operation.
+ */
+struct TALER_EXCHANGE_ManagementWireDisableResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+/**
+ * Function called with information about the wire disable operation result.
+ *
+ * @param cls closure
+ * @param wdr response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementWireDisableCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdr);
+
+
+/**
+ * @brief Handle for a POST /management/wire/disable request.
+ */
+struct TALER_EXCHANGE_ManagementWireDisableHandle;
+
+
+/**
+ * Inform the exchange that a wire account should be disabled.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param payto_uri RFC 8905 URI of the exchange's bank account
+ * @param validity_end when was this decided?
+ * @param master_sig signature affirming the wire addition
+ * of purpose #TALER_SIGNATURE_MASTER_DEL_WIRE
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementWireDisableHandle *
+TALER_EXCHANGE_management_disable_wire (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp validity_end,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementWireDisableCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_disable_wire() operation.
+ *
+ * @param wh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_disable_wire_cancel (
+ struct TALER_EXCHANGE_ManagementWireDisableHandle *wh);
+
+
+/**
+ * Response when setting wire fees.
+ */
+struct TALER_EXCHANGE_ManagementSetWireFeeResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+/**
+ * Function called with information about the wire enable operation result.
+ *
+ * @param cls closure
+ * @param wfr response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementSetWireFeeCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementSetWireFeeResponse *wfr);
+
+
+/**
+ * @brief Handle for a POST /management/wire-fees request.
+ */
+struct TALER_EXCHANGE_ManagementSetWireFeeHandle;
+
+
+/**
+ * Inform the exchange about future wire fees.
+ *
+ * @param ctx the context
+ * @param exchange_base_url HTTP base URL for the exchange
+ * @param wire_method for which wire method are fees provided
+ * @param validity_start start date for the provided wire fees
+ * @param validity_end end date for the provided wire fees
+ * @param fees the wire fees for this time period
+ * @param master_sig signature affirming the wire fees;
+ * of purpose #TALER_SIGNATURE_MASTER_WIRE_FEES
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementSetWireFeeHandle *
+TALER_EXCHANGE_management_set_wire_fees (
+ struct GNUNET_CURL_Context *ctx,
+ const char *exchange_base_url,
+ const char *wire_method,
+ struct GNUNET_TIME_Timestamp validity_start,
+ struct GNUNET_TIME_Timestamp validity_end,
+ const struct TALER_WireFeeSet *fees,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementSetWireFeeCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_enable_wire() operation.
+ *
+ * @param swfh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_set_wire_fees_cancel (
+ struct TALER_EXCHANGE_ManagementSetWireFeeHandle *swfh);
+
+
+/**
+ * Response when setting global fees.
+ */
+struct TALER_EXCHANGE_ManagementSetGlobalFeeResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+
+/**
+ * Function called with information about the global fee setting operation result.
+ *
+ * @param cls closure
+ * @param gfr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ManagementSetGlobalFeeCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ManagementSetGlobalFeeResponse *gfr);
+
+
+/**
+ * @brief Handle for a POST /management/global-fees request.
+ */
+struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle;
+
+
+/**
+ * Inform the exchange about global fees.
+ *
+ * @param ctx the context
+ * @param exchange_base_url HTTP base URL for the exchange
+ * @param validity_start start date for the provided wire fees
+ * @param validity_end end date for the provided wire fees
+ * @param fees the wire fees for this time period
+ * @param purse_timeout when do purses time out
+ * @param history_expiration how long are account histories preserved
+ * @param purse_account_limit how many purses are free per account
+ * @param master_sig signature affirming the wire fees;
+ * of purpose #TALER_SIGNATURE_MASTER_GLOBAL_FEES
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *
+TALER_EXCHANGE_management_set_global_fees (
+ struct GNUNET_CURL_Context *ctx,
+ const char *exchange_base_url,
+ struct GNUNET_TIME_Timestamp validity_start,
+ struct GNUNET_TIME_Timestamp validity_end,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ const struct TALER_MasterSignatureP *master_sig,
+ TALER_EXCHANGE_ManagementSetGlobalFeeCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_management_enable_wire() operation.
+ *
+ * @param sgfh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_management_set_global_fees_cancel (
+ struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle *sgfh);
+
+
+/**
+ * Response when adding denomination signature by auditor.
+ */
+struct TALER_EXCHANGE_AuditorAddDenominationResponse
+{
+ /**
+ * HTTP response data.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+
+/**
+ * Function called with information about the POST
+ * /auditor/$AUDITOR_PUB/$H_DENOM_PUB operation result.
+ *
+ * @param cls closure
+ * @param adr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_AuditorAddDenominationCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AuditorAddDenominationResponse *adr);
+
+
+/**
+ * @brief Handle for a POST /auditor/$AUDITOR_PUB/$H_DENOM_PUB request.
+ */
+struct TALER_EXCHANGE_AuditorAddDenominationHandle;
+
+
+/**
+ * Provide auditor signatures for a denomination to the exchange.
+ *
+ * @param ctx the context
+ * @param url HTTP base URL for the exchange
+ * @param h_denom_pub hash of the public key of the denomination
+ * @param auditor_pub public key of the auditor
+ * @param auditor_sig signature of the auditor, of
+ * purpose #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_AuditorAddDenominationHandle *
+TALER_EXCHANGE_add_auditor_denomination (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const struct TALER_AuditorSignatureP *auditor_sig,
+ TALER_EXCHANGE_AuditorAddDenominationCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_add_auditor_denomination() operation.
+ *
+ * @param ah handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_add_auditor_denomination_cancel (
+ struct TALER_EXCHANGE_AuditorAddDenominationHandle *ah);
+
+
+/* ********************* W2W API ****************** */
+
+
+/**
+ * Response generated for a contract get request.
+ */
+struct TALER_EXCHANGE_ContractGetResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP status code.
+ */
+ union
+ {
+ /**
+ * Information returned on #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * Public key of the purse.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Encrypted contract.
+ */
+ const void *econtract;
+
+ /**
+ * Number of bytes in @e econtract.
+ */
+ size_t econtract_size;
+
+ } ok;
+
+ } details;
+
+};
+
+/**
+ * Function called with information about the a purse.
+ *
+ * @param cls closure
+ * @param cgr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ContractGetCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ContractGetResponse *cgr);
+
+
+/**
+ * @brief Handle for a GET /contracts/$CPUB request.
+ */
+struct TALER_EXCHANGE_ContractsGetHandle;
+
+
+/**
+ * Request information about a contract from the exchange.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param contract_priv private key of the contract
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_ContractsGetHandle *
+TALER_EXCHANGE_contract_get (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ TALER_EXCHANGE_ContractGetCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_contract_get() operation.
+ *
+ * @param cgh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_contract_get_cancel (
+ struct TALER_EXCHANGE_ContractsGetHandle *cgh);
+
+
+/**
+ * Response generated for a purse get request.
+ */
+struct TALER_EXCHANGE_PurseGetResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Response on #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * Time when the purse was merged (or zero if it
+ * was not merged).
+ */
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+
+ /**
+ * Time when the full amount was deposited into
+ * the purse (or zero if a sufficient amount
+ * was not yet deposited).
+ */
+ struct GNUNET_TIME_Timestamp deposit_timestamp;
+
+ /**
+ * Reserve balance (how much was deposited in
+ * total into the reserve, minus deposit fees).
+ */
+ struct TALER_Amount balance;
+
+ /**
+ * Time when the purse will expire.
+ */
+ struct GNUNET_TIME_Timestamp purse_expiration;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Function called with information about the a purse.
+ *
+ * @param cls closure
+ * @param pgr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_PurseGetCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_PurseGetResponse *pgr);
+
+
+/**
+ * @brief Handle for a GET /purses/$PPUB request.
+ */
+struct TALER_EXCHANGE_PurseGetHandle;
+
+
+/**
+ * Request information about a purse from the exchange.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param purse_pub public key of the purse
+ * @param timeout how long to wait for a change to happen
+ * @param wait_for_merge true to wait for a merge event, otherwise wait for a deposit event
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_PurseGetHandle *
+TALER_EXCHANGE_purse_get (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Relative timeout,
+ bool wait_for_merge,
+ TALER_EXCHANGE_PurseGetCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_purse_get() operation.
+ *
+ * @param pgh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_purse_get_cancel (
+ struct TALER_EXCHANGE_PurseGetHandle *pgh);
+
+
+/**
+ * Response generated for a purse creation request.
+ */
+struct TALER_EXCHANGE_PurseCreateDepositResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP status.
+ */
+ union
+ {
+
+ /**
+ * Detailed returned on #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Signing key used by the exchange to sign the
+ * purse create with deposit confirmation.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * Signature from the exchange on the
+ * purse create with deposit confirmation.
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+
+
+ } ok;
+
+ } details;
+
+};
+
+/**
+ * Function called with information about the creation
+ * of a new purse.
+ *
+ * @param cls closure
+ * @param pcr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_PurseCreateDepositCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_PurseCreateDepositResponse *pcr);
+
+
+/**
+ * @brief Handle for a POST /purses/$PID/create request.
+ */
+struct TALER_EXCHANGE_PurseCreateDepositHandle;
+
+
+/**
+ * Information about a coin to be deposited into a purse or reserve.
+ */
+struct TALER_EXCHANGE_PurseDeposit
+{
+ /**
+ * Age commitment data, might be NULL.
+ */
+ const struct TALER_AgeCommitmentProof *age_commitment_proof;
+
+ /**
+ * Private key of the coin.
+ */
+ struct TALER_CoinSpendPrivateKeyP coin_priv;
+
+ /**
+ * Signature proving the validity of the coin.
+ */
+ struct TALER_DenominationSignature denom_sig;
+
+ /**
+ * Hash of the denomination's public key.
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
+ * Amount of the coin to transfer into the purse.
+ */
+ struct TALER_Amount amount;
+
+};
+
+
+/**
+ * Inform the exchange that a purse should be created
+ * and coins deposited into it.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param purse_priv private key of the purse
+ * @param merge_priv the merge credential
+ * @param contract_priv key needed to obtain and decrypt the contract
+ * @param contract_terms contract the purse is about
+ * @param num_deposits length of the @a deposits array
+ * @param deposits array of deposits to make into the purse
+ * @param upload_contract true to upload the contract; must
+ * be FALSE for repeated calls to this API for the
+ * same purse (i.e. when adding more deposits).
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_PurseCreateDepositHandle *
+TALER_EXCHANGE_purse_create_with_deposit (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ const struct TALER_PurseMergePrivateKeyP *merge_priv,
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const json_t *contract_terms,
+ unsigned int num_deposits,
+ const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
+ bool upload_contract,
+ TALER_EXCHANGE_PurseCreateDepositCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_purse_create_with_deposit() operation.
+ *
+ * @param pch handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_purse_create_with_deposit_cancel (
+ struct TALER_EXCHANGE_PurseCreateDepositHandle *pch);
+
+
+/**
+ * Response generated for a purse deletion request.
+ */
+struct TALER_EXCHANGE_PurseDeleteResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+};
+
+
+/**
+ * Function called with information about the deletion
+ * of a purse.
+ *
+ * @param cls closure
+ * @param pdr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_PurseDeleteCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_PurseDeleteResponse *pdr);
+
+
+/**
+ * @brief Handle for a DELETE /purses/$PID request.
+ */
+struct TALER_EXCHANGE_PurseDeleteHandle;
+
+
+/**
+ * Asks the exchange to delete a purse. Will only succeed if
+ * the purse was not yet merged and did not yet time out.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param purse_priv private key of the purse
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_PurseDeleteHandle *
+TALER_EXCHANGE_purse_delete (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ TALER_EXCHANGE_PurseDeleteCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_purse_delete() operation.
+ *
+ * @param pdh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_purse_delete_cancel (
+ struct TALER_EXCHANGE_PurseDeleteHandle *pdh);
+
+
+/**
+ * Response generated for an account merge request.
+ */
+struct TALER_EXCHANGE_AccountMergeResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Reserve signature affirming the merge.
+ */
+ const struct TALER_ReserveSignatureP *reserve_sig;
+
+ /**
+ * Details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Detailed returned on #MHD_HTTP_OK.
+ */
+ struct
+ {
+ /**
+ * Signature by the exchange affirming the merge.
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+
+ /**
+ * Online signing key used by the exchange.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * Timestamp of the exchange for @e exchange_sig.
+ */
+ struct GNUNET_TIME_Timestamp etime;
+
+ } ok;
+
+ /**
+ * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+ /**
+ * Requirement row target that the merchant should use
+ * to check for its KYC status.
+ */
+ uint64_t requirement_row;
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+/**
+ * Function called with information about an account merge
+ * operation.
+ *
+ * @param cls closure
+ * @param amr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_AccountMergeCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_AccountMergeResponse *amr);
+
+
+/**
+ * @brief Handle for a POST /purses/$PID/merge request.
+ */
+struct TALER_EXCHANGE_AccountMergeHandle;
+
+
+/**
+ * Inform the exchange that a purse should be merged
+ * with a reserve.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param reserve_exchange_url base URL of the exchange with the reserve
+ * @param reserve_priv private key of the reserve to merge into
+ * @param purse_pub public key of the purse to merge
+ * @param merge_priv private key granting us the right to merge
+ * @param h_contract_terms hash of the purses' contract
+ * @param min_age minimum age of deposits into the purse
+ * @param purse_value_after_fees amount that should be in the purse
+ * @param purse_expiration when will the purse expire
+ * @param merge_timestamp when is the merge happening (current time)
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_AccountMergeHandle *
+TALER_EXCHANGE_account_merge (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *reserve_exchange_url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergePrivateKeyP *merge_priv,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint8_t min_age,
+ const struct TALER_Amount *purse_value_after_fees,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ TALER_EXCHANGE_AccountMergeCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_account_merge() operation.
+ *
+ * @param amh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_account_merge_cancel (
+ struct TALER_EXCHANGE_AccountMergeHandle *amh);
+
+
+/**
+ * Response generated for a purse creation request.
+ */
+struct TALER_EXCHANGE_PurseCreateMergeResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Reserve signature generated for the request
+ * (client-side).
+ */
+ const struct TALER_ReserveSignatureP *reserve_sig;
+
+ /**
+ * Details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Details returned on #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ } ok;
+
+ /**
+ * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+ /**
+ * Requirement row that the merchant should use
+ * to check for its KYC status.
+ */
+ uint64_t requirement_row;
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+/**
+ * Function called with information about the creation
+ * of a new purse.
+ *
+ * @param cls closure
+ * @param pcr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_PurseCreateMergeCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_PurseCreateMergeResponse *pcr);
+
+
+/**
+ * @brief Handle for a POST /reserves/$RID/purse request.
+ */
+struct TALER_EXCHANGE_PurseCreateMergeHandle;
+
+
+/**
+ * Inform the exchange that a purse should be created
+ * and merged with a reserve.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param reserve_priv private key of the reserve
+ * @param purse_priv private key of the purse
+ * @param merge_priv private key of the merge capability
+ * @param contract_priv private key to get the contract
+ * @param contract_terms contract the purse is about
+ * @param upload_contract true to upload the contract
+ * @param pay_for_purse true to pay for purse creation
+ * @param merge_timestamp when should the merge happen (use current time)
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_PurseCreateMergeHandle *
+TALER_EXCHANGE_purse_create_with_merge (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_PurseContractPrivateKeyP *purse_priv,
+ const struct TALER_PurseMergePrivateKeyP *merge_priv,
+ const struct TALER_ContractDiffiePrivateP *contract_priv,
+ const json_t *contract_terms,
+ bool upload_contract,
+ bool pay_for_purse,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ TALER_EXCHANGE_PurseCreateMergeCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_purse_create_with_merge() operation.
+ *
+ * @param pcm handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_purse_create_with_merge_cancel (
+ struct TALER_EXCHANGE_PurseCreateMergeHandle *pcm);
+
+
+/**
+ * Response generated for purse deposit request.
+ */
+struct TALER_EXCHANGE_PurseDepositResponse
+{
+ /**
+ * Full HTTP response.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on the HTTP status.
+ */
+ union
+ {
+ /**
+ * Detailed returned on #MHD_HTTP_OK.
+ */
+ struct
+ {
+
+ /**
+ * When does the purse expire.
+ */
+ struct GNUNET_TIME_Timestamp purse_expiration;
+
+ /**
+ * How much was actually deposited into the purse.
+ */
+ struct TALER_Amount total_deposited;
+
+ /**
+ * How much should be in the purse in total in the end.
+ */
+ struct TALER_Amount purse_value_after_fees;
+
+ /**
+ * Hash of the contract (needed to verify signature).
+ */
+ struct TALER_PrivateContractHashP h_contract_terms;
+
+ } ok;
+ } details;
+
+};
+
+/**
+ * Function called with information about a purse-deposit
+ * operation.
+ *
+ * @param cls closure
+ * @param pdr HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_PurseDepositCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_PurseDepositResponse *pdr);
+
+
+/**
+ * @brief Handle for a POST /purses/$PID/deposit request.
+ */
+struct TALER_EXCHANGE_PurseDepositHandle;
+
+
+/**
+ * Inform the exchange that a deposit should be made into
+ * a purse.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param purse_exchange_url base URL of the exchange hosting the purse
+ * @param purse_pub public key of the purse to merge
+ * @param min_age minimum age we need to prove for the purse
+ * @param num_deposits length of the @a deposits array
+ * @param deposits array of deposits to make into the purse
+ * @param cb function to call with the exchange's result
+ * @param cb_cls closure for @a cb
+ * @return the request handle; NULL upon error
+ */
+struct TALER_EXCHANGE_PurseDepositHandle *
+TALER_EXCHANGE_purse_deposit (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const char *purse_exchange_url,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ uint8_t min_age,
+ unsigned int num_deposits,
+ const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits],
+ TALER_EXCHANGE_PurseDepositCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel #TALER_EXCHANGE_purse_deposit() operation.
+ *
+ * @param amh handle of the operation to cancel
+ */
+void
+TALER_EXCHANGE_purse_deposit_cancel (
+ struct TALER_EXCHANGE_PurseDepositHandle *amh);
+
+
+/* ********************* /reserves/$RID/open *********************** */
+
+
+/**
+ * @brief A /reserves/$RID/open Handle
+ */
+struct TALER_EXCHANGE_ReservesOpenHandle;
+
+
+/**
+ * @brief Reserve open result details.
+ */
+struct TALER_EXCHANGE_ReserveOpenResult
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+ /**
+ * New expiration time
+ */
+ struct GNUNET_TIME_Timestamp expiration_time;
+
+ /**
+ * Actual cost of the open operation.
+ */
+ struct TALER_Amount open_cost;
+
+ } ok;
+
+
+ /**
+ * Information returned if the payment provided is insufficient, if
+ * @e hr.http_status is #MHD_HTTP_PAYMENT_REQUIRED
+ */
+ struct
+ {
+ /**
+ * Current expiration time of the reserve.
+ */
+ struct GNUNET_TIME_Timestamp expiration_time;
+
+ /**
+ * Actual cost of the open operation that should have been paid.
+ */
+ struct TALER_Amount open_cost;
+
+ } payment_required;
+
+ /**
+ * Information returned if status is
+ * #MHD_HTTP_CONFLICT.
+ */
+ struct
+ {
+ /**
+ * Public key of the coin that caused the conflict.
+ */
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+
+ } conflict;
+
+ /**
+ * Information returned if KYC is required to proceed, set if
+ * @e hr.http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+ /**
+ * Requirement row that the merchant should use
+ * to check for its KYC status.
+ */
+ uint64_t requirement_row;
+
+ /**
+ * Hash of the payto-URI of the account to KYC;
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve open request to a exchange.
+ *
+ * @param cls closure
+ * @param ror HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ReservesOpenCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ReserveOpenResult *ror);
+
+
+/**
+ * Submit a request to open a reserve.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param keys exchange keys
+ * @param reserve_priv private key of the reserve to open
+ * @param reserve_contribution amount to pay from the reserve's balance for the operation
+ * @param coin_payments_length length of the @a coin_payments array
+ * @param coin_payments array of coin payments to use for opening the reserve
+ * @param expiration_time desired new expiration time for the reserve
+ * @param min_purses minimum number of purses to allow being concurrently opened per reserve
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ * signatures fail to verify). In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_ReservesOpenHandle *
+TALER_EXCHANGE_reserves_open (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const struct TALER_Amount *reserve_contribution,
+ unsigned int coin_payments_length,
+ const struct TALER_EXCHANGE_PurseDeposit coin_payments[
+ static coin_payments_length],
+ struct GNUNET_TIME_Timestamp expiration_time,
+ uint32_t min_purses,
+ TALER_EXCHANGE_ReservesOpenCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel a reserve status request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param[in] roh the reserve open request handle
+ */
+void
+TALER_EXCHANGE_reserves_open_cancel (
+ struct TALER_EXCHANGE_ReservesOpenHandle *roh);
+
+
+/* ********************* /reserves/$RID/attest *********************** */
+
+
+/**
+ * @brief A Get /reserves/$RID/attest Handle
+ */
+struct TALER_EXCHANGE_ReservesGetAttestHandle;
+
+
+/**
+ * @brief Reserve GET attest result details.
+ */
+struct TALER_EXCHANGE_ReserveGetAttestResult
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * Length of the @e attributes array.
+ */
+ unsigned int attributes_length;
+
+ /**
+ * Array of attributes available about the user.
+ */
+ const char **attributes;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve attest request to a exchange.
+ *
+ * @param cls closure
+ * @param ror HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ReservesGetAttestCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ReserveGetAttestResult *ror);
+
+
+/**
+ * Submit a request to get the list of attestable attributes for a reserve.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param reserve_pub public key of the reserve to get available attributes for
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ * signatures fail to verify). In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_ReservesGetAttestHandle *
+TALER_EXCHANGE_reserves_get_attestable (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ TALER_EXCHANGE_ReservesGetAttestCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel a request to get attestable attributes. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param rgah the reserve get attestable request handle
+ */
+void
+TALER_EXCHANGE_reserves_get_attestable_cancel (
+ struct TALER_EXCHANGE_ReservesGetAttestHandle *rgah);
+
+
+/**
+ * @brief A POST /reserves/$RID/attest Handle
+ */
+struct TALER_EXCHANGE_ReservesPostAttestHandle;
+
+
+/**
+ * @brief Reserve attest result details.
+ */
+struct TALER_EXCHANGE_ReservePostAttestResult
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+ /**
+ * Time when the exchange made the signature.
+ */
+ struct GNUNET_TIME_Timestamp exchange_time;
+
+ /**
+ * Expiration time of the attested attributes.
+ */
+ struct GNUNET_TIME_Timestamp expiration_time;
+
+ /**
+ * Signature by the exchange affirming the attributes.
+ */
+ struct TALER_ExchangeSignatureP exchange_sig;
+
+ /**
+ * Online signing key used by the exchange.
+ */
+ struct TALER_ExchangePublicKeyP exchange_pub;
+
+ /**
+ * Attributes being confirmed by the exchange.
+ */
+ const json_t *attributes;
+
+ } ok;
+
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve attest request to a exchange.
+ *
+ * @param cls closure
+ * @param ror HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ReservesPostAttestCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ReservePostAttestResult *ror);
+
+
+/**
+ * Submit a request to attest attributes about the owner of a reserve.
+ *
+ * @param ctx CURL context
+ * @param url exchange base URL
+ * @param keys exchange key data
+ * @param reserve_priv private key of the reserve to attest
+ * @param attributes_length length of the @a attributes array
+ * @param attributes array of names of attributes to get attestations for
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ * signatures fail to verify). In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_ReservesAttestHandle *
+TALER_EXCHANGE_reserves_attest (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ unsigned int attributes_length,
+ const char *attributes[const static attributes_length],
+ TALER_EXCHANGE_ReservesPostAttestCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel a reserve attestation request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param rah the reserve attest request handle
+ */
+void
+TALER_EXCHANGE_reserves_attest_cancel (
+ struct TALER_EXCHANGE_ReservesAttestHandle *rah);
+
+
+/* ********************* /reserves/$RID/close *********************** */
+
+
+/**
+ * @brief A /reserves/$RID/close Handle
+ */
+struct TALER_EXCHANGE_ReservesCloseHandle;
+
+
+/**
+ * @brief Reserve close result details.
+ */
+struct TALER_EXCHANGE_ReserveCloseResult
+{
+
+ /**
+ * High-level HTTP response details.
+ */
+ struct TALER_EXCHANGE_HttpResponse hr;
+
+ /**
+ * Details depending on @e hr.http_status.
+ */
+ union
+ {
+
+ /**
+ * Information returned on success, if
+ * @e hr.http_status is #MHD_HTTP_OK
+ */
+ struct
+ {
+
+ /**
+ * Amount wired to the target account.
+ */
+ struct TALER_Amount wire_amount;
+ } ok;
+
+ /**
+ * Information returned if KYC is required to proceed, set if
+ * @e hr.http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS.
+ */
+ struct
+ {
+ /**
+ * Requirement row that the merchant should use
+ * to check for its KYC status.
+ */
+ uint64_t requirement_row;
+
+ /**
+ * Hash of the payto-URI of the account to KYC;
+ */
+ struct TALER_PaytoHashP h_payto;
+
+ } unavailable_for_legal_reasons;
+
+ } details;
+
+};
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve close request to a exchange.
+ *
+ * @param cls closure
+ * @param ror HTTP response data
+ */
+typedef void
+(*TALER_EXCHANGE_ReservesCloseCallback) (
+ void *cls,
+ const struct TALER_EXCHANGE_ReserveCloseResult *ror);
+
+
+/**
+ * Submit a request to close a reserve.
+ *
+ * @param ctx curl context
+ * @param url exchange base URL
+ * @param reserve_priv private key of the reserve to close
+ * @param target_payto_uri where to send the payment, NULL to send to reserve origin
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for the above callback
+ * @return a handle for this request; NULL if the inputs are invalid (i.e.
+ * signatures fail to verify). In this case, the callback is not called.
+ */
+struct TALER_EXCHANGE_ReservesCloseHandle *
+TALER_EXCHANGE_reserves_close (
+ struct GNUNET_CURL_Context *ctx,
+ const char *url,
+ const struct TALER_ReservePrivateKeyP *reserve_priv,
+ const char *target_payto_uri,
+ TALER_EXCHANGE_ReservesCloseCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Cancel a reserve status request. This function cannot be used
+ * on a request handle if a response is already served for it.
+ *
+ * @param rch the reserve request handle
+ */
+void
+TALER_EXCHANGE_reserves_close_cancel (
+ struct TALER_EXCHANGE_ReservesCloseHandle *rch);
#endif /* _TALER_EXCHANGE_SERVICE_H */
diff --git a/src/include/taler_exchangedb_lib.h b/src/include/taler_exchangedb_lib.h
index 33ead98bb..d93cf9d6c 100644
--- a/src/include/taler_exchangedb_lib.h
+++ b/src/include/taler_exchangedb_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2017 Taler Systems SA
+ Copyright (C) 2014-2020 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -27,250 +27,6 @@
#include "taler_exchangedb_plugin.h"
#include "taler_bank_service.h"
-/**
- * Subdirectroy under the exchange's base directory which contains
- * the exchange's signing keys.
- */
-#define TALER_EXCHANGEDB_DIR_SIGNING_KEYS "signkeys"
-
-/**
- * Subdirectory under the exchange's base directory which contains
- * the exchange's denomination keys.
- */
-#define TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS "denomkeys"
-
-
-/**
- * @brief Iterator over signing keys.
- *
- * @param cls closure
- * @param filename name of the file the key came from
- * @param ski the sign key
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-typedef int
-(*TALER_EXCHANGEDB_SigningKeyIterator)(
- void *cls,
- const char *filename,
- const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski);
-
-
-/**
- * Call @a it for each signing key found in the @a exchange_base_dir.
- *
- * @param exchange_base_dir base directory for the exchange,
- * the signing keys must be in the #TALER_EXCHANGEDB_DIR_SIGNING_KEYS
- * subdirectory
- * @param it function to call on each signing key
- * @param it_cls closure for @a it
- * @return number of files found (may not match
- * number of keys given to @a it as malformed
- * files are simply skipped), -1 on error
- */
-int
-TALER_EXCHANGEDB_signing_keys_iterate (const char *exchange_base_dir,
- TALER_EXCHANGEDB_SigningKeyIterator it,
- void *it_cls);
-
-
-/**
- * Exports a signing key to the given file.
- *
- * @param exchange_base_dir base directory for the keys
- * @param start start time of the validity for the key
- * @param ski the signing key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_signing_key_write (
- const char *exchange_base_dir,
- struct GNUNET_TIME_Absolute start,
- const struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP *ski);
-
-
-/**
- * @brief Iterator over denomination keys.
- *
- * @param cls closure
- * @param alias coin alias
- * @param dki the denomination key
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-typedef int
-(*TALER_EXCHANGEDB_DenominationKeyIterator)(
- void *cls,
- const char *alias,
- const struct TALER_EXCHANGEDB_DenominationKey *dki);
-
-
-/**
- * @brief Iterator over revoked denomination keys.
- *
- * @param cls closure
- * @param denom_hash hash of the denomination public key
- * @param revocation_master_sig signature showing @a denom_hash was revoked
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-typedef int
-(*TALER_EXCHANGEDB_RevocationIterator)(
- void *cls,
- const struct GNUNET_HashCode *denom_hash,
- const struct TALER_MasterSignatureP *revocation_master_sig);
-
-
-/**
- * Call @a it for each denomination key found in the @a exchange_base_dir.
- *
- * @param exchange_base_dir base directory for the exchange,
- * the signing keys must be in the #TALER_EXCHANGEDB_DIR_DENOMINATION_KEYS
- * subdirectory
- * @param it function to call on each denomination key found
- * @param it_cls closure for @a it
- * @return -1 on error, 0 if no files were found, otherwise
- * a positive number (however, even with a positive
- * number it is possible that @a it was never called
- * as maybe none of the files were well-formed)
- */
-int
-TALER_EXCHANGEDB_denomination_keys_iterate (
- const char *exchange_base_dir,
- TALER_EXCHANGEDB_DenominationKeyIterator it,
- void *it_cls);
-
-
-/**
- * Call @a it for each revoked denomination key found in the @a revocation_dir.
- *
- * @param revocation_dir base directory where revocations are stored
- * @param master_pub master public key (used to check revocations)
- * @param it function to call on each revoked denomination key found
- * @param it_cls closure for @a it
- * @return -1 on error, 0 if no files were found, otherwise
- * a positive number (however, even with a positive
- * number it is possible that @a it was never called
- * as maybe none of the files were well-formed)
- */
-int
-TALER_EXCHANGEDB_revocations_iterate (
- const char *revocation_dir,
- const struct TALER_MasterPublicKeyP *master_pub,
- TALER_EXCHANGEDB_RevocationIterator it,
- void *it_cls);
-
-
-/**
- * Mark the given denomination key as revoked and request the wallets
- * to initiate recoup.
- *
- * @param revocation_dir where to write the revocation certificate
- * @param denom_hash hash of the denomination key to revoke
- * @param mpriv master private key to sign with
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_denomination_key_revoke (
- const char *revocation_dir,
- const struct GNUNET_HashCode *denom_hash,
- const struct TALER_MasterPrivateKeyP *mpriv);
-
-
-/**
- * Exports a denomination key to the given file.
- *
- * @param filename the file where to write the denomination key
- * @param dki the denomination key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_denomination_key_write (
- const char *filename,
- const struct TALER_EXCHANGEDB_DenominationKey *dki);
-
-
-/**
- * Import a denomination key from the given file.
- *
- * @param filename the file to import the key from
- * @param[out] dki set to the imported denomination key
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
- */
-int
-TALER_EXCHANGEDB_denomination_key_read (
- const char *filename,
- struct TALER_EXCHANGEDB_DenominationKey *dki);
-
-
-/**
- * @brief Iterator over auditor information.
- *
- * @param cls closure
- * @param apub the auditor's public key
- * @param auditor_url URL of the auditor
- * @param mpub the exchange's public key (as expected by the auditor)
- * @param dki_len length of @a asig and @a dki arrays
- * @param asigs array of the auditor's signatures over the @a dks, of length @a dki_len
- * @param dki array of denomination coin data signed by the auditor, of length @a dki_len
- * @return #GNUNET_OK to continue to iterate,
- * #GNUNET_NO to stop iteration with no error,
- * #GNUNET_SYSERR to abort iteration with error!
- */
-typedef int
-(*TALER_EXCHANGEDB_AuditorIterator)(
- void *cls,
- const struct TALER_AuditorPublicKeyP *apub,
- const char *auditor_url,
- const struct TALER_MasterPublicKeyP *mpub,
- unsigned int dki_len,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_DenominationKeyValidityPS *dki);
-
-
-/**
- * Call @a it with information for each auditor found in the
- * directory with auditor information as specified in @a cfg.
- *
- * @param cfg configuration to use
- * @param it function to call with auditor information
- * @param it_cls closure for @a it
- * @return -1 on error, 0 if no files were found, otherwise
- * a positive number (however, even with a positive
- * number it is possible that @a it was never called
- * as maybe none of the files were well-formed)
- */
-int
-TALER_EXCHANGEDB_auditor_iterate (const struct GNUNET_CONFIGURATION_Handle *cfg,
- TALER_EXCHANGEDB_AuditorIterator it,
- void *it_cls);
-
-
-/**
- * Write auditor information to the given file.
- *
- * @param filename the file where to write the auditor information to
- * @param apub the auditor's public key
- * @param auditor_url the URL of the auditor
- * @param asigs the auditor's signatures, array of length @a dki_len
- * @param mpub the exchange's public key (as expected by the auditor)
- * @param dki_len length of @a dki and @a asigs arrays
- * @param dki array of denomination coin data signed by the auditor
- * @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure.
- */
-int
-TALER_EXCHANGEDB_auditor_write (
- const char *filename,
- const struct TALER_AuditorPublicKeyP *apub,
- const char *auditor_url,
- const struct TALER_AuditorSignatureP *asigs,
- const struct TALER_MasterPublicKeyP *mpub,
- uint32_t dki_len,
- const struct TALER_DenominationKeyValidityPS *dki);
-
/**
* Initialize the plugin.
@@ -290,99 +46,17 @@ TALER_EXCHANGEDB_plugin_load (const struct GNUNET_CONFIGURATION_Handle *cfg);
void
TALER_EXCHANGEDB_plugin_unload (struct TALER_EXCHANGEDB_Plugin *plugin);
-
/**
- * Sorted list of fees to be paid for aggregate wire transfers.
- * Sorted by @e start_date or @e end_date --- both work fine as
- * the resulting order must be the same.
+ * Information about an account from the configuration.
*/
-struct TALER_EXCHANGEDB_AggregateFees
+struct TALER_EXCHANGEDB_AccountInfo
{
/**
- * This is a linked list.
+ * Authentication data. Only parsed if
+ * #TALER_EXCHANGEDB_ALO_AUTHDATA was set.
*/
- struct TALER_EXCHANGEDB_AggregateFees *next;
-
- /**
- * Fee to be paid for wire transfers to a merchant.
- */
- struct TALER_Amount wire_fee;
-
- /**
- * Fee to be paid when we close a reserve and send funds back.
- */
- struct TALER_Amount closing_fee;
-
- /**
- * Time when this fee goes into effect (inclusive)
- */
- struct GNUNET_TIME_Absolute start_date;
-
- /**
- * Time when this fee stops being in effect (exclusive).
- */
- struct GNUNET_TIME_Absolute end_date;
-
- /**
- * Signature affirming the above fee structure.
- */
- struct TALER_MasterSignatureP master_sig;
-};
-
-
-/**
- * Read the current fee structure from disk.
- *
- * @param cfg configuration to use
- * @param wireplugin name of the wire plugin to read fees for
- * @return sorted list of aggregation fees, NULL on error
- */
-struct TALER_EXCHANGEDB_AggregateFees *
-TALER_EXCHANGEDB_fees_read (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const char *wireplugin);
-
-
-/**
- * Convert @a af to @a wf.
- *
- * @param wiremethod name of the wire method the fees are for
- * @param[in,out] af aggregate fees, host format (updated to round time)
- * @param[out] wf aggregate fees, disk / signature format
- */
-void
-TALER_EXCHANGEDB_fees_2_wf (const char *wiremethod,
- struct TALER_EXCHANGEDB_AggregateFees *af,
- struct TALER_MasterWireFeePS *wf);
-
-
-/**
- * Write given fee structure to disk.
- *
- * @param filename where to write the fees
- * @param wireplugin name of the plugin for which we write the fees
- * @param af fee structure to write
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-int
-TALER_EXCHANGEDB_fees_write (const char *filename,
- const char *wireplugin,
- struct TALER_EXCHANGEDB_AggregateFees *af);
-
-
-/**
- * Free @a af data structure
- *
- * @param af list to free
- */
-void
-TALER_EXCHANGEDB_fees_free (struct TALER_EXCHANGEDB_AggregateFees *af);
+ const struct TALER_BANK_AuthenticationData *auth;
-
-/**
- * Information about an account from the configuration.
- */
-struct TALER_EXCHANGEDB_AccountInfo
-{
/**
* Section in the configuration file that specifies the
* account. Must start with "exchange-account-".
@@ -395,57 +69,22 @@ struct TALER_EXCHANGEDB_AccountInfo
const char *method;
/**
- * payto://-URL of the account.
- */
- const char *payto_uri;
-
- /**
- * Filename containing the signed /wire response, or NULL
- * if not given.
- */
- const char *wire_response_filename;
-
- /**
- * #GNUNET_YES if this account is enabed to be debited
+ * true if this account is enabled to be debited
* by the taler-exchange-aggregator.
*/
- int debit_enabled;
+ bool debit_enabled;
/**
- * #GNUNET_YES if this account is enabed to be credited by wallets
+ * true if this account is enabled to be credited by wallets
* and needs to be watched by the taler-exchange-wirewatch.
* Also, the account will only be included in /wire if credit
* is enabled.
*/
- int credit_enabled;
+ bool credit_enabled;
};
/**
- * Function called with information about a wire account.
- *
- * @param cls closure
- * @param ai account information
- */
-typedef void
-(*TALER_EXCHANGEDB_AccountCallback)(
- void *cls,
- const struct TALER_EXCHANGEDB_AccountInfo *ai);
-
-/**
- * Parse the configuration to find account information.
- *
- * @param cfg configuration to use
- * @param cb callback to invoke
- * @param cb_cls closure for @a cb
- */
-void
-TALER_EXCHANGEDB_find_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg,
- TALER_EXCHANGEDB_AccountCallback cb,
- void *cb_cls);
-
-
-/**
* Calculate the total value of all transactions performed.
* Stores @a off plus the cost of all transactions in @a tl
* in @a ret.
@@ -455,69 +94,35 @@ TALER_EXCHANGEDB_find_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg,
* @param[out] ret where the resulting total is to be stored
* @return #GNUNET_OK on success, #GNUNET_SYSERR on errors
*/
-int
+enum GNUNET_GenericReturnValue
TALER_EXCHANGEDB_calculate_transaction_list_totals (
struct TALER_EXCHANGEDB_TransactionList *tl,
const struct TALER_Amount *off,
struct TALER_Amount *ret);
-/* ***************** convenience functions ******** */
-
/**
- * Information we keep for each supported account of the exchange.
+ * Function called with information about a wire account.
+ *
+ * @param cls closure
+ * @param ai account information
*/
-struct TALER_EXCHANGEDB_WireAccount
-{
- /**
- * Accounts are kept in a DLL.
- */
- struct TALER_EXCHANGEDB_WireAccount *next;
-
- /**
- * Plugins are kept in a DLL.
- */
- struct TALER_EXCHANGEDB_WireAccount *prev;
-
- /**
- * Authentication data.
- */
- struct TALER_BANK_AuthenticationData auth;
-
- /**
- * Wire transfer fee structure.
- */
- struct TALER_EXCHANGEDB_AggregateFees *af;
-
- /**
- * Name of the section that configures this account.
- */
- char *section_name;
-
- /**
- * Name of the wire method underlying the account.
- */
- char *method;
-
-};
+typedef void
+(*TALER_EXCHANGEDB_AccountCallback)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_AccountInfo *ai);
/**
- * Update wire transfer fee data structure in @a wa.
+ * Return information about all accounts that
+ * were loaded by #TALER_EXCHANGEDB_load_accounts().
*
- * @param cfg configuration to use
- * @param db_plugin database plugin to use
- * @param wa wire account data structure to update
- * @param now timestamp to update fees to
- * @param session DB session to use
- * @return fee valid at @a now, or NULL if unknown
+ * @param cb callback to invoke
+ * @param cb_cls closure for @a cb
*/
-struct TALER_EXCHANGEDB_AggregateFees *
-TALER_EXCHANGEDB_update_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct TALER_EXCHANGEDB_Plugin *db_plugin,
- struct TALER_EXCHANGEDB_WireAccount *wa,
- struct GNUNET_TIME_Absolute now,
- struct TALER_EXCHANGEDB_Session *session);
+void
+TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
+ void *cb_cls);
/**
@@ -528,7 +133,7 @@ TALER_EXCHANGEDB_update_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
* @param method wire method we need an account for
* @return NULL on error
*/
-struct TALER_EXCHANGEDB_WireAccount *
+const struct TALER_EXCHANGEDB_AccountInfo *
TALER_EXCHANGEDB_find_account_by_method (const char *method);
@@ -540,19 +145,48 @@ TALER_EXCHANGEDB_find_account_by_method (const char *method);
* @param url wire address we need an account for
* @return NULL on error
*/
-struct TALER_EXCHANGEDB_WireAccount *
+const struct TALER_EXCHANGEDB_AccountInfo *
TALER_EXCHANGEDB_find_account_by_payto_uri (const char *url);
/**
+ * Options for #TALER_EXCHANGEDB_load_accounts()
+ */
+enum TALER_EXCHANGEDB_AccountLoaderOptions
+{
+ TALER_EXCHANGEDB_ALO_NONE = 0,
+
+ /**
+ * Load accounts enabled for DEBITs.
+ */
+ TALER_EXCHANGEDB_ALO_DEBIT = 1,
+
+ /**
+ * Load accounts enabled for CREDITs.
+ */
+ TALER_EXCHANGEDB_ALO_CREDIT = 2,
+
+ /**
+ * Load authentication data from the
+ * "taler-accountcredentials-" section
+ * to access the account at the bank.
+ */
+ TALER_EXCHANGEDB_ALO_AUTHDATA = 4
+};
+
+
+/**
* Load account information opf the exchange from
* @a cfg.
*
* @param cfg configuration to load from
+ * @param options loader options
* @return #GNUNET_OK on success, #GNUNET_NO if no accounts are configured
*/
-int
-TALER_EXCHANGEDB_load_accounts (const struct GNUNET_CONFIGURATION_Handle *cfg);
+enum GNUNET_GenericReturnValue
+TALER_EXCHANGEDB_load_accounts (
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ enum TALER_EXCHANGEDB_AccountLoaderOptions options);
/**
diff --git a/src/include/taler_exchangedb_plugin.h b/src/include/taler_exchangedb_plugin.h
index 4fd580724..2d5857677 100644
--- a/src/include/taler_exchangedb_plugin.h
+++ b/src/include/taler_exchangedb_plugin.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2020 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -18,47 +18,89 @@
* @brief Low-level (statement-level) database access for the exchange
* @author Florian Dold
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#ifndef TALER_EXCHANGEDB_PLUGIN_H
#define TALER_EXCHANGEDB_PLUGIN_H
#include <jansson.h>
#include <gnunet/gnunet_util_lib.h>
#include <gnunet/gnunet_db_lib.h>
+#include "taler_json_lib.h"
#include "taler_signatures.h"
+#include "taler_extensions_policy.h"
+/**
+ * The conflict that can occur for the age restriction
+ */
+enum TALER_EXCHANGEDB_AgeCommitmentHash_Conflict
+{
+ /**
+ * Value OK, no conflict
+ */
+ TALER_AgeCommitmentHash_NoConflict = 0,
-GNUNET_NETWORK_STRUCT_BEGIN
+ /**
+ * Given hash had a value, but NULL (or zero) was expected
+ */
+ TALER_AgeCommitmentHash_NullExpected = 1,
+
+ /**
+ * Given hash was NULL, but value was expected
+ */
+ TALER_AgeCommitmentHash_ValueExpected = 2,
+
+ /**
+ * Given hash differs from value in the known coin
+ */
+ TALER_AgeCommitmentHash_ValueDiffers = 3,
+};
/**
- * @brief On disk format used for a exchange signing key. Signing keys are used
- * by the exchange to affirm its messages, but not to create coins.
- * Includes the private key followed by the public information about
- * the signing key.
+ * Per-coin information returned when doing a batch insert.
*/
-struct TALER_EXCHANGEDB_PrivateSigningKeyInformationP
+struct TALER_EXCHANGEDB_CoinInfo
{
/**
- * Private key part of the exchange's signing key.
+ * Row of the coin in the known_coins table.
+ */
+ uint64_t known_coin_id;
+
+ /**
+ * Hash of the denomination, relevant on @e denom_conflict.
*/
- struct TALER_ExchangePrivateKeyP signkey_priv;
+ struct TALER_DenominationHashP denom_hash;
/**
- * Signature over @e issue
+ * Hash of the age commitment, relevant on @e age_conflict.
*/
- struct TALER_MasterSignatureP master_sig;
+ struct TALER_AgeCommitmentHash h_age_commitment;
/**
- * Public information about a exchange signing key.
+ * True if the coin was known previously.
*/
- struct TALER_ExchangeSigningKeyValidityPS issue;
+ bool existed;
+ /**
+ * True if the known coin has a different denomination;
+ * application will find denomination of the already
+ * known coin in @e denom_hash.
+ */
+ bool denom_conflict;
+
+ /**
+ * Indicates if and what kind of conflict with the age
+ * restriction of the known coin was present;
+ * application will find age commitment of the already
+ * known coin in @e h_age_commitment.
+ */
+ enum TALER_EXCHANGEDB_AgeCommitmentHash_Conflict age_conflict;
};
/**
* Information about a denomination key.
*/
-struct TALER_EXCHANGEDB_DenominationKeyInformationP
+struct TALER_EXCHANGEDB_DenominationKeyInformation
{
/**
@@ -67,14 +109,732 @@ struct TALER_EXCHANGEDB_DenominationKeyInformationP
struct TALER_MasterSignatureP signature;
/**
- * Signed properties of the denomination key.
+ * Start time of the validity period for this key.
+ */
+ struct GNUNET_TIME_Timestamp start;
+
+ /**
+ * The exchange will sign fresh coins between @e start and this time.
+ * @e expire_withdraw will be somewhat larger than @e start to
+ * ensure a sufficiently large anonymity set, while also allowing
+ * the Exchange to limit the financial damage in case of a key being
+ * compromised. Thus, exchanges with low volume are expected to have a
+ * longer withdraw period (@e expire_withdraw - @e start) than exchanges
+ * with high transaction volume. The period may also differ between
+ * types of coins. A exchange may also have a few denomination keys
+ * with the same value with overlapping validity periods, to address
+ * issues such as clock skew.
+ */
+ struct GNUNET_TIME_Timestamp expire_withdraw;
+
+ /**
+ * Coins signed with the denomination key must be spent or refreshed
+ * between @e start and this expiration time. After this time, the
+ * exchange will refuse transactions involving this key as it will
+ * "drop" the table with double-spending information (shortly after)
+ * this time. Note that wallets should refresh coins significantly
+ * before this time to be on the safe side. @e expire_deposit must be
+ * significantly larger than @e expire_withdraw (by months or even
+ * years).
+ */
+ struct GNUNET_TIME_Timestamp expire_deposit;
+
+ /**
+ * When do signatures with this denomination key become invalid?
+ * After this point, these signatures cannot be used in (legal)
+ * disputes anymore, as the Exchange is then allowed to destroy its side
+ * of the evidence. @e expire_legal is expected to be significantly
+ * larger than @e expire_deposit (by a year or more).
+ */
+ struct GNUNET_TIME_Timestamp expire_legal;
+
+ /**
+ * The value of the coins signed with this denomination key.
+ */
+ struct TALER_Amount value;
+
+ /**
+ * Fees for the coin.
+ */
+ struct TALER_DenomFeeSet fees;
+
+ /**
+ * Hash code of the denomination public key. (Used to avoid having
+ * the variable-size RSA key in this struct.)
+ */
+ struct TALER_DenominationHashP denom_hash;
+
+ /**
+ * If denomination was setup for age restriction, non-zero age mask.
+ * Note that the mask is not part of the signature.
+ */
+ struct TALER_AgeMask age_mask;
+};
+
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Events signalling that a coin deposit status
+ * changed.
+ */
+struct TALER_CoinDepositEventP
+{
+ /**
+ * Of type #TALER_DBEVENT_EXCHANGE_DEPOSIT_STATUS_CHANGED.
+ */
+ struct GNUNET_DB_EventHeaderP header;
+
+ /**
+ * Public key of the merchant.
+ */
+ struct TALER_MerchantPublicKeyP merchant_pub;
+
+};
+
+/**
+ * Events signalling a reserve got funding.
+ */
+struct TALER_ReserveEventP
+{
+ /**
+ * Of type #TALER_DBEVENT_EXCHANGE_RESERVE_INCOMING.
+ */
+ struct GNUNET_DB_EventHeaderP header;
+
+ /**
+ * Public key of the reserve the event is about.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+};
+
+
+/**
+ * Signature of events signalling a purse changed its status.
+ */
+struct TALER_PurseEventP
+{
+ /**
+ * Of type #TALER_DBEVENT_EXCHANGE_PURSE_MERGED or
+ * #TALER_DBEVENT_EXCHANGE_PURSE_DEPOSITED.
+ */
+ struct GNUNET_DB_EventHeaderP header;
+
+ /**
+ * Public key of the purse the event is about.
*/
- struct TALER_DenominationKeyValidityPS properties;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+};
+
+
+/**
+ * Signature of events signalling a KYC process was completed.
+ */
+struct TALER_KycCompletedEventP
+{
+ /**
+ * Of type #TALER_DBEVENT_EXCHANGE_KYC_COMPLETED.
+ */
+ struct GNUNET_DB_EventHeaderP header;
+
+ /**
+ * Public key of the reserve the event is about.
+ */
+ struct TALER_PaytoHashP h_payto;
};
GNUNET_NETWORK_STRUCT_END
+/**
+ * Meta data about an exchange online signing key.
+ */
+struct TALER_EXCHANGEDB_SignkeyMetaData
+{
+ /**
+ * Start time of the validity period for this key.
+ */
+ struct GNUNET_TIME_Timestamp start;
+
+ /**
+ * The exchange will sign messages with this key between @e start and this time.
+ */
+ struct GNUNET_TIME_Timestamp expire_sign;
+
+ /**
+ * When do signatures with this sign key become invalid?
+ * After this point, these signatures cannot be used in (legal)
+ * disputes anymore, as the Exchange is then allowed to destroy its side
+ * of the evidence. @e expire_legal is expected to be significantly
+ * larger than @e expire_sign (by a year or more).
+ */
+ struct GNUNET_TIME_Timestamp expire_legal;
+
+};
+
+
+/**
+ * Enumeration of all of the tables replicated by exchange-auditor
+ * database replication.
+ */
+enum TALER_EXCHANGEDB_ReplicatedTable
+{
+ /* From exchange-0002.sql: */
+ TALER_EXCHANGEDB_RT_DENOMINATIONS,
+ TALER_EXCHANGEDB_RT_DENOMINATION_REVOCATIONS,
+ TALER_EXCHANGEDB_RT_WIRE_TARGETS,
+ TALER_EXCHANGEDB_RT_LEGITIMIZATION_PROCESSES,
+ TALER_EXCHANGEDB_RT_LEGITIMIZATION_REQUIREMENTS,
+ TALER_EXCHANGEDB_RT_RESERVES,
+ TALER_EXCHANGEDB_RT_RESERVES_IN,
+ TALER_EXCHANGEDB_RT_RESERVES_CLOSE,
+ TALER_EXCHANGEDB_RT_RESERVES_OPEN_REQUESTS,
+ TALER_EXCHANGEDB_RT_RESERVES_OPEN_DEPOSITS,
+ TALER_EXCHANGEDB_RT_RESERVES_OUT,
+ TALER_EXCHANGEDB_RT_AUDITORS,
+ TALER_EXCHANGEDB_RT_AUDITOR_DENOM_SIGS,
+ TALER_EXCHANGEDB_RT_EXCHANGE_SIGN_KEYS,
+ TALER_EXCHANGEDB_RT_SIGNKEY_REVOCATIONS,
+ TALER_EXCHANGEDB_RT_KNOWN_COINS,
+ TALER_EXCHANGEDB_RT_REFRESH_COMMITMENTS,
+ TALER_EXCHANGEDB_RT_REFRESH_REVEALED_COINS,
+ TALER_EXCHANGEDB_RT_REFRESH_TRANSFER_KEYS,
+ TALER_EXCHANGEDB_RT_BATCH_DEPOSITS,
+ TALER_EXCHANGEDB_RT_COIN_DEPOSITS,
+ TALER_EXCHANGEDB_RT_REFUNDS,
+ TALER_EXCHANGEDB_RT_WIRE_OUT,
+ TALER_EXCHANGEDB_RT_AGGREGATION_TRACKING,
+ TALER_EXCHANGEDB_RT_WIRE_FEE,
+ TALER_EXCHANGEDB_RT_GLOBAL_FEE,
+ TALER_EXCHANGEDB_RT_RECOUP,
+ TALER_EXCHANGEDB_RT_RECOUP_REFRESH,
+ TALER_EXCHANGEDB_RT_EXTENSIONS,
+ TALER_EXCHANGEDB_RT_POLICY_DETAILS,
+ TALER_EXCHANGEDB_RT_POLICY_FULFILLMENTS,
+ TALER_EXCHANGEDB_RT_PURSE_REQUESTS,
+ TALER_EXCHANGEDB_RT_PURSE_DECISION,
+ TALER_EXCHANGEDB_RT_PURSE_MERGES,
+ TALER_EXCHANGEDB_RT_PURSE_DEPOSITS,
+ TALER_EXCHANGEDB_RT_ACCOUNT_MERGES,
+ TALER_EXCHANGEDB_RT_HISTORY_REQUESTS,
+ TALER_EXCHANGEDB_RT_CLOSE_REQUESTS,
+ TALER_EXCHANGEDB_RT_WADS_OUT,
+ TALER_EXCHANGEDB_RT_WADS_OUT_ENTRIES,
+ TALER_EXCHANGEDB_RT_WADS_IN,
+ TALER_EXCHANGEDB_RT_WADS_IN_ENTRIES,
+ TALER_EXCHANGEDB_RT_PROFIT_DRAINS,
+ /* From exchange-0003.sql: */
+ TALER_EXCHANGEDB_RT_AML_STAFF,
+ TALER_EXCHANGEDB_RT_AML_HISTORY,
+ TALER_EXCHANGEDB_RT_KYC_ATTRIBUTES,
+ TALER_EXCHANGEDB_RT_PURSE_DELETION,
+ TALER_EXCHANGEDB_RT_AGE_WITHDRAW,
+};
+
+
+/**
+ * Record of a single entry in a replicated table.
+ */
+struct TALER_EXCHANGEDB_TableData
+{
+ /**
+ * Data of which table is returned here?
+ */
+ enum TALER_EXCHANGEDB_ReplicatedTable table;
+
+ /**
+ * Serial number of the record.
+ */
+ uint64_t serial;
+
+ /**
+ * Table-specific details.
+ */
+ union
+ {
+
+ /**
+ * Details from the 'denominations' table.
+ */
+ struct
+ {
+ uint32_t denom_type;
+ uint32_t age_mask;
+ struct TALER_DenominationPublicKey denom_pub;
+ struct TALER_MasterSignatureP master_sig;
+ struct GNUNET_TIME_Timestamp valid_from;
+ struct GNUNET_TIME_Timestamp expire_withdraw;
+ struct GNUNET_TIME_Timestamp expire_deposit;
+ struct GNUNET_TIME_Timestamp expire_legal;
+ struct TALER_Amount coin;
+ struct TALER_DenomFeeSet fees;
+ } denominations;
+
+ struct
+ {
+ struct TALER_MasterSignatureP master_sig;
+ uint64_t denominations_serial;
+ } denomination_revocations;
+
+ struct
+ {
+ char *payto_uri;
+ } wire_targets;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct GNUNET_TIME_Timestamp expiration_time;
+ char *provider_section;
+ char *provider_user_id;
+ char *provider_legitimization_id;
+ } legitimization_processes;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ bool no_reserve_pub;
+ char *required_checks;
+ } legitimization_requirements;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_TIME_Timestamp expiration_date;
+ struct GNUNET_TIME_Timestamp gc_date;
+ } reserves;
+
+ struct
+ {
+ uint64_t wire_reference;
+ struct TALER_Amount credit;
+ struct TALER_PaytoHashP sender_account_h_payto;
+ char *exchange_account_section;
+ struct GNUNET_TIME_Timestamp execution_date;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ } reserves_in;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_TIME_Timestamp request_timestamp;
+ struct GNUNET_TIME_Timestamp expiration_date;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_Amount reserve_payment;
+ uint32_t requested_purse_limit;
+ } reserves_open_requests;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_Amount contribution;
+ } reserves_open_deposits;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_TIME_Timestamp execution_date;
+ struct TALER_WireTransferIdentifierRawP wtid;
+ struct TALER_PaytoHashP sender_account_h_payto;
+ struct TALER_Amount amount;
+ struct TALER_Amount closing_fee;
+ } reserves_close;
+
+ struct
+ {
+ struct TALER_BlindedCoinHashP h_blind_ev;
+ uint64_t denominations_serial;
+ struct TALER_BlindedDenominationSignature denom_sig;
+ uint64_t reserve_uuid;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct GNUNET_TIME_Timestamp execution_date;
+ struct TALER_Amount amount_with_fee;
+ } reserves_out;
+
+ struct
+ {
+ struct TALER_AuditorPublicKeyP auditor_pub;
+ char *auditor_url;
+ char *auditor_name;
+ bool is_active;
+ struct GNUNET_TIME_Timestamp last_change;
+ } auditors;
+
+ struct
+ {
+ uint64_t auditor_uuid;
+ uint64_t denominations_serial;
+ struct TALER_AuditorSignatureP auditor_sig;
+ } auditor_denom_sigs;
+
+ struct
+ {
+ struct TALER_ExchangePublicKeyP exchange_pub;
+ struct TALER_MasterSignatureP master_sig;
+ struct TALER_EXCHANGEDB_SignkeyMetaData meta;
+ } exchange_sign_keys;
+
+ struct
+ {
+ uint64_t esk_serial;
+ struct TALER_MasterSignatureP master_sig;
+ } signkey_revocations;
+
+ struct
+ {
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_AgeCommitmentHash age_hash;
+ uint64_t denominations_serial;
+ struct TALER_DenominationSignature denom_sig;
+ } known_coins;
+
+ struct
+ {
+ struct TALER_RefreshCommitmentP rc;
+ struct TALER_CoinSpendPublicKeyP old_coin_pub;
+ struct TALER_CoinSpendSignatureP old_coin_sig;
+ struct TALER_Amount amount_with_fee;
+ uint32_t noreveal_index;
+ } refresh_commitments;
+
+ struct
+ {
+ uint64_t melt_serial_id;
+ uint32_t freshcoin_index;
+ struct TALER_CoinSpendSignatureP link_sig;
+ uint64_t denominations_serial;
+ void *coin_ev;
+ size_t coin_ev_size;
+ struct TALER_ExchangeWithdrawValues ewv;
+ // h_coin_ev omitted, to be recomputed!
+ struct TALER_BlindedDenominationSignature ev_sig;
+ } refresh_revealed_coins;
+
+ struct
+ {
+ uint64_t melt_serial_id;
+ struct TALER_TransferPublicKeyP tp;
+ struct TALER_TransferPrivateKeyP tprivs[TALER_CNC_KAPPA - 1];
+ } refresh_transfer_keys;
+
+ struct
+ {
+ uint64_t shard;
+ struct TALER_MerchantPublicKeyP merchant_pub;
+ struct GNUNET_TIME_Timestamp wallet_timestamp;
+ struct GNUNET_TIME_Timestamp exchange_timestamp;
+ struct GNUNET_TIME_Timestamp refund_deadline;
+ struct GNUNET_TIME_Timestamp wire_deadline;
+ struct TALER_PrivateContractHashP h_contract_terms;
+ struct GNUNET_HashCode wallet_data_hash;
+ bool no_wallet_data_hash;
+ struct TALER_WireSaltP wire_salt;
+ struct TALER_PaytoHashP wire_target_h_payto;
+ bool policy_blocked;
+ uint64_t policy_details_serial_id;
+ bool no_policy_details;
+ } batch_deposits;
+
+ struct
+ {
+ uint64_t batch_deposit_serial_id;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ struct TALER_Amount amount_with_fee;
+ } coin_deposits;
+
+ struct
+ {
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ uint64_t batch_deposit_serial_id;
+ struct TALER_MerchantSignatureP merchant_sig;
+ uint64_t rtransaction_id;
+ struct TALER_Amount amount_with_fee;
+ } refunds;
+
+ struct
+ {
+ struct GNUNET_TIME_Timestamp execution_date;
+ struct TALER_WireTransferIdentifierRawP wtid_raw;
+ struct TALER_PaytoHashP wire_target_h_payto;
+ char *exchange_account_section;
+ struct TALER_Amount amount;
+ } wire_out;
+
+ struct
+ {
+ uint64_t batch_deposit_serial_id;
+ struct TALER_WireTransferIdentifierRawP wtid_raw;
+ } aggregation_tracking;
+
+ struct
+ {
+ char *wire_method;
+ struct GNUNET_TIME_Timestamp start_date;
+ struct GNUNET_TIME_Timestamp end_date;
+ struct TALER_WireFeeSet fees;
+ struct TALER_MasterSignatureP master_sig;
+ } wire_fee;
+
+ struct
+ {
+ struct GNUNET_TIME_Timestamp start_date;
+ struct GNUNET_TIME_Timestamp end_date;
+ struct TALER_GlobalFeeSet fees;
+ struct GNUNET_TIME_Relative purse_timeout;
+ struct GNUNET_TIME_Relative history_expiration;
+ uint32_t purse_account_limit;
+ struct TALER_MasterSignatureP master_sig;
+ } global_fee;
+
+ struct
+ {
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
+ struct TALER_Amount amount;
+ struct GNUNET_TIME_Timestamp timestamp;
+ uint64_t reserve_out_serial_id;
+ } recoup;
+
+ struct
+ {
+ uint64_t known_coin_id;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
+ struct TALER_Amount amount;
+ struct GNUNET_TIME_Timestamp timestamp;
+ uint64_t rrc_serial;
+ } recoup_refresh;
+
+ struct
+ {
+ char *name;
+ char *manifest;
+ } extensions;
+
+ struct
+ {
+ struct GNUNET_HashCode hash_code;
+ json_t *policy_json;
+ bool no_policy_json;
+ struct GNUNET_TIME_Timestamp deadline;
+ struct TALER_Amount commitment;
+ struct TALER_Amount accumulated_total;
+ struct TALER_Amount fee;
+ struct TALER_Amount transferable;
+ uint16_t fulfillment_state; /* will also be recomputed */
+ uint64_t fulfillment_id;
+ bool no_fulfillment_id;
+ } policy_details;
+
+ struct
+ {
+ struct GNUNET_TIME_Timestamp fulfillment_timestamp;
+ char *fulfillment_proof;
+ struct GNUNET_HashCode h_fulfillment_proof;
+ struct GNUNET_HashCode *policy_hash_codes;
+ size_t policy_hash_codes_count;
+ } policy_fulfillments;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PurseMergePublicKeyP merge_pub;
+ struct GNUNET_TIME_Timestamp purse_creation;
+ struct GNUNET_TIME_Timestamp purse_expiration;
+ struct TALER_PrivateContractHashP h_contract_terms;
+ uint32_t age_limit;
+ uint32_t flags;
+ struct TALER_Amount amount_with_fee;
+ struct TALER_Amount purse_fee;
+ struct TALER_PurseContractSignatureP purse_sig;
+ } purse_requests;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct GNUNET_TIME_Timestamp action_timestamp;
+ bool refunded;
+ } purse_decision;
+
+ struct
+ {
+ uint64_t partner_serial_id;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PurseMergeSignatureP merge_sig;
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+ } purse_merges;
+
+ struct
+ {
+ uint64_t partner_serial_id;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+ struct TALER_Amount amount_with_fee;
+ struct TALER_CoinSpendSignatureP coin_sig;
+ } purse_deposits;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PaytoHashP wallet_h_payto;
+ } account_merges;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct GNUNET_TIME_Timestamp request_timestamp;
+ struct TALER_Amount history_fee;
+ } history_requests;
+
+ struct
+ {
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct GNUNET_TIME_Timestamp close_timestamp;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_Amount close;
+ struct TALER_Amount close_fee;
+ char *payto_uri;
+ } close_requests;
+
+ struct
+ {
+ struct TALER_WadIdentifierP wad_id;
+ uint64_t partner_serial_id;
+ struct TALER_Amount amount;
+ struct GNUNET_TIME_Timestamp execution_time;
+ } wads_out;
+
+ struct
+ {
+ uint64_t wad_out_serial_id;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PrivateContractHashP h_contract;
+ struct GNUNET_TIME_Timestamp purse_expiration;
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+ struct TALER_Amount amount_with_fee;
+ struct TALER_Amount wad_fee;
+ struct TALER_Amount deposit_fees;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_PurseContractSignatureP purse_sig;
+ } wads_out_entries;
+
+ struct
+ {
+ struct TALER_WadIdentifierP wad_id;
+ char *origin_exchange_url;
+ struct TALER_Amount amount;
+ struct GNUNET_TIME_Timestamp arrival_time;
+ } wads_in;
+
+ struct
+ {
+ uint64_t wad_in_serial_id;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PrivateContractHashP h_contract;
+ struct GNUNET_TIME_Timestamp purse_expiration;
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+ struct TALER_Amount amount_with_fee;
+ struct TALER_Amount wad_fee;
+ struct TALER_Amount deposit_fees;
+ struct TALER_ReserveSignatureP reserve_sig;
+ struct TALER_PurseContractSignatureP purse_sig;
+ } wads_in_entries;
+
+ struct
+ {
+ struct TALER_WireTransferIdentifierRawP wtid;
+ char *account_section;
+ char *payto_uri;
+ struct GNUNET_TIME_Timestamp trigger_date;
+ struct TALER_Amount amount;
+ struct TALER_MasterSignatureP master_sig;
+ } profit_drains;
+
+ struct
+ {
+ struct TALER_AmlOfficerPublicKeyP decider_pub;
+ struct TALER_MasterSignatureP master_sig;
+ char *decider_name;
+ bool is_active;
+ bool read_only;
+ struct GNUNET_TIME_Timestamp last_change;
+ } aml_staff;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct TALER_Amount new_threshold;
+ enum TALER_AmlDecisionState new_status;
+ struct GNUNET_TIME_Timestamp decision_time;
+ char *justification;
+ char *kyc_requirements; /* NULL allowed! */
+ uint64_t kyc_req_row;
+ struct TALER_AmlOfficerPublicKeyP decider_pub;
+ struct TALER_AmlOfficerSignatureP decider_sig;
+ } aml_history;
+
+ struct
+ {
+ struct TALER_PaytoHashP h_payto;
+ struct GNUNET_ShortHashCode kyc_prox;
+ char *provider;
+ struct GNUNET_TIME_Timestamp collection_time;
+ struct GNUNET_TIME_Timestamp expiration_time;
+ void *encrypted_attributes;
+ size_t encrypted_attributes_size;
+ } kyc_attributes;
+
+ struct
+ {
+ struct TALER_PurseContractPublicKeyP purse_pub;
+ struct TALER_PurseContractSignatureP purse_sig;
+ } purse_deletion;
+
+ struct
+ {
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+ struct TALER_Amount amount_with_fee;
+ uint16_t max_age;
+ uint32_t noreveal_index;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ struct TALER_ReserveSignatureP reserve_sig;
+ uint64_t num_coins;
+ uint64_t *denominations_serials;
+ void *h_blind_evs;
+ struct TALER_BlindedDenominationSignature denom_sigs;
+ } age_withdraw;
+
+ } details;
+
+};
+
+
+/**
+ * Function called on data to replicate in the auditor's database.
+ *
+ * @param cls closure
+ * @param td record from an exchange table
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_SYSERR to fail with an error
+ */
+typedef int
+(*TALER_EXCHANGEDB_ReplicationCallback)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_TableData *td);
+
/**
* @brief All information about a denomination key (which is used to
@@ -98,7 +858,7 @@ struct TALER_EXCHANGEDB_DenominationKey
/**
* Signed public information about a denomination key.
*/
- struct TALER_EXCHANGEDB_DenominationKeyInformationP issue;
+ struct TALER_EXCHANGEDB_DenominationKeyInformation issue;
};
@@ -123,7 +883,7 @@ struct TALER_EXCHANGEDB_BankTransfer
* (This is the execution date of the exchange's database,
* the execution date of the bank should be in @e wire).
*/
- struct GNUNET_TIME_Absolute execution_date;
+ struct GNUNET_TIME_Timestamp execution_date;
/**
* Detailed wire information about the sending account
@@ -134,12 +894,7 @@ struct TALER_EXCHANGEDB_BankTransfer
/**
* Data uniquely identifying the wire transfer (wire transfer-type specific)
*/
- void *wire_reference;
-
- /**
- * Number of bytes in @e wire_reference.
- */
- size_t wire_reference_size;
+ uint64_t wire_reference;
};
@@ -157,7 +912,7 @@ struct TALER_EXCHANGEDB_ClosingTransfer
struct TALER_ReservePublicKeyP reserve_pub;
/**
- * Amount that was transferred to the exchange.
+ * Amount that was transferred from the exchange.
*/
struct TALER_Amount amount;
@@ -169,7 +924,7 @@ struct TALER_EXCHANGEDB_ClosingTransfer
/**
* When did the exchange execute the transaction?
*/
- struct GNUNET_TIME_Absolute execution_date;
+ struct GNUNET_TIME_Timestamp execution_date;
/**
* Detailed wire information about the receiving account
@@ -205,17 +960,203 @@ struct TALER_EXCHANGEDB_Reserve
* The expiration date of this reserve; funds will be wired back
* at this time.
*/
- struct GNUNET_TIME_Absolute expiry;
+ struct GNUNET_TIME_Timestamp expiry;
/**
* The legal expiration date of this reserve; we will forget about
* it at this time.
*/
- struct GNUNET_TIME_Absolute gc;
+ struct GNUNET_TIME_Timestamp gc;
+};
+
+
+/**
+ * Meta data about a denomination public key.
+ */
+struct TALER_EXCHANGEDB_DenominationKeyMetaData
+{
+ /**
+ * Serial of the denomination key as in the DB.
+ * Can be used in calls to stored procedures in order to spare
+ * additional lookups.
+ */
+ uint64_t serial;
+
+ /**
+ * Start time of the validity period for this key.
+ */
+ struct GNUNET_TIME_Timestamp start;
+
+ /**
+ * The exchange will sign fresh coins between @e start and this time.
+ * @e expire_withdraw will be somewhat larger than @e start to
+ * ensure a sufficiently large anonymity set, while also allowing
+ * the Exchange to limit the financial damage in case of a key being
+ * compromised. Thus, exchanges with low volume are expected to have a
+ * longer withdraw period (@e expire_withdraw - @e start) than exchanges
+ * with high transaction volume. The period may also differ between
+ * types of coins. A exchange may also have a few denomination keys
+ * with the same value with overlapping validity periods, to address
+ * issues such as clock skew.
+ */
+ struct GNUNET_TIME_Timestamp expire_withdraw;
+
+ /**
+ * Coins signed with the denomination key must be spent or refreshed
+ * between @e start and this expiration time. After this time, the
+ * exchange will refuse transactions involving this key as it will
+ * "drop" the table with double-spending information (shortly after)
+ * this time. Note that wallets should refresh coins significantly
+ * before this time to be on the safe side. @e expire_deposit must be
+ * significantly larger than @e expire_withdraw (by months or even
+ * years).
+ */
+ struct GNUNET_TIME_Timestamp expire_deposit;
+
+ /**
+ * When do signatures with this denomination key become invalid?
+ * After this point, these signatures cannot be used in (legal)
+ * disputes anymore, as the Exchange is then allowed to destroy its side
+ * of the evidence. @e expire_legal is expected to be significantly
+ * larger than @e expire_deposit (by a year or more).
+ */
+ struct GNUNET_TIME_Timestamp expire_legal;
+
+ /**
+ * The value of the coins signed with this denomination key.
+ */
+ struct TALER_Amount value;
+
+ /**
+ * The fees the exchange charges for operations with
+ * coins of this denomination.
+ */
+ struct TALER_DenomFeeSet fees;
+
+ /**
+ * Age restriction for the denomination. (can be zero). If not zero, the bits
+ * set in the mask mark the edges at the beginning of a next age group. F.e.
+ * for the age groups
+ * 0-7, 8-9, 10-11, 12-14, 14-15, 16-17, 18-21, 21-*
+ * the following bits are set:
+ *
+ * 31 24 16 8 0
+ * | | | | |
+ * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
+ *
+ * A value of 0 means that the denomination does not support the extension for
+ * age-restriction.
+ */
+ struct TALER_AgeMask age_mask;
};
/**
+ * Signature of a function called with information about the exchange's
+ * denomination keys.
+ *
+ * @param cls closure with a `struct TEH_KeyStateHandle *`
+ * @param denom_pub public key of the denomination
+ * @param h_denom_pub hash of @a denom_pub
+ * @param meta meta data information about the denomination type (value, expirations, fees)
+ * @param master_sig master signature affirming the validity of this denomination
+ * @param recoup_possible true if the key was revoked and clients can currently recoup
+ * coins of this denomination
+ */
+typedef void
+(*TALER_EXCHANGEDB_DenominationsCallback)(
+ void *cls,
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
+ const struct TALER_MasterSignatureP *master_sig,
+ bool recoup_possible);
+
+
+/**
+ * Signature of a function called with information about the exchange's
+ * online signing keys.
+ *
+ * @param cls closure with a `struct TEH_KeyStateHandle *`
+ * @param exchange_pub public key of the exchange
+ * @param meta meta data information about the signing type (expirations)
+ * @param master_sig master signature affirming the validity of this denomination
+ */
+typedef void
+(*TALER_EXCHANGEDB_ActiveSignkeysCallback)(
+ void *cls,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Function called on all KYC process names that the given
+ * account has already passed.
+ *
+ * @param cls closure
+ * @param kyc_provider_section_name configuration section
+ * of the respective KYC process
+ */
+typedef void
+(*TALER_EXCHANGEDB_SatisfiedProviderCallback)(
+ void *cls,
+ const char *kyc_provider_section_name);
+
+
+/**
+ * Function called on all legitimization operations
+ * we have performed for the given account so far
+ * (and that have not yet expired).
+ *
+ * @param cls closure
+ * @param kyc_provider_section_name configuration section
+ * of the respective KYC process
+ * @param provider_user_id UID at a provider (can be NULL)
+ * @param legi_id legitimization process ID (can be NULL)
+ */
+typedef void
+(*TALER_EXCHANGEDB_LegitimizationProcessCallback)(
+ void *cls,
+ const char *kyc_provider_section_name,
+ const char *provider_user_id,
+ const char *legi_id);
+
+
+/**
+ * Function called with information about the exchange's auditors.
+ *
+ * @param cls closure with a `struct TEH_KeyStateHandle *`
+ * @param auditor_pub the public key of the auditor
+ * @param auditor_url URL of the REST API of the auditor
+ * @param auditor_name human readable official name of the auditor
+ */
+typedef void
+(*TALER_EXCHANGEDB_AuditorsCallback)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name);
+
+
+/**
+ * Function called with information about the denominations
+ * audited by the exchange's auditors.
+ *
+ * @param cls closure with a `struct TEH_KeyStateHandle *`
+ * @param auditor_pub the public key of an auditor
+ * @param h_denom_pub hash of a denomination key audited by this auditor
+ * @param auditor_sig signature from the auditor affirming this
+ */
+typedef void
+(*TALER_EXCHANGEDB_AuditorDenominationsCallback)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AuditorSignatureP *auditor_sig);
+
+
+/**
* @brief Information we keep for a withdrawn coin to reproduce
* the /withdraw operation if needed, and to have proof
* that a reserve was drained by this amount.
@@ -224,14 +1165,14 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin
{
/**
- * Our signature over the (blinded) coin.
+ * Our (blinded) signature over the (blinded) coin.
*/
- struct TALER_DenominationSignature sig;
+ struct TALER_BlindedDenominationSignature sig;
/**
* Hash of the denomination key (which coin was generated).
*/
- struct GNUNET_HashCode denom_pub_hash;
+ struct TALER_DenominationHashP denom_pub_hash;
/**
* Value of the coin being exchangeed (matching the denomination key)
@@ -264,7 +1205,7 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin
* Hash over the blinded message, needed to verify
* the @e reserve_sig.
*/
- struct GNUNET_HashCode h_coin_envelope;
+ struct TALER_BlindedCoinHashP h_coin_envelope;
/**
* Signature confirming the withdrawal, matching @e reserve_pub,
@@ -275,6 +1216,79 @@ struct TALER_EXCHANGEDB_CollectableBlindcoin
/**
+ * @brief Information we keep for an age-withdraw request
+ * to reproduce the /age-withdraw operation if needed, and to have proof
+ * that a reserve was drained by this amount.
+ */
+struct TALER_EXCHANGEDB_AgeWithdraw
+{
+ /**
+ * Total amount (with fee) committed to withdraw
+ */
+ struct TALER_Amount amount_with_fee;
+
+ /**
+ * Maximum age (in years) that the coins are restricted to.
+ */
+ uint16_t max_age;
+
+ /**
+ * The hash of the commitment of all n*kappa coins
+ */
+ struct TALER_AgeWithdrawCommitmentHashP h_commitment;
+
+ /**
+ * Index (smaller #TALER_CNC_KAPPA) which the exchange has chosen to not have
+ * revealed during cut and choose. This value applies to all n coins in the
+ * commitment.
+ */
+ uint16_t noreveal_index;
+
+ /**
+ * Public key of the reserve that was drained.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Signature confirming the age withdrawal commitment, matching @e
+ * reserve_pub, @e max_age and @e h_commitment and @e amount_with_fee.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * Number of coins to be withdrawn.
+ */
+ size_t num_coins;
+
+ /**
+ * Array of @a num_coins blinded coins. These are the chosen coins
+ * (according to @a noreveal_index) from the request, which contained
+ * kappa*num_coins blinded coins.
+ */
+ struct TALER_BlindedCoinHashP *h_coin_evs;
+
+ /**
+ * Array of @a num_coins denomination signatures of the blinded coins @a
+ * h_coin_evs.
+ */
+ struct TALER_BlindedDenominationSignature *denom_sigs;
+
+ /**
+ * Array of @a num_coins serial id's of the denominations, corresponding to
+ * the coins in @a h_coin_evs.
+ */
+ uint64_t *denom_serials;
+
+ /**
+ * [out]-Array of @a num_coins hashes of the public keys of the denominations
+ * identified by @e denom_serials. This field is set when calling
+ * get_age_withdraw
+ */
+ struct TALER_DenominationHashP *denom_pub_hashes;
+};
+
+
+/**
* Information the exchange records about a recoup request
* in a reserve history.
*/
@@ -290,7 +1304,7 @@ struct TALER_EXCHANGEDB_Recoup
* Blinding factor supplied to prove to the exchange that
* the coin came from this reserve.
*/
- struct TALER_DenominationBlindingKeyP coin_blind;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
/**
* Signature of the coin of type
@@ -311,8 +1325,25 @@ struct TALER_EXCHANGEDB_Recoup
/**
* When did the recoup operation happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
+
+};
+
+/**
+ * Public key to which a nonce is locked.
+ */
+union TALER_EXCHANGEDB_NonceLockTargetP
+{
+ /**
+ * Nonce is locked to this coin key.
+ */
+ struct TALER_CoinSpendPublicKeyP coin;
+
+ /**
+ * Nonce is locked to this reserve key.
+ */
+ struct TALER_ReservePublicKeyP reserve;
};
@@ -327,7 +1358,7 @@ struct TALER_EXCHANGEDB_RecoupListEntry
* Blinding factor supplied to prove to the exchange that
* the coin came from this reserve.
*/
- struct TALER_DenominationBlindingKeyP coin_blind;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
/**
* Signature of the coin of type
@@ -336,6 +1367,11 @@ struct TALER_EXCHANGEDB_RecoupListEntry
struct TALER_CoinSpendSignatureP coin_sig;
/**
+ * Hash of the public denomination key used to sign the coin.
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
* Public key of the reserve the coin was paid back into.
*/
struct TALER_ReservePublicKeyP reserve_pub;
@@ -348,7 +1384,7 @@ struct TALER_EXCHANGEDB_RecoupListEntry
/**
* When did the /recoup operation happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
};
@@ -368,9 +1404,9 @@ struct TALER_EXCHANGEDB_RecoupRefreshListEntry
/**
* Blinding factor supplied to prove to the exchange that
- * the coin came from this reserve.
+ * the coin came from this @e old_coin_pub.
*/
- struct TALER_DenominationBlindingKeyP coin_blind;
+ union GNUNET_CRYPTO_BlindingSecretP coin_blind;
/**
* Signature of the coin of type
@@ -391,7 +1427,174 @@ struct TALER_EXCHANGEDB_RecoupRefreshListEntry
/**
* When did the recoup operation happen?
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
+
+};
+
+
+/**
+ * Details about a purse merge operation.
+ */
+struct TALER_EXCHANGEDB_PurseMerge
+{
+
+ /**
+ * Public key of the reserve the coin was merged into.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Amount in the purse, with fees.
+ */
+ struct TALER_Amount amount_with_fee;
+
+ /**
+ * Fee paid for the purse.
+ */
+ struct TALER_Amount purse_fee;
+
+ /**
+ * Hash over the contract.
+ */
+ struct TALER_PrivateContractHashP h_contract_terms;
+
+ /**
+ * Merge capability key.
+ */
+ struct TALER_PurseMergePublicKeyP merge_pub;
+
+ /**
+ * Purse public key.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Signature by the reserve approving the merge.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * When was the merge made.
+ */
+ struct GNUNET_TIME_Timestamp merge_timestamp;
+
+ /**
+ * When was the purse set to expire.
+ */
+ struct GNUNET_TIME_Timestamp purse_expiration;
+
+ /**
+ * Minimum age required for depositing into the purse.
+ */
+ uint32_t min_age;
+
+ /**
+ * Flags of the purse.
+ */
+ enum TALER_WalletAccountMergeFlags flags;
+
+ /**
+ * true if the purse was actually successfully merged,
+ * false if the @e purse_fee was charged but the
+ * @e amount was not credited to the reserve.
+ */
+ bool merged;
+};
+
+
+/**
+ * Details about a (paid for) reserve history request.
+ */
+struct TALER_EXCHANGEDB_HistoryRequest
+{
+ /**
+ * Public key of the reserve the history request was for.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Fee paid for the request.
+ */
+ struct TALER_Amount history_fee;
+
+ /**
+ * When was the request made.
+ */
+ struct GNUNET_TIME_Timestamp request_timestamp;
+
+ /**
+ * Signature by the reserve approving the history request.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+};
+
+
+/**
+ * Details about a (paid for) reserve open request.
+ */
+struct TALER_EXCHANGEDB_OpenRequest
+{
+ /**
+ * Public key of the reserve the open request was for.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * Fee paid for the request from the reserve.
+ */
+ struct TALER_Amount open_fee;
+
+ /**
+ * When was the request made.
+ */
+ struct GNUNET_TIME_Timestamp request_timestamp;
+
+ /**
+ * How long was the reserve supposed to be open.
+ */
+ struct GNUNET_TIME_Timestamp reserve_expiration;
+
+ /**
+ * Signature by the reserve approving the open request,
+ * with purpose #TALER_SIGNATURE_WALLET_RESERVE_OPEN.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * How many open purses should be included with the
+ * open reserve?
+ */
+ uint32_t purse_limit;
+
+};
+
+
+/**
+ * Details about an (explicit) reserve close request.
+ */
+struct TALER_EXCHANGEDB_CloseRequest
+{
+ /**
+ * Public key of the reserve the history request was for.
+ */
+ struct TALER_ReservePublicKeyP reserve_pub;
+
+ /**
+ * When was the request made.
+ */
+ struct GNUNET_TIME_Timestamp request_timestamp;
+
+ /**
+ * Hash of the payto://-URI of the target account
+ * for the closure, or all zeros for the reserve
+ * origin account.
+ */
+ struct TALER_PaytoHashP target_account_h_payto;
+
+ /**
+ * Signature by the reserve approving the history request.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
};
@@ -422,7 +1625,27 @@ enum TALER_EXCHANGEDB_ReserveOperation
* customer's bank account. This happens when the exchange
* closes a reserve with a non-zero amount left in it.
*/
- TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK = 3
+ TALER_EXCHANGEDB_RO_EXCHANGE_TO_BANK = 3,
+
+ /**
+ * Event where a purse was merged into a reserve.
+ */
+ TALER_EXCHANGEDB_RO_PURSE_MERGE = 4,
+
+ /**
+ * Event where a wallet paid for a full reserve history.
+ */
+ TALER_EXCHANGEDB_RO_HISTORY_REQUEST = 5,
+
+ /**
+ * Event where a wallet paid to open a reserve for longer.
+ */
+ TALER_EXCHANGEDB_RO_OPEN_REQUEST = 6,
+
+ /**
+ * Event where a wallet requested a reserve to be closed.
+ */
+ TALER_EXCHANGEDB_RO_CLOSE_REQUEST = 7
};
@@ -473,12 +1696,156 @@ struct TALER_EXCHANGEDB_ReserveHistory
*/
struct TALER_EXCHANGEDB_ClosingTransfer *closing;
+ /**
+ * Details about a purse merge operation.
+ */
+ struct TALER_EXCHANGEDB_PurseMerge *merge;
+
+ /**
+ * Details about a (paid for) reserve history request.
+ */
+ struct TALER_EXCHANGEDB_HistoryRequest *history;
+
+ /**
+ * Details about a (paid for) open reserve request.
+ */
+ struct TALER_EXCHANGEDB_OpenRequest *open_request;
+
+ /**
+ * Details about an (explicit) reserve close request.
+ */
+ struct TALER_EXCHANGEDB_CloseRequest *close_request;
+
} details;
};
/**
+ * @brief Data about a coin for a deposit operation.
+ */
+struct TALER_EXCHANGEDB_CoinDepositInformation
+{
+ /**
+ * Information about the coin that is being deposited.
+ */
+ struct TALER_CoinPublicInfo coin;
+
+ /**
+ * ECDSA signature affirming that the customer intends
+ * this coin to be deposited at the merchant identified
+ * by @e h_wire in relation to the proposal data identified
+ * by @e h_contract_terms.
+ */
+ struct TALER_CoinSpendSignatureP csig;
+
+ /**
+ * Fraction of the coin's remaining value to be deposited, including
+ * depositing fee (if any). The coin is identified by @e coin_pub.
+ */
+ struct TALER_Amount amount_with_fee;
+
+};
+
+
+/**
+ * @brief Data from a batch deposit operation.
+ */
+struct TALER_EXCHANGEDB_BatchDeposit
+{
+
+ /**
+ * Public key of the merchant. Enables later identification
+ * of the merchant in case of a need to rollback transactions.
+ */
+ struct TALER_MerchantPublicKeyP merchant_pub;
+
+ /**
+ * Hash over the proposal data between merchant and customer
+ * (remains unknown to the Exchange).
+ */
+ struct TALER_PrivateContractHashP h_contract_terms;
+
+ /**
+ * Hash over additional inputs by the wallet.
+ */
+ struct GNUNET_HashCode wallet_data_hash;
+
+ /**
+ * Unsalted hash over @e receiver_wire_account.
+ */
+ struct TALER_PaytoHashP wire_target_h_payto;
+
+ /**
+ * Salt used by the merchant to compute "h_wire".
+ */
+ struct TALER_WireSaltP wire_salt;
+
+ /**
+ * Time when this request was generated. Used, for example, to
+ * assess when (roughly) the income was achieved for tax purposes.
+ * Note that the Exchange will only check that the timestamp is not "too
+ * far" into the future (i.e. several days). The fact that the
+ * timestamp falls within the validity period of the coin's
+ * denomination key is irrelevant for the validity of the deposit
+ * request, as obviously the customer and merchant could conspire to
+ * set any timestamp. Also, the Exchange must accept very old deposit
+ * requests, as the merchant might have been unable to transmit the
+ * deposit request in a timely fashion (so back-dating is not
+ * prevented).
+ */
+ struct GNUNET_TIME_Timestamp wallet_timestamp;
+
+ /**
+ * How much time does the merchant have to issue a refund request?
+ * Zero if refunds are not allowed. After this time, the coin
+ * cannot be refunded.
+ */
+ struct GNUNET_TIME_Timestamp refund_deadline;
+
+ /**
+ * How much time does the merchant have to execute the wire transfer?
+ * This time is advisory for aggregating transactions, not a hard
+ * constraint (as the merchant can theoretically pick any time,
+ * including one in the past).
+ */
+ struct GNUNET_TIME_Timestamp wire_deadline;
+
+ /**
+ * Row ID of the policy details; 0 if no policy applies.
+ */
+ uint64_t policy_details_serial_id;
+
+ /**
+ * Information about the receiver for executing the transaction. URI in
+ * payto://-format.
+ */
+ const char *receiver_wire_account;
+
+ /**
+ * Array about the coins that are being deposited.
+ */
+ const struct TALER_EXCHANGEDB_CoinDepositInformation *cdis;
+
+ /**
+ * Length of the @e cdis array.
+ */
+ unsigned int num_cdis;
+
+ /**
+ * False if @e wallet_data_hash was provided
+ */
+ bool no_wallet_data_hash;
+
+ /**
+ * True if further processing is blocked by policy.
+ */
+ bool policy_blocked;
+
+};
+
+
+/**
* @brief Data from a deposit operation. The combination of
* the coin's public key, the merchant's public key and the
* transaction ID must be unique. While a coin can (theoretically) be
@@ -510,24 +1877,26 @@ struct TALER_EXCHANGEDB_Deposit
struct TALER_MerchantPublicKeyP merchant_pub;
/**
- * Hash over the proposa data between merchant and customer
+ * Hash over the proposal data between merchant and customer
* (remains unknown to the Exchange).
*/
- struct GNUNET_HashCode h_contract_terms;
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
- * Hash of the (canonical) representation of @e wire, used
- * to check the signature on the request. Generated by
- * the exchange from the detailed wire data provided by the
- * merchant.
+ * Salt used by the merchant to compute "h_wire".
*/
- struct GNUNET_HashCode h_wire;
+ struct TALER_WireSaltP wire_salt;
/**
- * Detailed information about the receiver for executing the transaction.
- * Includes URL in payto://-format and salt.
+ * Hash over inputs from the wallet to customize the contract.
+ */
+ struct GNUNET_HashCode wallet_data_hash;
+
+ /**
+ * Hash over the policy data for this deposit (remains unknown to the
+ * Exchange). Needed for the verification of the deposit's signature
*/
- json_t *receiver_wire_account;
+ struct TALER_ExtensionPolicyHashP h_policy;
/**
* Time when this request was generated. Used, for example, to
@@ -542,14 +1911,14 @@ struct TALER_EXCHANGEDB_Deposit
* deposit request in a timely fashion (so back-dating is not
* prevented).
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
/**
* How much time does the merchant have to issue a refund request?
* Zero if refunds are not allowed. After this time, the coin
* cannot be refunded.
*/
- struct GNUNET_TIME_Absolute refund_deadline;
+ struct GNUNET_TIME_Timestamp refund_deadline;
/**
* How much time does the merchant have to execute the wire transfer?
@@ -557,7 +1926,7 @@ struct TALER_EXCHANGEDB_Deposit
* constraint (as the merchant can theoretically pick any time,
* including one in the past).
*/
- struct GNUNET_TIME_Absolute wire_deadline;
+ struct GNUNET_TIME_Timestamp wire_deadline;
/**
* Fraction of the coin's remaining value to be deposited, including
@@ -570,6 +1939,22 @@ struct TALER_EXCHANGEDB_Deposit
*/
struct TALER_Amount deposit_fee;
+ /**
+ * Information about the receiver for executing the transaction. URI in
+ * payto://-format.
+ */
+ char *receiver_wire_account;
+
+ /**
+ * True if @e policy_json was provided
+ */
+ bool has_policy;
+
+ /**
+ * True if @e wallet_data_hash is not in use.
+ */
+ bool no_wallet_data_hash;
+
};
@@ -598,21 +1983,45 @@ struct TALER_EXCHANGEDB_DepositListEntry
* Hash over the proposa data between merchant and customer
* (remains unknown to the Exchange).
*/
- struct GNUNET_HashCode h_contract_terms;
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
- * Hash of the (canonical) representation of @e wire, used
- * to check the signature on the request. Generated by
- * the exchange from the detailed wire data provided by the
- * merchant.
+ * Hash over inputs from the wallet to customize the contract.
*/
- struct GNUNET_HashCode h_wire;
+ struct GNUNET_HashCode wallet_data_hash;
/**
- * Detailed information about the receiver for executing the transaction.
- * Includes URL in payto://-format and salt.
+ * Hash of the public denomination key used to sign the coin.
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
+ * Age commitment hash, if applicable to the denomination. Should be all
+ * zeroes if age commitment is not applicable to the denonimation.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Salt used to compute h_wire from the @e receiver_wire_account.
+ */
+ struct TALER_WireSaltP wire_salt;
+
+ /**
+ * Hash over the policy data for this deposit (remains unknown to the
+ * Exchange). Needed for the verification of the deposit's signature
+ */
+ struct TALER_ExtensionPolicyHashP h_policy;
+
+ /**
+ * Fraction of the coin's remaining value to be deposited, including
+ * depositing fee (if any). The coin is identified by @e coin_pub.
*/
- json_t *receiver_wire_account;
+ struct TALER_Amount amount_with_fee;
+
+ /**
+ * Depositing fee.
+ */
+ struct TALER_Amount deposit_fee;
/**
* Time when this request was generated. Used, for example, to
@@ -627,14 +2036,14 @@ struct TALER_EXCHANGEDB_DepositListEntry
* deposit request in a timely fashion (so back-dating is not
* prevented).
*/
- struct GNUNET_TIME_Absolute timestamp;
+ struct GNUNET_TIME_Timestamp timestamp;
/**
* How much time does the merchant have to issue a refund request?
* Zero if refunds are not allowed. After this time, the coin
* cannot be refunded.
*/
- struct GNUNET_TIME_Absolute refund_deadline;
+ struct GNUNET_TIME_Timestamp refund_deadline;
/**
* How much time does the merchant have to execute the wire transfer?
@@ -642,18 +2051,33 @@ struct TALER_EXCHANGEDB_DepositListEntry
* constraint (as the merchant can theoretically pick any time,
* including one in the past).
*/
- struct GNUNET_TIME_Absolute wire_deadline;
+ struct GNUNET_TIME_Timestamp wire_deadline;
/**
- * Fraction of the coin's remaining value to be deposited, including
- * depositing fee (if any). The coin is identified by @e coin_pub.
+ * Detailed information about the receiver for executing the transaction.
+ * URL in payto://-format.
*/
- struct TALER_Amount amount_with_fee;
+ char *receiver_wire_account;
/**
- * Depositing fee.
+ * true, if age commitment is not applicable
*/
- struct TALER_Amount deposit_fee;
+ bool no_age_commitment;
+
+ /**
+ * true, if wallet data hash is not present
+ */
+ bool no_wallet_data_hash;
+
+ /**
+ * True if a policy was provided with the deposit request
+ */
+ bool has_policy;
+
+ /**
+ * Has the deposit been wired?
+ */
+ bool done;
};
@@ -678,7 +2102,7 @@ struct TALER_EXCHANGEDB_RefundListEntry
* Hash over the proposal data between merchant and customer
* (remains unknown to the Exchange).
*/
- struct GNUNET_HashCode h_contract_terms;
+ struct TALER_PrivateContractHashP h_contract_terms;
/**
* Merchant-generated REFUND transaction ID to detect duplicate
@@ -782,6 +2206,23 @@ struct TALER_EXCHANGEDB_MeltListEntry
struct TALER_RefreshCommitmentP rc;
/**
+ * Hash of the public denomination key used to sign the coin.
+ */
+ struct TALER_DenominationHashP h_denom_pub;
+
+ /**
+ * Hash of the age commitment used to sign the coin, if age restriction was
+ * applicable to the denomination. May be all zeroes if no age restriction
+ * applies.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * true, if no h_age_commitment is applicable
+ */
+ bool no_age_commitment;
+
+ /**
* How much value is being melted? This amount includes the fees,
* so the final amount contributed to the melt is this value minus
* the fee for melting the coin. We include the fee in what is
@@ -806,6 +2247,158 @@ struct TALER_EXCHANGEDB_MeltListEntry
/**
+ * Information about a /purses/$PID/deposit operation in a coin transaction history.
+ */
+struct TALER_EXCHANGEDB_PurseDepositListEntry
+{
+
+ /**
+ * Exchange hosting the purse, NULL for this exchange.
+ */
+ char *exchange_base_url;
+
+ /**
+ * Public key of the purse.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Contribution of the coin to the purse, including
+ * deposit fee.
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * Depositing fee.
+ */
+ struct TALER_Amount deposit_fee;
+
+ /**
+ * Signature by the coin affirming the deposit.
+ */
+ struct TALER_CoinSpendSignatureP coin_sig;
+
+ /**
+ * Hash of the age commitment used to sign the coin, if age restriction was
+ * applicable to the denomination.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Set to true if the coin was refunded.
+ */
+ bool refunded;
+
+ /**
+ * Set to true if there was no age commitment.
+ */
+ bool no_age_commitment;
+
+};
+
+
+/**
+ * @brief Specification for a purse refund operation in a coin's transaction list.
+ */
+struct TALER_EXCHANGEDB_PurseRefundListEntry
+{
+
+ /**
+ * Public key of the purse.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Fraction of the original deposit's value to be refunded, including
+ * refund fee (if any). The coin is identified by @e coin_pub.
+ */
+ struct TALER_Amount refund_amount;
+
+ /**
+ * Refund fee to be covered by the customer.
+ */
+ struct TALER_Amount refund_fee;
+
+};
+
+
+/**
+ * Information about a /reserves/$RID/open operation in a coin transaction history.
+ */
+struct TALER_EXCHANGEDB_ReserveOpenListEntry
+{
+
+ /**
+ * Signature of the reserve.
+ */
+ struct TALER_ReserveSignatureP reserve_sig;
+
+ /**
+ * Contribution of the coin to the open fee, including
+ * deposit fee.
+ */
+ struct TALER_Amount coin_contribution;
+
+ /**
+ * Signature by the coin affirming the open deposit.
+ */
+ struct TALER_CoinSpendSignatureP coin_sig;
+
+};
+
+
+/**
+ * Information about a /purses/$PID/deposit operation.
+ */
+struct TALER_EXCHANGEDB_PurseDeposit
+{
+
+ /**
+ * Exchange hosting the purse, NULL for this exchange.
+ */
+ char *exchange_base_url;
+
+ /**
+ * Public key of the purse.
+ */
+ struct TALER_PurseContractPublicKeyP purse_pub;
+
+ /**
+ * Contribution of the coin to the purse, including
+ * deposit fee.
+ */
+ struct TALER_Amount amount;
+
+ /**
+ * Depositing fee.
+ */
+ struct TALER_Amount deposit_fee;
+
+ /**
+ * Signature by the coin affirming the deposit.
+ */
+ struct TALER_CoinSpendSignatureP coin_sig;
+
+ /**
+ * Public key of the coin.
+ */
+ struct TALER_CoinSpendPublicKeyP coin_pub;
+
+ /**
+ * Hash of the age commitment used to sign the coin, if age restriction was
+ * applicable to the denomination. May be all zeroes if no age restriction
+ * applies.
+ */
+ struct TALER_AgeCommitmentHash h_age_commitment;
+
+ /**
+ * Set to true if @e h_age_commitment is not available.
+ */
+ bool no_age_commitment;
+
+};
+
+/**
* Information about a melt operation.
*/
struct TALER_EXCHANGEDB_Melt
@@ -842,13 +2435,34 @@ struct TALER_EXCHANGEDB_LinkList
/**
* Signature over the blinded envelope.
*/
- struct TALER_DenominationSignature ev_sig;
+ struct TALER_BlindedDenominationSignature ev_sig;
+
+ /**
+ * Exchange-provided values during the coin generation.
+ */
+ struct TALER_ExchangeWithdrawValues alg_values;
/**
* Signature of the original coin being refreshed over the
* link data, of type #TALER_SIGNATURE_WALLET_COIN_LINK
*/
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
+
+ /**
+ * Session nonce, if cipher has one.
+ */
+ union GNUNET_CRYPTO_BlindSessionNonce nonce;
+
+ /**
+ * Offset that generated this coin in the refresh
+ * operation.
+ */
+ uint32_t coin_refresh_offset;
+
+ /**
+ * Set to true if @e nonce was initialized.
+ */
+ bool have_nonce;
};
@@ -887,7 +2501,22 @@ enum TALER_EXCHANGEDB_TransactionType
/**
* Recoup-refresh operation (on the new coin, eliminating its value)
*/
- TALER_EXCHANGEDB_TT_RECOUP_REFRESH = 5
+ TALER_EXCHANGEDB_TT_RECOUP_REFRESH = 5,
+
+ /**
+ * Purse deposit operation.
+ */
+ TALER_EXCHANGEDB_TT_PURSE_DEPOSIT = 6,
+
+ /**
+ * Purse deposit operation.
+ */
+ TALER_EXCHANGEDB_TT_PURSE_REFUND = 7,
+
+ /**
+ * Reserve open deposit operation.
+ */
+ TALER_EXCHANGEDB_TT_RESERVE_OPEN = 8
};
@@ -957,46 +2586,27 @@ struct TALER_EXCHANGEDB_TransactionList
*/
struct TALER_EXCHANGEDB_RecoupRefreshListEntry *recoup_refresh;
- } details;
-
-};
+ /**
+ * Coin was deposited into a purse.
+ * (#TALER_EXCHANGEDB_TT_PURSE_DEPOSIT)
+ */
+ struct TALER_EXCHANGEDB_PurseDepositListEntry *purse_deposit;
+ /**
+ * Coin was refunded upon purse expiration
+ * (#TALER_EXCHANGEDB_TT_PURSE_REFUND)
+ */
+ struct TALER_EXCHANGEDB_PurseRefundListEntry *purse_refund;
-/**
- * @brief Handle for a database session (per-thread, for transactions).
- */
-struct TALER_EXCHANGEDB_Session;
+ /**
+ * Coin was used to pay to open a reserve.
+ * (#TALER_EXCHANGEDB_TT_RESERVE_OPEN)
+ */
+ struct TALER_EXCHANGEDB_ReserveOpenListEntry *reserve_open;
+ } details;
-/**
- * Function called with details about deposits that have been made,
- * with the goal of executing the corresponding wire transaction.
- *
- * @param cls closure
- * @param rowid unique ID for the deposit in our DB, used for marking
- * it as 'tiny' or 'done'
- * @param merchant_pub public key of the merchant
- * @param coin_pub public key of the coin
- * @param amount_with_fee amount that was deposited including fee
- * @param deposit_fee amount the exchange gets to keep as transaction fees
- * @param h_contract_terms hash of the proposal data known to merchant and customer
- * @param wire_deadline by which the merchant advised that he would like the
- * wire transfer to be executed
- * @param receiver_wire_account wire details for the merchant, includes
- * 'url' in payto://-format; NULL from iterate_matching_deposits()
- * @return transaction status code, #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT to continue to iterate
- */
-typedef enum GNUNET_DB_QueryStatus
-(*TALER_EXCHANGEDB_DepositIterator)(
- void *cls,
- uint64_t rowid,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *deposit_fee,
- const struct GNUNET_HashCode *h_contract_terms,
- struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *receiver_wire_account);
+};
/**
@@ -1017,42 +2627,200 @@ typedef void
/**
+ * Callback with KYC attributes about a particular user.
+ *
+ * @param cls closure
+ * @param h_payto account for which the attribute data is stored
+ * @param provider_section provider that must be checked
+ * @param collection_time when was the data collected
+ * @param expiration_time when does the data expire
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ */
+typedef void
+(*TALER_EXCHANGEDB_AttributeCallback)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *provider_section,
+ struct GNUNET_TIME_Timestamp collection_time,
+ struct GNUNET_TIME_Timestamp expiration_time,
+ size_t enc_attributes_size,
+ const void *enc_attributes);
+
+
+/**
* Function called with details about deposits that have been made,
* with the goal of auditing the deposit's execution.
*
* @param cls closure
* @param rowid unique serial ID for the deposit in our DB
- * @param timestamp when did the deposit happen
- * @param merchant_pub public key of the merchant
+ * @param exchange_timestamp when did the deposit happen
+ * @param deposit deposit details
* @param denom_pub denomination public key of @a coin_pub
- * @param coin_pub public key of the coin
- * @param coin_sig signature from the coin
- * @param amount_with_fee amount that was deposited including fee
- * @param h_contract_terms hash of the proposal data known to merchant and customer
- * @param refund_deadline by which the merchant advised that he might want
- * to get a refund
- * @param wire_deadline by which the merchant advised that he would like the
- * wire transfer to be executed
- * @param receiver_wire_account wire details for the merchant including 'url' in payto://-format;
- * NULL from iterate_matching_deposits()
* @param done flag set if the deposit was already executed (or not)
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_DepositCallback)(
void *cls,
uint64_t rowid,
- struct GNUNET_TIME_Absolute timestamp,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
+ const struct TALER_EXCHANGEDB_Deposit *deposit,
const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_CoinSpendSignatureP *coin_sig,
+ bool done);
+
+
+/**
+ * Function called with details about purse deposits that have been made, with
+ * the goal of auditing the deposit's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param deposit deposit details
+ * @param reserve_pub which reserve is the purse merged into, NULL if unknown
+ * @param flags purse flags
+ * @param auditor_balance purse balance (according to the
+ * auditor during auditing)
+ * @param purse_total target amount the purse should reach
+ * @param denom_pub denomination public key of @a coin_pub
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_PurseDepositCallback)(
+ void *cls,
+ uint64_t rowid,
+ const struct TALER_EXCHANGEDB_PurseDeposit *deposit,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_Amount *auditor_balance,
+ const struct TALER_Amount *purse_total,
+ const struct TALER_DenominationPublicKey *denom_pub);
+
+
+/**
+ * Function called with details about
+ * account merge requests that have been made, with
+ * the goal of auditing the account merge execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param reserve_pub reserve affected by the merge
+ * @param purse_pub purse being merged
+ * @param h_contract_terms hash over contract of the purse
+ * @param purse_expiration when would the purse expire
+ * @param amount total amount in the purse
+ * @param min_age minimum age of all coins deposited into the purse
+ * @param flags how was the purse created
+ * @param purse_fee if a purse fee was paid, how high is it
+ * @param merge_timestamp when was the merge approved
+ * @param reserve_sig signature by reserve approving the merge
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_AccountMergeCallback)(
+ void *cls,
+ uint64_t rowid,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_Amount *amount,
+ uint32_t min_age,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_Amount *purse_fee,
+ struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_ReserveSignatureP *reserve_sig);
+
+
+/**
+ * Function called with details about purse
+ * merges that have been made, with
+ * the goal of auditing the purse merge execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param partner_base_url where is the reserve, NULL for this exchange
+ * @param amount total amount expected in the purse
+ * @param balance current balance in the purse (according to the auditor)
+ * @param flags purse flags
+ * @param merge_pub merge capability key
+ * @param reserve_pub reserve the merge affects
+ * @param merge_sig signature affirming the merge
+ * @param purse_pub purse key
+ * @param merge_timestamp when did the merge happen
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_PurseMergeCallback)(
+ void *cls,
+ uint64_t rowid,
+ const char *partner_base_url,
+ const struct TALER_Amount *amount,
+ const struct TALER_Amount *balance,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_PurseMergeSignatureP *merge_sig,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Timestamp merge_timestamp);
+
+
+/**
+ * Function called with details about purse decisions that have been made, with
+ * the goal of auditing the purse's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param purse_pub public key of the purse
+ * @param reserve_pub public key of the target reserve, NULL if not known / refunded
+ * @param purse_value what is the (target) value of the purse
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_PurseDecisionCallback)(
+ void *cls,
+ uint64_t rowid,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *purse_value);
+
+
+/**
+ * Function called with details about purse decisions that have been made, with
+ * the goal of auditing the purse's execution.
+ *
+ * @param cls closure
+ * @param rowid unique serial ID for the deposit in our DB
+ * @param purse_pub public key of the purse
+ * @param refunded true if decision was to refund
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_AllPurseDecisionCallback)(
+ void *cls,
+ uint64_t rowid,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ bool refunded);
+
+
+/**
+ * Function called with details about purse refunds that have been made, with
+ * the goal of auditing the purse refund's execution.
+ *
+ * @param cls closure
+ * @param rowid row of the refund event
+ * @param amount_with_fee amount of the deposit into the purse
+ * @param coin_pub coin that is to be refunded the @a given amount_with_fee
+ * @param denom_pub denomination of @a coin_pub
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_PurseRefundCoinCallback)(
+ void *cls,
+ uint64_t rowid,
const struct TALER_Amount *amount_with_fee,
- const struct GNUNET_HashCode *h_contract_terms,
- struct GNUNET_TIME_Absolute refund_deadline,
- struct GNUNET_TIME_Absolute wire_deadline,
- const json_t *receiver_wire_account,
- int done);
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_DenominationPublicKey *denom_pub);
/**
@@ -1062,6 +2830,7 @@ typedef int
* @param cls closure
* @param rowid unique serial ID for the refresh session in our DB
* @param denom_pub denomination public key of @a coin_pub
+ * @param h_age_commitment age commitment that went into the signing of the coin, may be NULL
* @param coin_pub public key of the coin
* @param coin_sig signature from the coin
* @param amount_with_fee amount that was deposited including fee
@@ -1069,11 +2838,12 @@ typedef int
* @param rc what is the commitment
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_RefreshesCallback)(
void *cls,
uint64_t rowid,
const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_AgeCommitmentHash *h_age_commitment,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,
const struct TALER_Amount *amount_with_fee,
@@ -1089,7 +2859,7 @@ typedef int
* @param amount_with_fee amount being refunded
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_RefundCoinCallback)(
void *cls,
const struct TALER_Amount *amount_with_fee);
@@ -1102,9 +2872,9 @@ typedef int
struct TALER_EXCHANGEDB_RefreshRevealedCoin
{
/**
- * Public denomination key of the coin.
+ * Hash of the public denomination key of the coin.
*/
- struct TALER_DenominationPublicKey denom_pub;
+ struct TALER_DenominationHashP h_denom_pub;
/**
* Signature of the original coin being refreshed over the
@@ -1113,41 +2883,117 @@ struct TALER_EXCHANGEDB_RefreshRevealedCoin
struct TALER_CoinSpendSignatureP orig_coin_link_sig;
/**
- * Blinded message to be signed (in envelope), with @e coin_env_size bytes.
+ * Hash of the blinded new coin, that is @e coin_ev.
*/
- char *coin_ev;
+ struct TALER_BlindedCoinHashP coin_envelope_hash;
/**
- * Number of bytes in @e coin_ev.
+ * Signature generated by the exchange over the coin (in blinded format).
*/
- size_t coin_ev_size;
+ struct TALER_BlindedDenominationSignature coin_sig;
/**
- * Signature generated by the exchange over the coin (in blinded format).
+ * Values contributed from the exchange to the
+ * coin generation (see /csr).
*/
- struct TALER_DenominationSignature coin_sig;
+ struct TALER_ExchangeWithdrawValues exchange_vals;
+
+ /**
+ * Blinded message to be signed (in envelope).
+ */
+ struct TALER_BlindedPlanchet blinded_planchet;
+
};
/**
+ * Information per Clause-Schnorr (CS) fresh coin to
+ * be persisted for idempotency during refreshes-reveal.
+ */
+struct TALER_EXCHANGEDB_CsRevealFreshCoinData
+{
+ /**
+ * Denomination of the fresh coin.
+ */
+ struct TALER_DenominationHashP new_denom_pub_hash;
+
+ /**
+ * Blind signature of the fresh coin (possibly updated
+ * in case if a replay!).
+ */
+ struct TALER_BlindedDenominationSignature bsig;
+
+ /**
+ * Offset of the fresh coin in the reveal operation.
+ * (May not match the array offset as we may have
+ * a mixture of RSA and CS coins being created, and
+ * this request is only made for the CS subset).
+ */
+ uint32_t coin_off;
+};
+
+
+/**
+ * Generic KYC status for some operation.
+ */
+struct TALER_EXCHANGEDB_KycStatus
+{
+ /**
+ * Number that identifies the KYC requirement the operation
+ * was about.
+ */
+ uint64_t requirement_row;
+
+ /**
+ * True if the KYC status is "satisfied".
+ */
+ bool ok;
+
+};
+
+
+struct TALER_EXCHANGEDB_ReserveInInfo
+{
+ const struct TALER_ReservePublicKeyP *reserve_pub;
+ const struct TALER_Amount *balance;
+ struct GNUNET_TIME_Timestamp execution_time;
+ const char *sender_account_details;
+ const char *exchange_account_name;
+ uint64_t wire_reference;
+};
+
+
+/**
+ * Function called on each @a amount that was found to
+ * be relevant for a KYC check.
+ *
+ * @param cls closure to allow the KYC module to
+ * total up amounts and evaluate rules
+ * @param amount encountered transaction amount
+ * @param date when was the amount encountered
+ * @return #GNUNET_OK to continue to iterate,
+ * #GNUNET_NO to abort iteration
+ * #GNUNET_SYSERR on internal error (also abort itaration)
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_KycAmountCallback)(
+ void *cls,
+ const struct TALER_Amount *amount,
+ struct GNUNET_TIME_Absolute date);
+
+
+/**
* Function called with information about a refresh order.
*
* @param cls closure
- * @param rowid unique serial ID for the row in our database
* @param num_freshcoins size of the @a rrcs array
* @param rrcs array of @a num_freshcoins information about coins to be created
- * @param num_tprivs number of entries in @a tprivs, should be #TALER_CNC_KAPPA - 1
- * @param tprivs array of @e num_tprivs transfer private keys
- * @param tp transfer public key information
*/
typedef void
(*TALER_EXCHANGEDB_RefreshCallback)(
void *cls,
uint32_t num_freshcoins,
- const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs,
- unsigned int num_tprivs,
- const struct TALER_TransferPrivateKeyP *tprivs,
- const struct TALER_TransferPublicKeyP *tp);
+ const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs);
/**
@@ -1162,10 +3008,11 @@ typedef void
* @param merchant_sig signature of the merchant
* @param h_contract_terms hash of the proposal data known to merchant and customer
* @param rtransaction_id refund transaction ID chosen by the merchant
+ * @param full_refund true if the refunds total up to the entire value of the deposit
* @param amount_with_fee amount that was deposited including fee
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_RefundCallback)(
void *cls,
uint64_t rowid,
@@ -1173,8 +3020,9 @@ typedef int
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
const struct TALER_MerchantSignatureP *merchant_sig,
- const struct GNUNET_HashCode *h_contract_terms,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
uint64_t rtransaction_id,
+ bool full_refund,
const struct TALER_Amount *amount_with_fee);
@@ -1183,14 +3031,14 @@ typedef int
*
* @param cls closure
* @param rowid unique serial ID for the refresh session in our DB
- * @param reserve_pub public key of the reserve (also the WTID)
+ * @param reserve_pub public key of the reserve (also the wire subject)
* @param credit amount that was received
* @param sender_account_details information about the sender's bank account, in payto://-format
* @param wire_reference unique identifier for the wire transfer
* @param execution_date when did we receive the funds
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_ReserveInCallback)(
void *cls,
uint64_t rowid,
@@ -1198,7 +3046,76 @@ typedef int
const struct TALER_Amount *credit,
const char *sender_account_details,
uint64_t wire_reference,
- struct GNUNET_TIME_Absolute execution_date);
+ struct GNUNET_TIME_Timestamp execution_date);
+
+
+/**
+ * Provide information about a wire account.
+ *
+ * @param cls closure
+ * @param payto_uri the exchange bank account URI
+ * @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param debit_restrictions JSON array with debit restrictions on the account
+ * @param credit_restrictions JSON array with credit restrictions on the account
+ * @param master_sig master key signature affirming that this is a bank
+ * account of the exchange (of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS)
+ * @param bank_label label the wallet should use to display the account, can be NULL
+ * @param priority priority for ordering bank account labels
+ */
+typedef void
+(*TALER_EXCHANGEDB_WireAccountCallback)(
+ void *cls,
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ const struct TALER_MasterSignatureP *master_sig,
+ const char *bank_label,
+ int64_t priority);
+
+
+/**
+ * Provide information about wire fees.
+ *
+ * @param cls closure
+ * @param fees the wire fees we charge
+ * @param start_date from when are these fees valid (start date)
+ * @param end_date until when are these fees valid (end date, exclusive)
+ * @param master_sig master key signature affirming that this is the correct
+ * fee (of purpose #TALER_SIGNATURE_MASTER_WIRE_FEES)
+ */
+typedef void
+(*TALER_EXCHANGEDB_WireFeeCallback)(
+ void *cls,
+ const struct TALER_WireFeeSet *fees,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+/**
+ * Provide information about global fees.
+ *
+ * @param cls closure
+ * @param fees the global fees we charge
+ * @param purse_timeout when do purses time out
+ * @param history_expiration how long are account histories preserved
+ * @param purse_account_limit how many purses are free per account
+ * @param start_date from when are these fees valid (start date)
+ * @param end_date until when are these fees valid (end date, exclusive)
+ * @param master_sig master key signature affirming that this is the correct
+ * fee (of purpose #TALER_SIGNATURE_MASTER_GLOBAL_FEES)
+ */
+typedef void
+(*TALER_EXCHANGEDB_GlobalFeeCallback)(
+ void *cls,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_MasterSignatureP *master_sig);
/**
@@ -1214,15 +3131,15 @@ typedef int
* @param amount_with_fee amount that was withdrawn
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_WithdrawCallback)(
void *cls,
uint64_t rowid,
- const struct GNUNET_HashCode *h_blind_ev,
+ const struct TALER_BlindedCoinHashP *h_blind_ev,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_ReserveSignatureP *reserve_sig,
- struct GNUNET_TIME_Absolute execution_date,
+ struct GNUNET_TIME_Timestamp execution_date,
const struct TALER_Amount *amount_with_fee);
@@ -1242,37 +3159,14 @@ typedef void
/**
- * Function called with the results of the lookup of the wire transfer
- * identifier information. Only called if we are at least aware of the
- * transaction existing.
- *
- * @param cls closure
- * @param wtid wire transfer identifier, NULL
- * if the transaction was not yet done
- * @param coin_contribution how much did the coin we asked about
- * contribute to the total transfer value? (deposit value including fee)
- * @param coin_fee how much did the exchange charge for the deposit fee
- * @param execution_time when was the transaction done, or
- * when we expect it to be done (if @a wtid was NULL)
- */
-typedef void
-(*TALER_EXCHANGEDB_WireTransferByCoinCallback)(
- void *cls,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- const struct TALER_Amount *coin_contribution,
- const struct TALER_Amount *coin_fee,
- struct GNUNET_TIME_Absolute execution_time);
-
-
-/**
* Function called with the results of the lookup of the
* transaction data associated with a wire transfer identifier.
*
* @param cls closure
* @param rowid which row in the table is the information from (for diagnostics)
* @param merchant_pub public key of the merchant (should be same for all callbacks with the same @e cls)
- * @param h_wire hash of wire transfer details of the merchant (should be same for all callbacks with the same @e cls)
- * @param account_details which account did the transfer go to?
+ * @param account_payto_uri which account did the transfer go to?
+ * @param h_payto hash over @a account_payto_uri as it is in the DB
* @param exec_time execution time of the wire transfer (should be same for all callbacks with the same @e cls)
* @param h_contract_terms which proposal was this payment about
* @param denom_pub denomination of @a coin_pub
@@ -1285,10 +3179,10 @@ typedef void
void *cls,
uint64_t rowid,
const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_wire,
- const json_t *account_details,
- struct GNUNET_TIME_Absolute exec_time,
- const struct GNUNET_HashCode *h_contract_terms,
+ const char *account_payto_uri,
+ const struct TALER_PaytoHashP *h_payto,
+ struct GNUNET_TIME_Timestamp exec_time,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_Amount *coin_value,
@@ -1303,21 +3197,41 @@ typedef void
* @param rowid identifier of the respective row in the database
* @param date timestamp of the wire transfer (roughly)
* @param wtid wire transfer subject
- * @param wire wire transfer details of the receiver, including "url" in payto://-format
+ * @param payto_uri details of the receiver, URI in payto://-format
* @param amount amount that was wired
* @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_WireTransferOutCallback)(
void *cls,
uint64_t rowid,
- struct GNUNET_TIME_Absolute date,
+ struct GNUNET_TIME_Timestamp date,
const struct TALER_WireTransferIdentifierRawP *wtid,
- const json_t *wire,
+ const char *payto_uri,
const struct TALER_Amount *amount);
/**
+ * Function called on transient aggregations matching
+ * a particular hash of a payto URI.
+ *
+ * @param cls
+ * @param payto_uri corresponding payto URI
+ * @param wtid wire transfer identifier of transient aggregation
+ * @param merchant_pub public key of the merchant
+ * @param total amount aggregated so far
+ * @return true to continue iterating
+ */
+typedef bool
+(*TALER_EXCHANGEDB_TransientAggregationCallback)(
+ void *cls,
+ const char *payto_uri,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_Amount *total);
+
+
+/**
* Callback with data about a prepared wire transfer.
*
* @param cls closure
@@ -1328,7 +3242,7 @@ typedef int
* @param finished did we complete the transfer yet?
* @return #GNUNET_OK to continue, #GNUNET_SYSERR to stop iteration
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_WirePreparationCallback)(void *cls,
uint64_t rowid,
const char *wire_method,
@@ -1351,17 +3265,17 @@ typedef int
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_RecoupCallback)(
void *cls,
uint64_t rowid,
- struct GNUNET_TIME_Absolute timestamp,
+ struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *amount,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_DenominationBlindingKeyP *coin_blind);
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_blind);
/**
@@ -1380,18 +3294,45 @@ typedef int
* @param coin_blind blinding factor used to blind the coin
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_RecoupRefreshCallback)(
void *cls,
uint64_t rowid,
- struct GNUNET_TIME_Absolute timestamp,
+ struct GNUNET_TIME_Timestamp timestamp,
const struct TALER_Amount *amount,
const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
- const struct GNUNET_HashCode *old_denom_pub_hash,
+ const struct TALER_DenominationHashP *old_denom_pub_hash,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_DenominationPublicKey *denom_pub,
const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_DenominationBlindingKeyP *coin_blind);
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_blind);
+
+
+/**
+ * Function called about reserve opening operations.
+ *
+ * @param cls closure
+ * @param rowid row identifier used to uniquely identify the reserve closing operation
+ * @param reserve_payment how much to pay from the
+ * reserve's own balance for opening the reserve
+ * @param request_timestamp when was the request created
+ * @param reserve_expiration desired expiration time for the reserve
+ * @param purse_limit minimum number of purses the client
+ * wants to have concurrently open for this reserve
+ * @param reserve_pub public key of the reserve
+ * @param reserve_sig signature affirming the operation
+ * @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_ReserveOpenCallback)(
+ void *cls,
+ uint64_t rowid,
+ const struct TALER_Amount *reserve_payment,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ struct GNUNET_TIME_Timestamp reserve_expiration,
+ uint32_t purse_limit,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_ReserveSignatureP *reserve_sig);
/**
@@ -1406,21 +3347,36 @@ typedef int
* @param reserve_pub public key of the reserve
* @param receiver_account where did we send the funds, in payto://-format
* @param wtid identifier used for the wire transfer
+ * @param close_request_row row with the responsible close
+ * request, 0 if regular expiration triggered close
* @return #GNUNET_OK to continue to iterate, #GNUNET_SYSERR to stop
*/
-typedef int
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_ReserveClosedCallback)(
void *cls,
uint64_t rowid,
- struct GNUNET_TIME_Absolute execution_date,
+ struct GNUNET_TIME_Timestamp execution_date,
const struct TALER_Amount *amount_with_fee,
const struct TALER_Amount *closing_fee,
const struct TALER_ReservePublicKeyP *reserve_pub,
const char *receiver_account,
- const struct TALER_WireTransferIdentifierRawP *wtid);
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ uint64_t close_request_row);
/**
+ * Function called with the amounts historically
+ * withdrawn from the same origin account.
+ *
+ * @param cls closure
+ * @param val one of the withdrawn amounts
+ */
+typedef void
+(*TALER_EXCHANGEDB_WithdrawHistoryCallback)(
+ void *cls,
+ const struct TALER_Amount *val);
+
+/**
* Function called with details about expired reserves.
*
* @param cls closure
@@ -1428,15 +3384,20 @@ typedef int
* @param left amount left in the reserve
* @param account_details information about the reserve's bank account, in payto://-format
* @param expiration_date when did the reserve expire
- * @return transaction status code to pass on
+ * @param close_request_row row that caused the reserve
+ * to be closed, 0 if it expired without request
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO to retry
+ * #GNUNET_SYSERR on hard failures (exit)
*/
-typedef enum GNUNET_DB_QueryStatus
+typedef enum GNUNET_GenericReturnValue
(*TALER_EXCHANGEDB_ReserveExpiredCallback)(
void *cls,
const struct TALER_ReservePublicKeyP *reserve_pub,
const struct TALER_Amount *left,
const char *account_details,
- struct GNUNET_TIME_Absolute expiration_date);
+ struct GNUNET_TIME_Timestamp expiration_date,
+ uint64_t close_request_row);
/**
@@ -1448,7 +3409,7 @@ typedef enum GNUNET_DB_QueryStatus
* @param coin information about the coin
* @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
* @param coin_blind blinding key of the coin
- * @param h_blind_ev blinded envelope, as calculated by the exchange
+ * @param h_blinded_ev blinded envelope, as calculated by the exchange
* @param amount total amount to be paid back
*/
typedef void
@@ -1457,49 +3418,128 @@ typedef void
uint64_t rowid,
const struct TALER_CoinPublicInfo *coin,
const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_DenominationBlindingKeyP *coin_blind,
- const struct GNUNET_HashCode *h_blinded_ev,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_blind,
+ const struct TALER_BlindedCoinHashP *h_blinded_ev,
const struct TALER_Amount *amount);
/**
- * Function called on deposits that are past their due date
- * and have not yet seen a wire transfer.
+ * Function called on (batch) deposits will need a wire
+ * transfer.
*
* @param cls closure
- * @param rowid deposit table row of the coin's deposit
- * @param coin_pub public key of the coin
- * @param amount value of the deposit, including fee
- * @param wire where should the funds be wired, including 'url' in payto://-format
- * @param deadline what was the requested wire transfer deadline
- * @param tiny did the exchange defer this transfer because it is too small?
- * @param done did the exchange claim that it made a transfer?
+ * @param batch_deposit_serial_id where in the table are we
+ * @param total_amount value of all missing deposits, including fees
+ * @param wire_target_h_payto hash of the recipient account's payto URI
+ * @param deadline what was the earliest requested wire transfer deadline
*/
typedef void
(*TALER_EXCHANGEDB_WireMissingCallback)(
void *cls,
+ uint64_t batch_deposit_serial_id,
+ const struct TALER_Amount *total_amount,
+ const struct TALER_PaytoHashP *wire_target_h_payto,
+ struct GNUNET_TIME_Timestamp deadline);
+
+
+/**
+ * Function called on aggregations that were done for
+ * a (batch) deposit.
+ *
+ * @param cls closure
+ * @param tracking_serial_id where in the table are we
+ * @param batch_deposit_serial_id which batch deposit was aggregated
+ */
+typedef void
+(*TALER_EXCHANGEDB_AggregationCallback)(
+ void *cls,
+ uint64_t tracking_serial_id,
+ uint64_t batch_deposit_serial_id);
+
+
+/**
+ * Function called on purse requests.
+ *
+ * @param cls closure
+ * @param rowid purse request table row of the purse
+ * @param purse_pub public key of the purse
+ * @param merge_pub public key representing the merge capability
+ * @param purse_creation when was the purse created?
+ * @param purse_expiration when would an unmerged purse expire
+ * @param h_contract_terms contract associated with the purse
+ * @param age_limit the age limit for deposits into the purse
+ * @param target_amount amount to be put into the purse
+ * @param purse_sig signature of the purse over the initialization data
+ * @return #GNUNET_OK to continue to iterate
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_EXCHANGEDB_PurseRequestCallback)(
+ void *cls,
uint64_t rowid,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_Amount *amount,
- const json_t *wire,
- struct GNUNET_TIME_Absolute deadline,
- /* bool? */ int tiny,
- /* bool? */ int done);
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ struct GNUNET_TIME_Timestamp purse_creation,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint32_t age_limit,
+ const struct TALER_Amount *target_amount,
+ const struct TALER_PurseContractSignatureP *purse_sig);
/**
* Function called with information about the exchange's denomination keys.
+ * Note that the 'master' field in @a issue will not yet be initialized when
+ * this function is called!
*
* @param cls closure
* @param denom_pub public key of the denomination
- * @param issue detailed information about the denomination (value, expiration times, fees)
+ * @param issue detailed information about the denomination (value, expiration times, fees);
*/
typedef void
(*TALER_EXCHANGEDB_DenominationCallback)(
void *cls,
- const struct
- TALER_DenominationPublicKey *denom_pub,
- const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue);
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue);
+
+
+/**
+ * Return AML status.
+ *
+ * @param cls closure
+ * @param row_id current row in AML status table
+ * @param h_payto account for which the attribute data is stored
+ * @param threshold currently monthly threshold that would trigger an AML check
+ * @param status what is the current AML decision
+ */
+typedef void
+(*TALER_EXCHANGEDB_AmlStatusCallback)(
+ void *cls,
+ uint64_t row_id,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_Amount *threshold,
+ enum TALER_AmlDecisionState status);
+
+
+/**
+ * Return historic AML decision.
+ *
+ * @param cls closure
+ * @param new_threshold new monthly threshold that would trigger an AML check
+ * @param new_status AML decision status
+ * @param decision_time when was the decision made
+ * @param justification human-readable text justifying the decision
+ * @param decider_pub public key of the staff member
+ * @param decider_sig signature of the staff member
+ */
+typedef void
+(*TALER_EXCHANGEDB_AmlHistoryCallback)(
+ void *cls,
+ const struct TALER_Amount *new_threshold,
+ enum TALER_AmlDecisionState new_status,
+ struct GNUNET_TIME_Timestamp decision_time,
+ const char *justification,
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+ const struct TALER_AmlOfficerSignatureP *decider_sig);
/**
@@ -1520,16 +3560,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
char *library_name;
- /**
- * Get the thread-local (!) database-handle.
- * Connect to the db if the connection does not exist yet.
- *
- * @param cls the @e cls of this struct with the plugin-specific state
- * @returns the database connection, or NULL on error
- */
- struct TALER_EXCHANGEDB_Session *
- (*get_session) (void *cls);
-
/**
* Drop the Taler tables. This should only be used in testcases.
@@ -1537,45 +3567,71 @@ struct TALER_EXCHANGEDB_Plugin
* @param cls the @e cls of this struct with the plugin-specific state
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
- int
- (*drop_tables) (void *cls);
-
+ enum GNUNET_GenericReturnValue
+ (*drop_tables)(void *cls);
/**
* Create the necessary tables if they are not present
*
* @param cls the @e cls of this struct with the plugin-specific state
+ * @param support_partitions true to enable partitioning support (disables foreign key constraints)
+ * @param num_partitions number of partitions to create,
+ * (0 to not actually use partitions, 1 to only
+ * setup a default partition, >1 for real partitions)
* @return #GNUNET_OK upon success; #GNUNET_SYSERR upon failure
*/
- int
- (*create_tables) (void *cls);
+ enum GNUNET_GenericReturnValue
+ (*create_tables)(void *cls,
+ bool support_partitions,
+ uint32_t num_partitions);
/**
* Start a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param name unique name identifying the transaction (for debugging),
* must point to a constant
* @return #GNUNET_OK on success
*/
- int
- (*start) (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const char *name);
+ enum GNUNET_GenericReturnValue
+ (*start)(void *cls,
+ const char *name);
+
+
+ /**
+ * Start a READ COMMITTED transaction.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging)
+ * must point to a constant
+ * @return #GNUNET_OK on success
+ */
+ enum GNUNET_GenericReturnValue
+ (*start_read_committed)(void *cls,
+ const char *name);
+
+ /**
+ * Start a READ ONLY serializable transaction.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param name unique name identifying the transaction (for debugging)
+ * must point to a constant
+ * @return #GNUNET_OK on success
+ */
+ enum GNUNET_GenericReturnValue
+ (*start_read_only)(void *cls,
+ const char *name);
/**
* Commit a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*commit)(void *cls,
- struct TALER_EXCHANGEDB_Session *session);
+ (*commit)(void *cls);
/**
@@ -1584,22 +3640,65 @@ struct TALER_EXCHANGEDB_Plugin
* Does not return anything, as we will continue regardless of the outcome.
*
* @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session the database connection
+ * @return #GNUNET_OK if everything is fine
+ * #GNUNET_NO if a transaction was rolled back
+ * #GNUNET_SYSERR on hard errors
*/
- void
- (*preflight) (void *cls,
- struct TALER_EXCHANGEDB_Session *session);
+ enum GNUNET_GenericReturnValue
+ (*preflight)(void *cls);
/**
* Abort/rollback a transaction.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
*/
void
- (*rollback) (void *cls,
- struct TALER_EXCHANGEDB_Session *session);
+ (*rollback) (void *cls);
+
+
+ /**
+ * Register callback to be invoked on events of type @a es.
+ *
+ * @param cls database context to use
+ * @param timeout how long to wait at most
+ * @param es specification of the event to listen for
+ * @param cb function to call when the event happens, possibly
+ * multiple times (until cancel is invoked)
+ * @param cb_cls closure for @a cb
+ * @return handle useful to cancel the listener
+ */
+ struct GNUNET_DB_EventHandler *
+ (*event_listen)(void *cls,
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_DB_EventHeaderP *es,
+ GNUNET_DB_EventCallback cb,
+ void *cb_cls);
+
+ /**
+ * Stop notifications.
+ *
+ * @param cls database context to use
+ * @param eh handle to unregister.
+ */
+ void
+ (*event_listen_cancel)(void *cls,
+ struct GNUNET_DB_EventHandler *eh);
+
+
+ /**
+ * Notify all that listen on @a es of an event.
+ *
+ * @param cls database context to use
+ * @param es specification of the event to generate
+ * @param extra additional event data provided
+ * @param extra_size number of bytes in @a extra
+ */
+ void
+ (*event_notify)(void *cls,
+ const struct GNUNET_DB_EventHeaderP *es,
+ const void *extra,
+ size_t extra_size);
/**
@@ -1608,7 +3707,6 @@ struct TALER_EXCHANGEDB_Plugin
* with this key have.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param denom_pub the public key used for signing coins of this denomination
* @param issue issuing information with value, fees and other info about the denomination
* @return status of the query
@@ -1616,16 +3714,14 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_denomination_info)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_DenominationPublicKey *denom_pub,
- const struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue);
+ const struct TALER_EXCHANGEDB_DenominationKeyInformation *issue);
/**
* Fetch information about a denomination key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param denom_pub_hash hash of the public key used for signing coins of this denomination
* @param[out] issue set to issue information with value, fees and other info about the coin
* @return transaction status code
@@ -1633,14 +3729,15 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*get_denomination_info)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
- struct TALER_EXCHANGEDB_DenominationKeyInformationP *issue);
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ struct TALER_EXCHANGEDB_DenominationKeyInformation *issue);
/**
* Function called on every known denomination key. Runs in its
- * own read-only transaction (hence no session provided).
+ * own read-only transaction (hence no session provided). Note that
+ * the "master" field in the callback's 'issue' argument will NOT
+ * be initialized yet.
*
* @param cls the @e cls of this struct with the plugin-specific state
* @param cb function to call on each denomination key
@@ -1652,11 +3749,74 @@ struct TALER_EXCHANGEDB_Plugin
TALER_EXCHANGEDB_DenominationCallback cb,
void *cb_cls);
+
+ /**
+ * Function called to invoke @a cb on every known denomination key (revoked
+ * and non-revoked) that has been signed by the master key. Runs in its own
+ * read-only transaction.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param cb function to call on each denomination key
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_denominations)(void *cls,
+ TALER_EXCHANGEDB_DenominationsCallback cb,
+ void *cb_cls);
+
+ /**
+ * Function called to invoke @a cb on every non-revoked exchange signing key
+ * that has been signed by the master key. Revoked and (for signing!)
+ * expired keys are skipped. Runs in its own read-only transaction.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param cb function to call on each signing key
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_active_signkeys)(void *cls,
+ TALER_EXCHANGEDB_ActiveSignkeysCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Function called to invoke @a cb on every active auditor. Disabled
+ * auditors are skipped. Runs in its own read-only transaction.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param cb function to call on each active auditor
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_active_auditors)(void *cls,
+ TALER_EXCHANGEDB_AuditorsCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Function called to invoke @a cb on every denomination with an active
+ * auditor. Disabled auditors and denominations without auditor are
+ * skipped. Runs in its own read-only transaction.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param cb function to call on each active auditor-denomination pair
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_auditor_denominations)(
+ void *cls,
+ TALER_EXCHANGEDB_AuditorDenominationsCallback cb,
+ void *cb_cls);
+
+
/**
* Get the summary of a reserve.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session the database connection handle
* @param[in,out] reserve the reserve data. The public key of the reserve should be set
* in this structure; it is used to query the database. The balance
* and expiration are then filled accordingly.
@@ -1664,107 +3824,447 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*reserves_get)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
struct TALER_EXCHANGEDB_Reserve *reserve);
/**
- * Insert a incoming transaction into reserves. New reserves are
+ * Get the origin of funds of a reserve.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param reserve_pub public key of the reserve
+ * @param[out] h_payto set to hash of the wire source payto://-URI
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*reserves_get_origin)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_PaytoHashP *h_payto);
+
+
+ /**
+ * Extract next KYC alert. Deletes the alert.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param trigger_type which type of alert to drain
+ * @param[out] h_payto set to hash of payto-URI where KYC status changed
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*drain_kyc_alert)(void *cls,
+ uint32_t trigger_type,
+ struct TALER_PaytoHashP *h_payto);
+
+
+ /**
+ * Insert a batch of incoming transaction into reserves. New reserves are
* also created through this function.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session the database session handle
- * @param reserve_pub public key of the reserve
- * @param balance the amount that has to be added to the reserve
- * @param execution_time when was the amount added
- * @param sender_account_details information about the sender's bank account, in payto://-format
- * @param wire_reference unique reference identifying the wire transfer
- * @return transaction status code
+ * @param reserves
+ * @param reserves_length length of the @a reserves array
+ * @param[out] results array of transaction status codes of length @a reserves_length,
+ * set to the status of the
*/
enum GNUNET_DB_QueryStatus
- (*reserves_in_insert)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_Amount *balance,
- struct GNUNET_TIME_Absolute execution_time,
- const char *sender_account_details,
- const char *exchange_account_name,
- uint64_t wire_reference);
+ (*reserves_in_insert)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_ReserveInInfo *reserves,
+ unsigned int reserves_length,
+ enum GNUNET_DB_QueryStatus *results);
/**
- * Obtain the most recent @a wire_reference that was inserted via @e reserves_in_insert.
- * Used by the wirewatch process when resuming.
+ * Locate a nonce for use with a particular public key.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session the database connection handle
- * @param exchange_account_name name of the section in the exchange's configuration
- * for the account that we are tracking here
- * @param[out] wire_reference set to unique reference identifying the wire transfer
- * @return transaction status code
+ * @param nonce the nonce to be locked
+ * @param denom_pub_hash hash of the public key of the denomination
+ * @param target public key the nonce is to be locked to
+ * @return statement execution status
*/
enum GNUNET_DB_QueryStatus
- (*get_latest_reserve_in_reference)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const char *exchange_account_name,
- uint64_t *wire_reference);
+ (*lock_nonce)(void *cls,
+ const struct GNUNET_CRYPTO_CsSessionNonce *nonce,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ const union TALER_EXCHANGEDB_NonceLockTargetP *target);
/**
- * Locate the response for a withdraw request under the
- * key of the hash of the blinded message. Used to ensure
- * idempotency of the request.
+ * Locate the response for a withdraw request under a hash that uniquely
+ * identifies the withdraw operation. Used to ensure idempotency of the
+ * request.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection to use
- * @param h_blind hash of the blinded coin to be signed (will match
- * `h_coin_envelope` in the @a collectable to be returned)
- * @param collectable corresponding collectable coin (blind signature)
+ * @param bch hash that uniquely identifies the withdraw operation
+ * @param[out] collectable corresponding collectable coin (blind signature)
* if a coin is found
* @return statement execution status
*/
enum GNUNET_DB_QueryStatus
(*get_withdraw_info)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *h_blind,
- struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable);
+ const struct TALER_BlindedCoinHashP *bch,
+ struct TALER_EXCHANGEDB_CollectableBlindcoin *
+ collectable);
/**
- * Store collectable coin under the corresponding hash of the blinded
- * message.
+ * FIXME: merge do_batch_withdraw and do_batch_withdraw_insert into one API,
+ * which takes as input (among others)
+ * - denom_serial[]
+ * - blinded_coin_evs[]
+ * - denom_sigs[]
+ * The implementation should persist the data as _arrays_ in the DB.
+ */
+
+ /**
+ * Perform reserve update as part of a batch withdraw operation, checking
+ * for sufficient balance. Persisting the withdrawal details is done
+ * separately!
*
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection to use
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param now current time (rounded)
+ * @param reserve_pub public key of the reserve to debit
+ * @param amount total amount to withdraw
+ * @param do_age_check if set, the batch-withdrawal can only succeed when the reserve has no age restriction (birthday) set.
+ * @param[out] found set to true if the reserve was found
+ * @param[out] balance_ok set to true if the balance was sufficient
+ * @param[out] reserve_balance set to original balance of the reserve
+ * @param[out] age_ok set to true if no age requirements were defined on the reserve or @e do_age_check was false
+ * @param[out] allowed_maximum_age when @e age_ok is false, set to the allowed maximum age for withdrawal from the reserve. The client MUST then use the age-withdraw endpoint
+ * @param[out] ruuid set to the reserve's UUID (reserves table row)
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_batch_withdraw)(
+ void *cls,
+ struct GNUNET_TIME_Timestamp now,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *amount,
+ bool do_age_check,
+ bool *found,
+ bool *balance_ok,
+ struct TALER_Amount *reserve_balance,
+ bool *age_ok,
+ uint16_t *allowed_maximum_age,
+ uint64_t *ruuid);
+
+
+ /**
+ * Perform insert as part of a batch withdraw operation, and persisting the
+ * withdrawal details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param nonce client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals
* @param collectable corresponding collectable coin (blind signature)
- * if a coin is found
+ * @param now current time (rounded)
+ * @param ruuid reserve UUID
+ * @param[out] denom_unknown set if the denomination is unknown in the DB
+ * @param[out] conflict if the envelope was already in the DB
+ * @param[out] nonce_reuse if @a nonce was non-NULL and reused
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_batch_withdraw_insert)(
+ void *cls,
+ const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
+ const struct TALER_EXCHANGEDB_CollectableBlindcoin *collectable,
+ struct GNUNET_TIME_Timestamp now,
+ uint64_t ruuid,
+ bool *denom_unknown,
+ bool *conflict,
+ bool *nonce_reuse);
+
+ /**
+ * Locate the response for a age-withdraw request under a hash of the
+ * commitment and reserve_pub that uniquely identifies the age-withdraw
+ * operation. Used to ensure idempotency of the request.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param reserve_pub public key of the reserve for which the age-withdraw request is made
+ * @param ach hash that uniquely identifies the age-withdraw operation
+ * @param[out] aw corresponding details of the previous age-withdraw request if an entry was found
* @return statement execution status
*/
enum GNUNET_DB_QueryStatus
- (*insert_withdraw_info)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct
- TALER_EXCHANGEDB_CollectableBlindcoin *collectable);
+ (*get_age_withdraw)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_AgeWithdrawCommitmentHashP *ach,
+ struct TALER_EXCHANGEDB_AgeWithdraw *aw);
+
+ /**
+ * Perform an age-withdraw operation, checking for sufficient balance and
+ * fulfillment of age requirements and possibly persisting the withdrawal
+ * details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param commitment corresponding commitment for the age-withdraw
+ * @param[out] found set to true if the reserve was found
+ * @param[out] balance_ok set to true if the balance was sufficient
+ * @param[out] reserve_balance set to original balance of the reserve
+ * @param[out] age_ok set to true if age requirements were met
+ * @param[out] allowed_maximum_age if @e age_ok is FALSE, this is set to the allowed maximum age
+ * @param[out] reserve_birthday if @e age_ok is FALSE, this is set to the reserve's birthday
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_age_withdraw)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_AgeWithdraw *commitment,
+ struct GNUNET_TIME_Timestamp now,
+ bool *found,
+ bool *balance_ok,
+ struct TALER_Amount *reserve_balance,
+ bool *age_ok,
+ uint16_t *allowed_maximum_age,
+ uint32_t *reserve_birthday,
+ bool *conflict);
+
+ /**
+ * Retrieve the details to a policy given by its hash_code
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param hc Hash code that identifies the policy
+ * @param[out] detail retrieved policy details
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_policy_details)(
+ void *cls,
+ const struct GNUNET_HashCode *hc,
+ struct TALER_PolicyDetails *detail);
+
+ /**
+ * Persist the policy details that extends a deposit. The particular policy
+ * - referenced by details->hash_code - might already exist in the table, in
+ * which case the call will update the contents of the record with @e details
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param details The parsed `struct TALER_PolicyDetails` according to the responsible policy extension.
+ * @param[out] policy_details_serial_id The ID of the entry in the policy_details table
+ * @param[out] accumulated_total The total amount accumulated in that policy
+ * @param[out] fulfillment_state The state of policy. If the state was Insufficient prior to the call and the provided deposit raises the accumulated_total above the commitment, it will be set to Ready.
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*persist_policy_details)(
+ void *cls,
+ const struct TALER_PolicyDetails *details,
+ uint64_t *policy_details_serial_id,
+ struct TALER_Amount *accumulated_total,
+ enum TALER_PolicyFulfillmentState *fulfillment_state);
/**
- * Get all of the transaction history associated with the specified
- * reserve.
+ * Perform deposit operation, checking for sufficient balance
+ * of the coin and possibly persisting the deposit details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param bd batch deposit operation details
+ * @param[in,out] exchange_timestamp time to use for the deposit (possibly updated)
+ * @param[out] balance_ok set to true if the balance was sufficient
+ * @param[out] bad_balance_index set to the first index of a coin for which the balance was insufficient,
+ * only used if @a balance_ok is set to false.
+ * @param[out] ctr_conflict set to true if the same contract terms hash was previously submitted with other meta data (deadlines, wallet_data_hash, wire data etc.)
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_deposit)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_BatchDeposit *bd,
+ struct GNUNET_TIME_Timestamp *exchange_timestamp,
+ bool *balance_ok,
+ uint32_t *bad_balance_index,
+ bool *ctr_conflict);
+
+
+ /**
+ * Perform melt operation, checking for sufficient balance
+ * of the coin and possibly persisting the melt details.
+ *
+ * @param cls the plugin-specific state
+ * @param rms client-contributed input for CS denominations that must be checked for idempotency, or NULL for non-CS withdrawals
+ * @param[in,out] refresh refresh operation details; the noreveal_index
+ * is set in case the coin was already melted before
+ * @param known_coin_id row of the coin in the known_coins table
+ * @param[in,out] zombie_required true if the melt must only succeed if the coin is a zombie, set to false if the requirement was satisfied
+ * @param[out] balance_ok set to true if the balance was sufficient
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_melt)(
+ void *cls,
+ const struct TALER_RefreshMasterSecretP *rms,
+ struct TALER_EXCHANGEDB_Refresh *refresh,
+ uint64_t known_coin_id,
+ bool *zombie_required,
+ bool *balance_ok);
+
+
+ /**
+ * Add a proof of fulfillment of an policy
+ *
+ * @param cls the plugin-specific state
+ * @param[in,out] fulfillment The proof of fulfillment and serial_ids of the policy_details along with their new state and potential new amounts.
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*add_policy_fulfillment_proof)(
+ void *cls,
+ struct TALER_PolicyFulfillmentTransactionData *fulfillment);
+
+
+ /**
+ * Check if the given @a nonce was properly locked to the given @a old_coin_pub. If so, check if we already
+ * created CS signatures for the given @a nonce and @a new_denom_pub_hashes,
+ * and if so, return them in @a s_scalars. Otherwise, persist the
+ * signatures from @a s_scalars in the database.
+ *
+ * @param cls the plugin-specific state
+ * @param nonce the client-provided nonce where we must prevent reuse
+ * @param old_coin_pub public key the nonce was locked to
+ * @param num_fresh_coins array length, number of fresh coins revealed
+ * @param[in,out] crfcds array of data about the fresh coins, of length @a num_fresh_coins
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*cs_refreshes_reveal)(
+ void *cls,
+ const struct GNUNET_CRYPTO_CsSessionNonce *nonce,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ unsigned int num_fresh_coins,
+ struct TALER_EXCHANGEDB_CsRevealFreshCoinData *crfcds);
+
+
+ /**
+ * Perform refund operation, checking for sufficient deposits
+ * of the coin and possibly persisting the refund details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param refund refund operation details
+ * @param deposit_fee deposit fee applicable for the coin, possibly refunded
+ * @param known_coin_id row of the coin in the known_coins table
+ * @param[out] not_found set if the deposit was not found
+ * @param[out] refund_ok set if the refund succeeded (below deposit amount)
+ * @param[out] gone if the merchant was already paid
+ * @param[out] conflict set if the refund ID was re-used
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_refund)(
+ void *cls,
+ const struct TALER_EXCHANGEDB_Refund *refund,
+ const struct TALER_Amount *deposit_fee,
+ uint64_t known_coin_id,
+ bool *not_found,
+ bool *refund_ok,
+ bool *gone,
+ bool *conflict);
+
+
+ /**
+ * Perform recoup operation, checking for sufficient deposits
+ * of the coin and possibly persisting the recoup details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param reserve_pub public key of the reserve to credit
+ * @param reserve_out_serial_id row in the reserves_out table justifying the recoup
+ * @param coin_bks coin blinding key secret to persist
+ * @param coin_pub public key of the coin being recouped
+ * @param known_coin_id row of the @a coin_pub in the known_coins table
+ * @param coin_sig signature of the coin requesting the recoup
+ * @param[in,out] recoup_timestamp recoup timestamp, set if recoup existed
+ * @param[out] recoup_ok set if the recoup succeeded (balance ok)
+ * @param[out] internal_failure set on internal failures
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_recoup)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t reserve_out_serial_id,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ uint64_t known_coin_id,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ struct GNUNET_TIME_Timestamp *recoup_timestamp,
+ bool *recoup_ok,
+ bool *internal_failure);
+
+
+ /**
+ * Perform recoup-refresh operation, checking for sufficient deposits of the
+ * coin and possibly persisting the recoup-refresh details.
+ *
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param old_coin_pub public key of the old coin to credit
+ * @param rrc_serial row in the refresh_revealed_coins table justifying the recoup-refresh
+ * @param coin_bks coin blinding key secret to persist
+ * @param coin_pub public key of the coin being recouped
+ * @param known_coin_id row of the @a coin_pub in the known_coins table
+ * @param coin_sig signature of the coin requesting the recoup
+ * @param[in,out] recoup_timestamp recoup timestamp, set if recoup existed
+ * @param[out] recoup_ok set if the recoup-refresh succeeded (balance ok)
+ * @param[out] internal_failure set on internal failures
+ * @return query execution status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_recoup_refresh)(
+ void *cls,
+ const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ uint64_t rrc_serial,
+ const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ uint64_t known_coin_id,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ struct GNUNET_TIME_Timestamp *recoup_timestamp,
+ bool *recoup_ok,
+ bool *internal_failure);
+
+
+ /**
+ * Compile a list of (historic) transactions performed with the given reserve
+ * (withdraw, incoming wire, open, close operations). Should return 0 if the @a
+ * reserve_pub is unknown, otherwise determine @a etag_out and if it is past @a
+ * etag_in return the history after @a start_off. @a etag_out should be set
+ * to the last row ID of the given @a reserve_pub in the reserve history table.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @param reserve_pub public key of the reserve
+ * @param start_off maximum starting offset in history to exclude from returning
+ * @param etag_in up to this offset the client already has a response, do not
+ * return anything unless @a etag_out will be larger
+ * @param[out] etag_out set to the latest history offset known for this @a coin_pub
+ * @param[out] balance set to the reserve balance
* @param[out] rhp set to known transaction history (NULL if reserve is unknown)
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*get_reserve_history)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t start_off,
+ uint64_t etag_in,
+ uint64_t *etag_out,
+ struct TALER_Amount *balance,
struct TALER_EXCHANGEDB_ReserveHistory **rhp);
/**
+ * The current reserve balance of the specified reserve.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param reserve_pub public key of the reserve
+ * @param[out] balance set to the reserve balance
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_reserve_balance)(void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_Amount *balance);
+
+
+ /**
* Free memory associated with the given reserve history.
*
* @param cls the @e cls of this struct with the plugin-specific state
@@ -1779,104 +4279,195 @@ struct TALER_EXCHANGEDB_Plugin
* Count the number of known coins by denomination.
*
* @param cls database connection plugin state
- * @param session database session
* @param denom_pub_hash denomination to count by
* @return number of coins if non-negative, otherwise an `enum GNUNET_DB_QueryStatus`
*/
long long
(*count_known_coins) (void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash);
+ const struct TALER_DenominationHashP *denom_pub_hash);
/**
* Make sure the given @a coin is known to the database.
*
* @param cls database connection plugin state
- * @param session database session
* @param coin the coin that must be made known
+ * @param[out] known_coin_id set to the unique row of the coin
+ * @param[out] denom_pub_hash set to the conflicting denomination hash on conflict
+ * @param[out] age_hash set to the conflicting age hash on conflict
* @return database transaction status, non-negative on success
*/
- enum GNUNET_DB_QueryStatus
+ enum TALER_EXCHANGEDB_CoinKnownStatus
+ {
+ /**
+ * The coin was successfully added.
+ */
+ TALER_EXCHANGEDB_CKS_ADDED = 1,
+
+ /**
+ * The coin was already present.
+ */
+ TALER_EXCHANGEDB_CKS_PRESENT = 0,
+
+ /**
+ * Serialization failure.
+ */
+ TALER_EXCHANGEDB_CKS_SOFT_FAIL = -1,
+
+ /**
+ * Hard database failure.
+ */
+ TALER_EXCHANGEDB_CKS_HARD_FAIL = -2,
+
+ /**
+ * Conflicting coin (different denomination key) already in database.
+ */
+ TALER_EXCHANGEDB_CKS_DENOM_CONFLICT = -3,
+
+ /**
+ * Conflicting coin (expected NULL age hash) already in database.
+ */
+ TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NULL = -4,
+
+ /**
+ * Conflicting coin (unexpected NULL age hash) already in database.
+ */
+ TALER_EXCHANGEDB_CKS_AGE_CONFLICT_EXPECTED_NON_NULL = -5,
+
+ /**
+ * Conflicting coin (different age hash) already in database.
+ */
+ TALER_EXCHANGEDB_CKS_AGE_CONFLICT_VALUE_DIFFERS = -6,
+
+ }
(*ensure_coin_known)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_CoinPublicInfo *coin);
+ const struct TALER_CoinPublicInfo *coin,
+ uint64_t *known_coin_id,
+ struct TALER_DenominationHashP *denom_pub_hash,
+ struct TALER_AgeCommitmentHash *age_hash);
+
+
+ /**
+ * Make sure the array of given @a coin is known to the database.
+ *
+ * @param cls database connection plugin state
+ * @param coin array of coins that must be made known
+ * @param[out] result array where to store information about each coin
+ * @param coin_length length of the @a coin and @a result arraysf
+ * @param batch_size desired (maximum) batch size
+ * @return database transaction status, non-negative on success
+ */
+ enum GNUNET_DB_QueryStatus
+ (*batch_ensure_coin_known)(
+ void *cls,
+ const struct TALER_CoinPublicInfo *coin,
+ struct TALER_EXCHANGEDB_CoinInfo *result,
+ unsigned int coin_length,
+ unsigned int batch_size);
/**
* Retrieve information about the given @a coin from the database.
*
* @param cls database connection plugin state
- * @param session database session
- * @param coin the coin that must be made known
+ * @param coin_pub the coin that must be made known
+ * @param[out] coin_info detailed information about the coin
* @return database transaction status, non-negative on success
*/
enum GNUNET_DB_QueryStatus
(*get_known_coin)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
struct TALER_CoinPublicInfo *coin_info);
+ /**
+ * Retrieve the signature and corresponding denomination for a given @a coin
+ * from the database
+ *
+ * @param cls database connection plugin state
+ * @param coin_pub the public key of the coin we search for
+ * @param[out] denom_pub the public key of the denomination that the coin was signed with
+ * @param[out] denom_sig the signature with the denomination's private key over the coin_pub
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_signature_for_known_coin)(
+ void *cls,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_DenominationPublicKey *denom_pub,
+ struct TALER_DenominationSignature *denom_sig);
/**
* Retrieve the denomination of a known coin.
*
* @param cls the plugin closure
- * @param session the database session handle
* @param coin_pub the public key of the coin to search for
+ * @param[out] known_coin_id set to the ID of the coin in the known_coins table
* @param[out] denom_hash where to store the hash of the coins denomination
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*get_coin_denomination)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
- struct GNUNET_HashCode *denom_hash);
+ uint64_t *known_coin_id,
+ struct TALER_DenominationHashP *denom_hash);
/**
- * Check if we have the specified deposit already in the database.
+ * Try to retrieve the salted hash of the merchant's bank account to a
+ * deposit contract. Used in case of conflicts for a given (merchant_pub,
+ * h_contract_terms) to provide the client the necessary input to retrieve
+ * more details about the conflict.
*
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
- * @param deposit deposit to search for
- * @param check_extras whether to check extra fields or not
- * @return 1 if we know this operation,
- * 0 if this exact deposit is unknown to us,
- * otherwise transaction error status
+ * @param cls the plugin closure
+ * @param merchant_pub public key of the merchant
+ * @param h_contract_terms contract to check for
+ * @param[out] h_wire hash of the wire details
*/
enum GNUNET_DB_QueryStatus
- (*have_deposit)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_EXCHANGEDB_Deposit *deposit,
- int check_extras);
+ (*get_wire_hash_for_contract)(
+ void *cls,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ struct TALER_MerchantWireHashP *h_wire);
/**
- * Insert information about deposited coin into the database.
+ * Check if we have the specified deposit already in the database.
*
- * @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param deposit deposit information to store
- * @return query result status
+ * @param cls the `struct PostgresClosure` with the plugin-specific state
+ * @param h_contract_terms contract to check for
+ * @param h_wire wire hash to check for
+ * @param coin_pub public key of the coin to check for
+ * @param merchant merchant public key to check for
+ * @param refund_deadline expected refund deadline
+ * @param[out] deposit_fee set to the deposit fee the exchange charged
+ * @param[out] exchange_timestamp set to the time when the exchange received the deposit
+ * @return 1 if we know this operation,
+ * 0 if this exact deposit is unknown to us,
+ * otherwise transaction error status
*/
+ // FIXME: rename!
enum GNUNET_DB_QueryStatus
- (*insert_deposit)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_EXCHANGEDB_Deposit *deposit);
+ (*have_deposit2)(
+ void *cls,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant,
+ struct GNUNET_TIME_Timestamp refund_deadline,
+ struct TALER_Amount *deposit_fee,
+ struct GNUNET_TIME_Timestamp *exchange_timestamp);
/**
* Insert information about refunded coin into the database.
+ * Used in tests and for benchmarking.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
* @param refund refund information to store
* @return query result status
*/
enum GNUNET_DB_QueryStatus
(*insert_refund)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_EXCHANGEDB_Refund *refund);
@@ -1884,7 +4475,6 @@ struct TALER_EXCHANGEDB_Plugin
* Select refunds by @a coin_pub, @a merchant_pub and @a h_contract.
*
* @param cls closure of plugin
- * @param session database handle to use
* @param coin_pub coin to get refunds for
* @param merchant_pub merchant to get refunds for
* @param h_contract_pub contract (hash) to get refunds for
@@ -1893,174 +4483,169 @@ struct TALER_EXCHANGEDB_Plugin
* @return query result status
*/
enum GNUNET_DB_QueryStatus
- (*select_refunds_by_coin)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_contract,
- TALER_EXCHANGEDB_RefundCoinCallback cb,
- void *cb_cls);
+ (*select_refunds_by_coin)(
+ void *cls,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_PrivateContractHashP *h_contract,
+ TALER_EXCHANGEDB_RefundCoinCallback cb,
+ void *cb_cls);
/**
- * Mark a deposit as tiny, thereby declaring that it cannot be executed by
- * itself (only included in a larger aggregation) and should no longer be
- * returned by @e iterate_ready_deposits()
+ * Obtain information about deposits that are ready to be executed.
+ * Such deposits must not be marked as "done", and the
+ * execution time, the refund deadlines must both be in the past and
+ * the KYC status must be 'ok'.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param deposit_rowid identifies the deposit row to modify
- * @return query result status
+ * @param start_shard_row minimum shard row to select
+ * @param end_shard_row maximum shard row to select (inclusive)
+ * @param[out] merchant_pub set to the public key of a merchant with a ready deposit
+ * @param[out] payto_uri set to the account of the merchant, to be freed by caller
+ * @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*mark_deposit_tiny)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- uint64_t rowid);
+ (*get_ready_deposit)(void *cls,
+ uint64_t start_shard_row,
+ uint64_t end_shard_row,
+ struct TALER_MerchantPublicKeyP *merchant_pub,
+ char **payto_uri);
/**
- * Test if a deposit was marked as done, thereby declaring that it
- * cannot be refunded anymore.
+ * Aggregate all matching deposits for @a h_payto and
+ * @a merchant_pub, returning the total amounts.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param coin_pub the coin to check for deposit
- * @param merchant_pub merchant to receive the deposit
- * @param h_contract_terms contract terms of the deposit
- * @param h_wire hash of the merchant's wire details
- * @return #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT if is is marked done,
- * #GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if not,
- * otherwise transaction error status (incl. deposit unknown)
+ * @param h_payto destination of the wire transfer
+ * @param merchant_pub public key of the merchant
+ * @param wtid wire transfer ID to set for the aggregate
+ * @param[out] total set to the sum of the total deposits minus applicable deposit fees and refunds
+ * @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*test_deposit_done)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct GNUNET_HashCode *h_wire);
+ (*aggregate)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ struct TALER_Amount *total);
/**
- * Mark a deposit as done, thereby declaring that it cannot be
- * executed at all anymore, and should no longer be returned by
- * @e iterate_ready_deposits() or @e iterate_matching_deposits().
+ * Create a new entry in the transient aggregation table.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param deposit_rowid identifies the deposit row to modify
- * @return query result status
+ * @param h_payto destination of the wire transfer
+ * @param exchange_account_section exchange account to use
+ * @param merchant_pub public key of the merchant
+ * @param wtid the raw wire transfer identifier to be used
+ * @param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue, or 0 for none
+ * @param total amount to be wired in the future
+ * @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*mark_deposit_done)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- uint64_t rowid);
+ (*create_aggregation_transient)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *exchange_account_section,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ uint64_t kyc_requirement_row,
+ const struct TALER_Amount *total);
/**
- * Obtain information about deposits that are ready to be executed.
- * Such deposits must not be marked as "tiny" or "done", and the
- * execution time and refund deadlines must both be in the past.
+ * Select existing entry in the transient aggregation table.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param deposit_cb function to call for ONE such deposit
- * @param deposit_cb_cls closure for @a deposit_cb
- * @return transaction status code
+ * @param h_payto destination of the wire transfer
+ * @param merchant_pub public key of the merchant
+ * @param exchange_account_section exchange account to use
+ * @param[out] wtid set to the raw wire transfer identifier to be used
+ * @param[out] total existing amount to be wired in the future
+ * @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*get_ready_deposit)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- TALER_EXCHANGEDB_DepositIterator deposit_cb,
- void *deposit_cb_cls);
+ (*select_aggregation_transient)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_MerchantPublicKeyP *merchant_pub,
+ const char *exchange_account_section,
+ struct TALER_WireTransferIdentifierRawP *wtid,
+ struct TALER_Amount *total);
-/**
- * Maximum number of results we return from iterate_matching_deposits().
- *
- * Limit on the number of transactions we aggregate at once. Note
- * that the limit must be big enough to ensure that when transactions
- * of the smallest possible unit are aggregated, they do surpass the
- * "tiny" threshold beyond which we never trigger a wire transaction!
- */
-#define TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT 10000
+ /**
+ * Find existing entry in the transient aggregation table.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto destination of the wire transfer
+ * @param cb function to call on each matching entry
+ * @param cb_cls closure for @a cb
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*find_aggregation_transient)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_TransientAggregationCallback cb,
+ void *cb_cls);
+
/**
- * Obtain information about other pending deposits for the same
- * destination. Those deposits must not already be "done".
+ * Update existing entry in the transient aggregation table.
+ * @a h_payto is only needed for query performance.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to the database
- * @param h_wire destination of the wire transfer
- * @param merchant_pub public key of the merchant
- * @param deposit_cb function to call for each deposit
- * @param deposit_cb_cls closure for @a deposit_cb
- * @param limit maximum number of matching deposits to return; should
- * be #TALER_EXCHANGEDB_MATCHING_DEPOSITS_LIMIT, larger values
- * are not supported, smaller values would be inefficient.
- * @return number of rows processed, 0 if none exist,
- * transaction status code on error
+ * @param h_payto destination of the wire transfer
+ * @param wtid the raw wire transfer identifier to update
+ * @param kyc_requirement_row row in legitimization_requirements that need to be satisfied to continue, or 0 for none
+ * @param total new total amount to be wired in the future
+ * @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*iterate_matching_deposits)(
+ (*update_aggregation_transient)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *h_wire,
- const struct TALER_MerchantPublicKeyP *merchant_pub,
- TALER_EXCHANGEDB_DepositIterator deposit_cb,
- void *deposit_cb_cls,
- uint32_t limit);
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ uint64_t kyc_requirement_row,
+ const struct TALER_Amount *total);
/**
- * Store new melt commitment data.
+ * Delete existing entry in the transient aggregation table.
+ * @a h_payto is only needed for query performance.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database handle to use
- * @param refresh_session operational data to store
- * @return query status for the transaction
+ * @param h_payto destination of the wire transfer
+ * @param wtid the raw wire transfer identifier to update
+ * @return transaction status
*/
enum GNUNET_DB_QueryStatus
- (*insert_melt)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_EXCHANGEDB_Refresh *refresh_session);
+ (*delete_aggregation_transient)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_WireTransferIdentifierRawP *wtid);
/**
* Lookup melt commitment data under the given @a rc.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database handle to use
* @param rc commitment to use for the lookup
* @param[out] melt where to store the result; note that
* melt->session.coin.denom_sig will be set to NULL
* and is not fetched by this routine (as it is not needed by the client)
+ * @param[out] melt_serial_id set to the row ID of @a rc in the refresh_commitments table
* @return transaction status
*/
enum GNUNET_DB_QueryStatus
(*get_melt)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_RefreshCommitmentP *rc,
- struct TALER_EXCHANGEDB_Melt *melt);
-
-
- /**
- * Lookup noreveal index of a previous melt operation under the given
- * @a rc.
- *
- * @param cls the `struct PostgresClosure` with the plugin-specific state
- * @param session database handle to use
- * @param rc commitment hash to use to locate the operation
- * @param[out] noreveal_index returns the "gamma" value selected by the
- * exchange which is the index of the transfer key that is
- * not to be revealed to the exchange
- * @return transaction status
- */
- enum GNUNET_DB_QueryStatus
- (*get_melt_index)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_RefreshCommitmentP *rc,
- uint32_t *noreveal_index);
+ struct TALER_EXCHANGEDB_Melt *melt,
+ uint64_t *melt_serial_id);
/**
@@ -2069,8 +4654,7 @@ struct TALER_EXCHANGEDB_Plugin
* we learned or created in the reveal step.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
- * @param rc identify commitment and thus refresh operation
+ * @param melt_serial_id row ID of the commitment / melt operation in refresh_commitments
* @param num_rrcs number of coins to generate, size of the @a rrcs array
* @param rrcs information about the new coins
* @param num_tprivs number of entries in @a tprivs, should be #TALER_CNC_KAPPA - 1
@@ -2081,8 +4665,7 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_refresh_reveal)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_RefreshCommitmentP *rc,
+ uint64_t melt_serial_id,
uint32_t num_rrcs,
const struct TALER_EXCHANGEDB_RefreshRevealedCoin *rrcs,
unsigned int num_tprivs,
@@ -2091,11 +4674,10 @@ struct TALER_EXCHANGEDB_Plugin
/**
- * Lookup in the database for the @a num_freshcoins coins that we
+ * Lookup in the database for the fresh coins that we
* created in the given refresh operation.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
* @param rc identify commitment and thus refresh operation
* @param cb function to call with the results
* @param cb_cls closure for @a cb
@@ -2103,7 +4685,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*get_refresh_reveal)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_RefreshCommitmentP *rc,
TALER_EXCHANGEDB_RefreshCallback cb,
void *cb_cls);
@@ -2116,7 +4697,6 @@ struct TALER_EXCHANGEDB_Plugin
* the private keys of the new coins after the melt.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
* @param coin_pub public key of the coin
* @param ldc function to call for each session the coin was melted into
* @param ldc_cls closure for @a tdc
@@ -2124,29 +4704,41 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*get_link_data)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
TALER_EXCHANGEDB_LinkCallback ldc,
void *tdc_cls);
/**
- * Compile a list of all (historic) transactions performed
- * with the given coin (melt, refund, recoup and deposit operations).
+ * Compile a list of (historic) transactions performed with the given coin
+ * (melt, refund, recoup and deposit operations). Should return 0 if the @a
+ * coin_pub is unknown, otherwise determine @a etag_out and if it is past @a
+ * etag_in return the history after @a start_off. @a etag_out should be set
+ * to the last row ID of the given @a coin_pub in the coin history table.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
* @param coin_pub coin to investigate
- * @param include_recoup include recoup transactions of the coin?
- * @param[out] tlp set to list of transactions, NULL if coin is fresh
+ * @param start_off starting offset from which on to return entries
+ * @param etag_in up to this offset the client already has a response, do not
+ * return anything unless @a etag_out will be larger
+ * @param[out] etag_out set to the latest history offset known for this @a coin_pub
+ * @param[out] balance set to current balance of the coin
+ * @param[out] h_denom_pub set to denomination public key of the coin
+ * @param[out] tlp set to list of transactions, set to NULL if coin has no
+ * transaction history past @a start_off or if @a etag_in is equal
+ * to the value written to @a etag_out.
* @return database transaction status
*/
enum GNUNET_DB_QueryStatus
- (*get_coin_transactions)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_CoinSpendPublicKeyP *coin_pub,
- int include_recoup,
- struct TALER_EXCHANGEDB_TransactionList **tlp);
+ (*get_coin_transactions)(
+ void *cls,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ uint64_t start_off,
+ uint64_t etag_in,
+ uint64_t *etag_out,
+ struct TALER_Amount *balance,
+ struct TALER_DenominationHashP *h_denom_pub,
+ struct TALER_EXCHANGEDB_TransactionList **tlp);
/**
@@ -2165,7 +4757,6 @@ struct TALER_EXCHANGEDB_Plugin
* into a wire transfer by the respective @a raw_wtid.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session database connection
* @param wtid the raw wire transfer identifier we used
* @param cb function to call on each transaction found
* @param cb_cls closure for @a cb
@@ -2173,7 +4764,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*lookup_wire_transfer)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_WireTransferIdentifierRawP *wtid,
TALER_EXCHANGEDB_AggregationDataCallback cb,
void *cb_cls);
@@ -2185,100 +4775,135 @@ struct TALER_EXCHANGEDB_Plugin
* to be executed.
*
* @param cls closure
- * @param session database connection
* @param h_contract_terms hash of the proposal data
* @param h_wire hash of merchant wire details
* @param coin_pub public key of deposited coin
* @param merchant_pub merchant public key
- * @param cb function to call with the result
- * @param cb_cls closure to pass to @a cb
+ * @param[out] pending set to true if the transaction is still pending
+ * @param[out] wtid wire transfer identifier, only set if @a pending is false
+ * @param[out] coin_contribution how much did the coin we asked about
+ * contribute to the total transfer value? (deposit value including fee)
+ * @param[out] coin_fee how much did the exchange charge for the deposit fee
+ * @param[out] execution_time when was the transaction done, or
+ * when we expect it to be done (if @a pending is false)
+ * @param[out] kyc set to the kyc status of the receiver (if @a pending)
+ * @param[out] aml_decision set to the current AML status for the target account
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*lookup_transfer_by_deposit)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *h_contract_terms,
- const struct GNUNET_HashCode *h_wire,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ const struct TALER_MerchantWireHashP *h_wire,
const struct TALER_CoinSpendPublicKeyP *coin_pub,
const struct TALER_MerchantPublicKeyP *merchant_pub,
- TALER_EXCHANGEDB_WireTransferByCoinCallback cb,
- void *cb_cls);
+ bool *pending,
+ struct TALER_WireTransferIdentifierRawP *wtid,
+ struct GNUNET_TIME_Timestamp *exec_time,
+ struct TALER_Amount *amount_with_fee,
+ struct TALER_Amount *deposit_fee,
+ struct TALER_EXCHANGEDB_KycStatus *kyc,
+ enum TALER_AmlDecisionState *aml_decision);
/**
- * Function called to insert aggregation information into the DB.
+ * Insert wire transfer fee into database.
*
* @param cls closure
- * @param session database connection
- * @param wtid the raw wire transfer identifier we used
- * @param deposit_serial_id row in the deposits table for which this is aggregation data
+ * @param wire_method which wire method is the fee about?
+ * @param start_date when does the fee go into effect
+ * @param end_date when does the fee end being valid
+ * @param fees how high is are the wire fees
+ * @param master_sig signature over the above by the exchange master key
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_aggregation_tracking)(
- void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_WireTransferIdentifierRawP *wtid,
- unsigned long long deposit_serial_id);
+ (*insert_wire_fee)(void *cls,
+ const char *wire_method,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_WireFeeSet *fees,
+ const struct TALER_MasterSignatureP *master_sig);
/**
- * Insert wire transfer fee into database.
+ * Insert global fee set into database.
*
* @param cls closure
- * @param session database connection
- * @param wire_method which wire method is the fee about?
- * @param start_date when does the fee go into effect
- * @param end_date when does the fee end being valid
- * @param wire_fee how high is the wire transfer fee
- * @param closing_fee how high is the closing fee
+ * @param start_date when does the fees go into effect
+ * @param end_date when does the fees end being valid
+ * @param fees how high is are the global fees
+ * @param purse_timeout when do purses time out
+ * @param history_expiration how long are account histories preserved
+ * @param purse_account_limit how many purses are free per account
* @param master_sig signature over the above by the exchange master key
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*insert_wire_fee)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const char *wire_method,
- struct GNUNET_TIME_Absolute start_date,
- struct GNUNET_TIME_Absolute end_date,
- const struct TALER_Amount *wire_fee,
- const struct TALER_Amount *closing_fee,
- const struct TALER_MasterSignatureP *master_sig);
+ (*insert_global_fee)(void *cls,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ const struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ uint32_t purse_account_limit,
+
+ const struct TALER_MasterSignatureP *master_sig);
/**
* Obtain wire fee from database.
*
* @param cls closure
- * @param session database connection
* @param type type of wire transfer the fee applies for
* @param date for which date do we want the fee?
* @param[out] start_date when does the fee go into effect
* @param[out] end_date when does the fee end being valid
- * @param[out] wire_fee how high is the wire transfer fee
- * @param[out] closing_fee how high is the closing fee
+ * @param[out] fees how high are the wire fees
* @param[out] master_sig signature over the above by the exchange master key
* @return query status of the transaction
*/
enum GNUNET_DB_QueryStatus
(*get_wire_fee)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const char *type,
- struct GNUNET_TIME_Absolute date,
- struct GNUNET_TIME_Absolute *start_date,
- struct GNUNET_TIME_Absolute *end_date,
- struct TALER_Amount *wire_fee,
- struct TALER_Amount *closing_fee,
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_WireFeeSet *fees,
struct TALER_MasterSignatureP *master_sig);
/**
+ * Obtain global fees from database.
+ *
+ * @param cls closure
+ * @param date for which date do we want the fee?
+ * @param[out] start_date when does the fee go into effect
+ * @param[out] end_date when does the fee end being valid
+ * @param[out] fees how high are the global fees
+ * @param[out] purse_timeout when do purses time out
+ * @param[out] history_expiration how long are account histories preserved
+ * @param[out] purse_account_limit how many purses are free per account
+ * @param[out] master_sig signature over the above by the exchange master key
+ * @return query status of the transaction
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_global_fee)(void *cls,
+ struct GNUNET_TIME_Timestamp date,
+ struct GNUNET_TIME_Timestamp *start_date,
+ struct GNUNET_TIME_Timestamp *end_date,
+ struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative *purse_timeout,
+ struct GNUNET_TIME_Relative *history_expiration,
+ uint32_t *purse_account_limit,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
* Obtain information about expired reserves and their
* remaining balances.
*
* @param cls closure of the plugin
- * @param session database connection
* @param now timestamp based on which we decide expiration
* @param rec function to call on expired reserves
* @param rec_cls closure for @a rec
@@ -2286,41 +4911,186 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*get_expired_reserves)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- struct GNUNET_TIME_Absolute now,
+ struct GNUNET_TIME_Timestamp now,
TALER_EXCHANGEDB_ReserveExpiredCallback rec,
void *rec_cls);
/**
+ * Obtain information about force-closed reserves
+ * where the close was not yet done (and their remaining
+ * balances). Updates the returned reserve's close
+ * status to "done".
+ *
+ * @param cls closure of the plugin
+ * @param rec function to call on (to be) closed reserves
+ * @param rec_cls closure for @a rec
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_unfinished_close_requests)(
+ void *cls,
+ TALER_EXCHANGEDB_ReserveExpiredCallback rec,
+ void *rec_cls);
+
+
+ /**
+ * Insert reserve open coin deposit data into database.
+ * Subtracts the @a coin_total from the coin's balance.
+ *
+ * @param cls closure
+ * @param cpi public information about the coin
+ * @param coin_sig signature with @e coin_pub of type #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
+ * @param known_coin_id ID of the coin in the known_coins table
+ * @param coin_total amount to be spent of the coin (including deposit fee)
+ * @param reserve_sig signature by the reserve affirming the open operation
+ * @param reserve_pub public key of the reserve being opened
+ * @param[out] insufficient_funds set to true if the coin's balance is insufficient, otherwise to false
+ * @return transaction status code, 0 if operation is already in the DB
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_reserve_open_deposit)(
+ void *cls,
+ const struct TALER_CoinPublicInfo *cpi,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ uint64_t known_coin_id,
+ const struct TALER_Amount *coin_total,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ bool *insufficient_funds);
+
+
+ /**
+ * Insert reserve close operation into database.
+ *
+ * @param cls closure
+ * @param reserve_pub which reserve is this about?
+ * @param total_paid total amount paid (coins and reserve)
+ * @param reserve_payment amount to be paid from the reserve
+ * @param min_purse_limit minimum number of purses we should be able to open
+ * @param reserve_sig signature by the reserve for the operation
+ * @param desired_expiration when should the reserve expire (earliest time)
+ * @param now when did we the client initiate the action
+ * @param open_fee annual fee to be charged for the open operation by the exchange
+ * @param[out] no_funds set to true if reserve balance is insufficient
+ * @param[out] reserve_balance set to original balance of the reserve
+ * @param[out] open_cost set to the actual cost
+ * @param[out] final_expiration when will the reserve expire now
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_reserve_open)(void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const struct TALER_Amount *total_paid,
+ const struct TALER_Amount *reserve_payment,
+ uint32_t min_purse_limit,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ struct GNUNET_TIME_Timestamp desired_expiration,
+ struct GNUNET_TIME_Timestamp now,
+ const struct TALER_Amount *open_fee,
+ bool *no_funds,
+ struct TALER_Amount *reserve_balance,
+ struct TALER_Amount *open_cost,
+ struct GNUNET_TIME_Timestamp *final_expiration);
+
+
+ /**
+ * Select information needed to see if we can close
+ * a reserve.
+ *
+ * @param cls closure
+ * @param reserve_pub which reserve is this about?
+ * @param[out] balance current reserve balance
+ * @param[out] payto_uri set to URL of account that
+ * originally funded the reserve;
+ * could be set to NULL if not known
+ * @return transaction status code, 0 if reserve unknown
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_reserve_close_info)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ struct TALER_Amount *balance,
+ char **payto_uri);
+
+
+ /**
+ * Select information about reserve close requests.
+ *
+ * @param cls closure
+ * @param reserve_pub which reserve is this about?
+ * @param rowid row ID of the close request
+ * @param[out] reserve_sig reserve signature affirming
+ * @param[out] request_timestamp when was the request made
+ * @param[out] close_balance reserve balance at close time
+ * @param[out] close_fee closing fee to be charged
+ * @param[out] payto_uri set to URL of account that
+ * should receive the money;
+ * could be set to NULL for origin
+ * @return transaction status code, 0 if reserve unknown
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_reserve_close_request_info)(
+ void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t rowid,
+ struct TALER_ReserveSignatureP *reserve_sig,
+ struct GNUNET_TIME_Timestamp *request_timestamp,
+ struct TALER_Amount *close_balance,
+ struct TALER_Amount *close_fee,
+ char **payto_uri);
+
+
+ /**
+ * Select information needed for KYC checks on reserve close: historic
+ * reserve closures going to the same account.
+ *
+ * @param cls closure
+ * @param h_payto which target account is this about?
+ * @param h_payto account identifier
+ * @param time_limit oldest transaction that could be relevant
+ * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK).
+ * @param kac_cls closure for @a kac
+ * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_reserve_close_info)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ struct GNUNET_TIME_Absolute time_limit,
+ TALER_EXCHANGEDB_KycAmountCallback kac,
+ void *kac_cls);
+
+
+ /**
* Insert reserve close operation into database.
*
* @param cls closure
- * @param session database connection
* @param reserve_pub which reserve is this about?
* @param execution_date when did we perform the transfer?
* @param receiver_account to which account do we transfer, in payto://-format
* @param wtid identifier for the wire transfer
* @param amount_with_fee amount we charged to the reserve
* @param closing_fee how high is the closing fee
+ * @param close_request_row identifies explicit close request, 0 for none
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*insert_reserve_closed)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const struct TALER_ReservePublicKeyP *reserve_pub,
- struct GNUNET_TIME_Absolute execution_date,
+ struct GNUNET_TIME_Timestamp execution_date,
const char *receiver_account,
- const struct TALER_WireTransferIdentifierRawP *wtid,
+ const struct
+ TALER_WireTransferIdentifierRawP *wtid,
const struct TALER_Amount *amount_with_fee,
- const struct TALER_Amount *closing_fee);
+ const struct TALER_Amount *closing_fee,
+ uint64_t close_request_row);
/**
* Function called to insert wire transfer commit data into the DB.
*
* @param cls closure
- * @param session database connection
* @param type type of the wire transfer (i.e. "iban")
* @param buf buffer with wire transfer preparation data
* @param buf_size number of bytes in @a buf
@@ -2328,7 +5098,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*wire_prepare_data_insert)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const char *type,
const char *buf,
size_t buf_size);
@@ -2338,54 +5107,63 @@ struct TALER_EXCHANGEDB_Plugin
* Function called to mark wire transfer commit data as finished.
*
* @param cls closure
- * @param session database connection
* @param rowid which entry to mark as finished
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*wire_prepare_data_mark_finished)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t rowid);
/**
+ * Function called to mark wire transfer as failed.
+ *
+ * @param cls closure
+ * @param rowid which entry to mark as failed
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*wire_prepare_data_mark_failed)(void *cls,
+ uint64_t rowid);
+
+
+ /**
* Function called to get an unfinished wire transfer
- * preparation data. Fetches at most one item.
+ * preparation data.
*
* @param cls closure
- * @param session database connection
- * @param cb function to call for ONE unfinished item
+ * @param start_row offset to query table at
+ * @param limit maximum number of results to return
+ * @param cb function to call for unfinished work
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
(*wire_prepare_data_get)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
+ uint64_t start_row,
+ uint64_t limit,
TALER_EXCHANGEDB_WirePreparationIterator cb,
void *cb_cls);
/**
- * Start a transaction where we transiently violate the foreign
+ * Starts a READ COMMITTED transaction where we transiently violate the foreign
* constraints on the "wire_out" table as we insert aggregations
* and only add the wire transfer out at the end.
*
* @param cls the @e cls of this struct with the plugin-specific state
- * @param session connection to use
* @return #GNUNET_OK on success
*/
- int
- (*start_deferred_wire_out) (void *cls,
- struct TALER_EXCHANGEDB_Session *session);
+ enum GNUNET_GenericReturnValue
+ (*start_deferred_wire_out)(void *cls);
/**
* Store information about an outgoing wire transfer that was executed.
*
* @param cls closure
- * @param session database connection
* @param date time of the wire transfer
- * @param wtid subject of the wire transfer
+ * @param h_payto identifies the receiver account of the wire transfer
* @param wire_account details about the receiver account of the wire transfer,
* including 'url' in payto://-format
* @param amount amount that was transmitted
@@ -2396,10 +5174,9 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*store_wire_transfer_out)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- struct GNUNET_TIME_Absolute date,
+ struct GNUNET_TIME_Timestamp date,
const struct TALER_WireTransferIdentifierRawP *wtid,
- const json_t *wire_account,
+ const struct TALER_PaytoHashP *h_payto,
const char *exchange_account_section,
const struct TALER_Amount *amount);
@@ -2412,8 +5189,8 @@ struct TALER_EXCHANGEDB_Plugin
* @return #GNUNET_OK on success,
* #GNUNET_SYSERR on DB errors
*/
- int
- (*gc) (void *cls);
+ enum GNUNET_GenericReturnValue
+ (*gc)(void *cls);
/**
@@ -2421,25 +5198,150 @@ struct TALER_EXCHANGEDB_Plugin
* order.
*
* @param cls closure
- * @param session database connection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*select_deposits_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- uint64_t serial_id,
- TALER_EXCHANGEDB_DepositCallback cb,
- void *cb_cls);
+ (*select_coin_deposits_above_serial_id)(void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_DepositCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Function called to return meta data about a purses
+ * above a certain serial ID.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param serial_id number to select requests by
+ * @param cb function to call on each request
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_requests_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_PurseRequestCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select purse deposits above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_deposits_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_PurseDepositCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select account merges above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_account_merges_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_AccountMergeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select purse merges deposits above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_merges_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_PurseMergeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select purse refunds above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param refunded which refund status to select for
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_decisions_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ bool refunded,
+ TALER_EXCHANGEDB_PurseDecisionCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select all purse refunds above @a serial_id in monotonically increasing
+ * order.
+ *
+ * @param cls closure
+ * @param serial_id highest serial ID to exclude (select strictly larger)
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_all_purse_decisions_above_serial_id)(
+ void *cls,
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_AllPurseDecisionCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select coins deposited into a purse.
+ *
+ * @param cls closure
+ * @param purse_pub public key of the purse
+ * @param cb function to call on each result
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_deposits_by_purse)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ TALER_EXCHANGEDB_PurseRefundCoinCallback cb,
+ void *cb_cls);
+
/**
* Select refresh sessions above @a serial_id in monotonically increasing
* order.
*
* @param cls closure
- * @param session database connection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
* @param cb_cls closure for @a cb
@@ -2447,7 +5349,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_refreshes_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_RefreshesCallback cb,
void *cb_cls);
@@ -2458,7 +5359,6 @@ struct TALER_EXCHANGEDB_Plugin
* order.
*
* @param cls closure
- * @param session database connection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
* @param cb_cls closure for @a cb
@@ -2466,7 +5366,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_refunds_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_RefundCallback cb,
void *cb_cls);
@@ -2477,7 +5376,6 @@ struct TALER_EXCHANGEDB_Plugin
* in monotonically increasing order.
*
* @param cls closure
- * @param session database connection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
* @param cb_cls closure for @a cb
@@ -2485,7 +5383,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_reserves_in_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_ReserveInCallback cb,
void *cb_cls);
@@ -2496,7 +5393,6 @@ struct TALER_EXCHANGEDB_Plugin
* in monotonically increasing order by @a account_name.
*
* @param cls closure
- * @param session database connection
* @param account_name name of the account for which we do the selection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
@@ -2506,7 +5402,6 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_reserves_in_above_serial_id_by_account)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const char *account_name,
uint64_t serial_id,
TALER_EXCHANGEDB_ReserveInCallback cb,
@@ -2518,7 +5413,6 @@ struct TALER_EXCHANGEDB_Plugin
* in monotonically increasing order.
*
* @param cls closure
- * @param session database connection
* @param account_name name of the account for which we do the selection
* @param serial_id highest serial ID to exclude (select strictly larger)
* @param cb function to call on each result
@@ -2528,7 +5422,6 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_withdrawals_above_serial_id)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_WithdrawCallback cb,
void *cb_cls);
@@ -2539,7 +5432,6 @@ struct TALER_EXCHANGEDB_Plugin
* executed, ordered by serial ID (monotonically increasing).
*
* @param cls closure
- * @param session database connection
* @param serial_id lowest serial ID to include (select larger or equal)
* @param cb function to call for ONE unfinished item
* @param cb_cls closure for @a cb
@@ -2547,9 +5439,9 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_wire_out_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
- TALER_EXCHANGEDB_WireTransferOutCallback cb,
+ TALER_EXCHANGEDB_WireTransferOutCallback
+ cb,
void *cb_cls);
/**
@@ -2557,7 +5449,6 @@ struct TALER_EXCHANGEDB_Plugin
* executed, ordered by serial ID (monotonically increasing).
*
* @param cls closure
- * @param session database connection
* @param account_name name to select by
* @param serial_id lowest serial ID to include (select larger or equal)
* @param cb function to call for ONE unfinished item
@@ -2567,7 +5458,6 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_wire_out_above_serial_id_by_account)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
const char *account_name,
uint64_t serial_id,
TALER_EXCHANGEDB_WireTransferOutCallback cb,
@@ -2579,7 +5469,6 @@ struct TALER_EXCHANGEDB_Plugin
* received, ordered by serial ID (monotonically increasing).
*
* @param cls closure
- * @param session database connection
* @param serial_id lowest serial ID to include (select larger or equal)
* @param cb function to call for ONE unfinished item
* @param cb_cls closure for @a cb
@@ -2587,7 +5476,6 @@ struct TALER_EXCHANGEDB_Plugin
*/
enum GNUNET_DB_QueryStatus
(*select_recoup_above_serial_id)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_RecoupCallback cb,
void *cb_cls);
@@ -2598,7 +5486,6 @@ struct TALER_EXCHANGEDB_Plugin
* refreshed coins, ordered by serial ID (monotonically increasing).
*
* @param cls closure
- * @param session database connection
* @param serial_id lowest serial ID to include (select larger or equal)
* @param cb function to call for ONE unfinished item
* @param cb_cls closure for @a cb
@@ -2607,86 +5494,45 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*select_recoup_refresh_above_serial_id)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
TALER_EXCHANGEDB_RecoupRefreshCallback cb,
void *cb_cls);
/**
- * Function called to select reserve close operations the aggregator
- * triggered, ordered by serial ID (monotonically increasing).
+ * Function called to select reserve open operations, ordered by serial ID
+ * (monotonically increasing).
*
* @param cls closure
- * @param session database connection
* @param serial_id lowest serial ID to include (select larger or equal)
* @param cb function to call
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*select_reserve_closed_above_serial_id)(
+ (*select_reserve_open_above_serial_id)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
uint64_t serial_id,
- TALER_EXCHANGEDB_ReserveClosedCallback cb,
+ TALER_EXCHANGEDB_ReserveOpenCallback cb,
void *cb_cls);
/**
- * Function called to add a request for an emergency recoup for a
- * coin. The funds are to be added back to the reserve.
- *
- * @param cls closure
- * @param session database connection
- * @param reserve_pub public key of the reserve that is being refunded
- * @param coin public information about a coin
- * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
- * @param coin_blind blinding key of the coin
- * @param h_blind_ev blinded envelope, as calculated by the exchange
- * @param amount total amount to be paid back
- * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
- * @param timestamp the timestamp to store
- * @return transaction result status
- */
- enum GNUNET_DB_QueryStatus
- (*insert_recoup_request)(
- void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_ReservePublicKeyP *reserve_pub,
- const struct TALER_CoinPublicInfo *coin,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_DenominationBlindingKeyP *coin_blind,
- const struct TALER_Amount *amount,
- const struct GNUNET_HashCode *h_blind_ev,
- struct GNUNET_TIME_Absolute timestamp);
-
-
- /**
- * Function called to add a request for an emergency recoup for a
- * refreshed coin. The funds are to be added back to the original coin.
- *
- * @param cls closure
- * @param session database connection
- * @param coin public information about the refreshed coin
- * @param coin_sig signature of the coin of type #TALER_SIGNATURE_WALLET_COIN_RECOUP
- * @param coin_blind blinding key of the coin
- * @param h_blind_ev blinded envelope, as calculated by the exchange
- * @param amount total amount to be paid back
- * @param h_blind_ev hash of the blinded coin's envelope (must match reserves_out entry)
- * @param timestamp a timestamp to store
- * @return transaction result status
- */
+ * Function called to select reserve close operations the aggregator
+ * triggered, ordered by serial ID (monotonically increasing).
+ *
+ * @param cls closure
+ * @param serial_id lowest serial ID to include (select larger or equal)
+ * @param cb function to call
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
enum GNUNET_DB_QueryStatus
- (*insert_recoup_refresh_request)(
+ (*select_reserve_closed_above_serial_id)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct TALER_CoinPublicInfo *coin,
- const struct TALER_CoinSpendSignatureP *coin_sig,
- const struct TALER_DenominationBlindingKeyP *coin_blind,
- const struct TALER_Amount *amount,
- const struct GNUNET_HashCode *h_blind_ev,
- struct GNUNET_TIME_Absolute timestamp);
+ uint64_t serial_id,
+ TALER_EXCHANGEDB_ReserveClosedCallback cb,
+ void *cb_cls);
/**
@@ -2694,16 +5540,17 @@ struct TALER_EXCHANGEDB_Plugin
* from given the hash of the blinded coin.
*
* @param cls closure
- * @param session a session
- * @param h_blind_ev hash of the blinded coin
+ * @param bch hash identifying the withdraw operation
* @param[out] reserve_pub set to information about the reserve (on success only)
+ * @param[out] reserve_out_serial_id set to row of the @a h_blind_ev in reserves_out
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_reserve_by_h_blind)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *h_blind_ev,
- struct TALER_ReservePublicKeyP *reserve_pub);
+ (*get_reserve_by_h_blind)(
+ void *cls,
+ const struct TALER_BlindedCoinHashP *bch,
+ struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t *reserve_out_serial_id);
/**
@@ -2711,16 +5558,17 @@ struct TALER_EXCHANGEDB_Plugin
* given the hash of the blinded (fresh) coin.
*
* @param cls closure
- * @param session a session
* @param h_blind_ev hash of the blinded coin
* @param[out] old_coin_pub set to information about the old coin (on success only)
+ * @param[out] rrc_serial set to the row of the @a h_blind_ev in the refresh_revealed_coins table
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_old_coin_by_h_blind)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *h_blind_ev,
- struct TALER_CoinSpendPublicKeyP *old_coin_pub);
+ (*get_old_coin_by_h_blind)(
+ void *cls,
+ const struct TALER_BlindedCoinHashP *h_blind_ev,
+ struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+ uint64_t *rrc_serial);
/**
@@ -2728,7 +5576,6 @@ struct TALER_EXCHANGEDB_Plugin
* in the database.
*
* @param cls closure
- * @param session a session
* @param denom_pub_hash hash of the revoked denomination key
* @param master_sig signature affirming the revocation
* @return transaction status code
@@ -2736,8 +5583,7 @@ struct TALER_EXCHANGEDB_Plugin
enum GNUNET_DB_QueryStatus
(*insert_denomination_revocation)(
void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
+ const struct TALER_DenominationHashP *denom_pub_hash,
const struct TALER_MasterSignatureP *master_sig);
@@ -2746,40 +5592,1652 @@ struct TALER_EXCHANGEDB_Plugin
* the database.
*
* @param cls closure
- * @param session a session
* @param denom_pub_hash hash of the revoked denomination key
* @param[out] master_sig signature affirming the revocation
* @param[out] rowid row where the information is stored
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*get_denomination_revocation)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- const struct GNUNET_HashCode *denom_pub_hash,
- struct TALER_MasterSignatureP *master_sig,
- uint64_t *rowid);
+ (*get_denomination_revocation)(
+ void *cls,
+ const struct TALER_DenominationHashP *denom_pub_hash,
+ struct TALER_MasterSignatureP *master_sig,
+ uint64_t *rowid);
/**
- * Select all of those deposits in the database for which we do
- * not have a wire transfer (or a refund) and which should have
- * been deposited between @a start_date and @a end_date.
+ * Select all (batch) deposits in the database
+ * above a given @a min_batch_deposit_serial_id.
*
* @param cls closure
- * @param session a session
- * @param start_date lower bound on the requested wire execution date
- * @param end_date upper bound on the requested wire execution date
+ * @param min_batch_deposit_serial_id only return entries strictly above this row (and in order)
* @param cb function to call on all such deposits
* @param cb_cls closure for @a cb
* @return transaction status code
*/
enum GNUNET_DB_QueryStatus
- (*select_deposits_missing_wire)(void *cls,
- struct TALER_EXCHANGEDB_Session *session,
- struct GNUNET_TIME_Absolute start_date,
- struct GNUNET_TIME_Absolute end_date,
- TALER_EXCHANGEDB_WireMissingCallback cb,
- void *cb_cls);
+ (*select_batch_deposits_missing_wire)(
+ void *cls,
+ uint64_t min_batch_deposit_serial_id,
+ TALER_EXCHANGEDB_WireMissingCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Select all aggregation tracking IDs in the database
+ * above a given @a min_tracking_serial_id.
+ *
+ * @param cls closure
+ * @param min_tracking_serial_id only return entries strictly above this row (and in order)
+ * @param cb function to call on all such aggregations
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aggregations_above_serial)(
+ void *cls,
+ uint64_t min_tracking_serial_id,
+ TALER_EXCHANGEDB_AggregationCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Return any applicable justification as to why
+ * a wire transfer might have been held. Used
+ * by the auditor to determine if a wire transfer
+ * is legitimately stalled.
+ *
+ * @param cls closure
+ * @param wire_target_h_payto effected target account
+ * @param[out] payto_uri target account URI, set to NULL if unknown
+ * @param[out] kyc_pending set to string describing missing KYC data
+ * @param[out] status set to AML status
+ * @param[out] aml_limit set to AML limit, or invalid amount for none
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_justification_for_missing_wire)(
+ void *cls,
+ const struct TALER_PaytoHashP *wire_target_h_payto,
+ char **payto_uri,
+ char **kyc_pending,
+ enum TALER_AmlDecisionState *status,
+ struct TALER_Amount *aml_limit);
+
+
+ /**
+ * Check the last date an auditor was modified.
+ *
+ * @param cls closure
+ * @param auditor_pub key to look up information for
+ * @param[out] last_date last modification date to auditor status
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_auditor_timestamp)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct GNUNET_TIME_Timestamp *last_date);
+
+
+ /**
+ * Lookup current state of an auditor.
+ *
+ * @param cls closure
+ * @param auditor_pub key to look up information for
+ * @param[out] auditor_url set to the base URL of the auditor's REST API; memory to be
+ * released by the caller!
+ * @param[out] enabled set if the auditor is currently in use
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_auditor_status)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ char **auditor_url,
+ bool *enabled);
+
+
+ /**
+ * Insert information about an auditor that will audit this exchange.
+ *
+ * @param cls closure
+ * @param auditor_pub key of the auditor
+ * @param auditor_url base URL of the auditor's REST service
+ * @param auditor_name name of the auditor (for humans)
+ * @param start_date date when the auditor was added by the offline system
+ * (only to be used for replay detection)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_auditor)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp start_date);
+
+
+ /**
+ * Update information about an auditor that will audit this exchange.
+ *
+ * @param cls closure
+ * @param auditor_pub key of the auditor (primary key for the existing record)
+ * @param auditor_url base URL of the auditor's REST service, to be updated
+ * @param auditor_name name of the auditor (for humans)
+ * @param change_date date when the auditor status was last changed
+ * (only to be used for replay detection)
+ * @param enabled true to enable, false to disable
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*update_auditor)(
+ void *cls,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const char *auditor_url,
+ const char *auditor_name,
+ struct GNUNET_TIME_Timestamp change_date,
+ bool enabled);
+
+
+ /**
+ * Check the last date an exchange wire account was modified.
+ *
+ * @param cls closure
+ * @param payto_uri key to look up information for
+ * @param[out] last_date last modification date to auditor status
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_wire_timestamp)(void *cls,
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp *last_date);
+
+
+ /**
+ * Insert information about an wire account used by this exchange.
+ *
+ * @param cls closure
+ * @param payto_uri wire account of the exchange
+ * @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param debit_restrictions JSON array with debit restrictions on the account
+ * @param credit_restrictions JSON array with credit restrictions on the account
+ * @param start_date date when the account was added by the offline system
+ * (only to be used for replay detection)
+ * @param master_sig public signature affirming the existence of the account,
+ * must be of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS
+ * @param bank_label label to show this entry under in the UI, can be NULL
+ * @param priority determines order in which entries are shown in the UI
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_wire)(void *cls,
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ struct GNUNET_TIME_Timestamp start_date,
+ const struct TALER_MasterSignatureP *master_sig,
+ const char *bank_label,
+ int64_t priority);
+
+
+ /**
+ * Update information about a wire account of the exchange.
+ *
+ * @param cls closure
+ * @param payto_uri account the update is about
+ * @param conversion_url URL of a conversion service, NULL if there is no conversion
+ * @param debit_restrictions JSON array with debit restrictions on the account; NULL allowed if not @a enabled
+ * @param credit_restrictions JSON array with credit restrictions on the account; NULL allowed if not @a enabled
+ * @param change_date date when the account status was last changed
+ * (only to be used for replay detection)
+ * @param master_sig master signature to store, can be NULL (if @a enabled is false)
+ * @param bank_label label to show this entry under in the UI, can be NULL
+ * @param priority determines order in which entries are shown in the UI
+ * @param enabled true to enable, false to disable (the actual change)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*update_wire)(void *cls,
+ const char *payto_uri,
+ const char *conversion_url,
+ const json_t *debit_restrictions,
+ const json_t *credit_restrictions,
+ struct GNUNET_TIME_Timestamp change_date,
+ const struct TALER_MasterSignatureP *master_sig,
+ const char *bank_label,
+ int64_t priority,
+ bool enabled);
+
+
+ /**
+ * Obtain information about the enabled wire accounts of the exchange.
+ *
+ * @param cls closure
+ * @param cb function to call on each account
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_wire_accounts)(void *cls,
+ TALER_EXCHANGEDB_WireAccountCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Obtain information about the fee structure of the exchange for
+ * a given @a wire_method
+ *
+ * @param cls closure
+ * @param wire_method which wire method to obtain fees for
+ * @param cb function to call on each account
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_wire_fees)(void *cls,
+ const char *wire_method,
+ TALER_EXCHANGEDB_WireFeeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Obtain information about the global fee structure of the exchange.
+ *
+ * @param cls closure
+ * @param cb function to call on each fee entry
+ * @param cb_cls closure for @a cb
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_global_fees)(void *cls,
+ TALER_EXCHANGEDB_GlobalFeeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Store information about a revoked online signing key.
+ *
+ * @param cls closure
+ * @param exchange_pub exchange online signing key that was revoked
+ * @param master_sig signature affirming the revocation
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_signkey_revocation)(
+ void *cls,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Obtain information about a revoked online signing key.
+ *
+ * @param cls closure
+ * @param exchange_pub exchange online signing key that was revoked
+ * @param[out] master_sig signature affirming the revocation
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_signkey_revocation)(
+ void *cls,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Lookup information about current denomination key.
+ *
+ * @param cls closure
+ * @param h_denom_pub hash of the denomination public key
+ * @param[out] meta set to various meta data about the key
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_denomination_key)(
+ void *cls,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta);
+
+
+ /**
+ * Add denomination key.
+ *
+ * @param cls closure
+ * @param h_denom_pub hash of the denomination public key
+ * @param denom_pub the denomination public key
+ * @param meta meta data about the denomination
+ * @param master_sig master signature to add
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*add_denomination_key)(
+ void *cls,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_DenominationPublicKey *denom_pub,
+ const struct TALER_EXCHANGEDB_DenominationKeyMetaData *meta,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Activate future signing key, turning it into a "current" or "valid"
+ * denomination key by adding the master signature.
+ *
+ * @param cls closure
+ * @param exchange_pub the exchange online signing public key
+ * @param meta meta data about @a exchange_pub
+ * @param master_sig master signature to add
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*activate_signing_key)(
+ void *cls,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ const struct TALER_EXCHANGEDB_SignkeyMetaData *meta,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Lookup signing key meta data.
+ *
+ * @param cls closure
+ * @param exchange_pub the exchange online signing public key
+ * @param[out] meta meta data about @a exchange_pub
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_signing_key)(
+ void *cls,
+ const struct TALER_ExchangePublicKeyP *exchange_pub,
+ struct TALER_EXCHANGEDB_SignkeyMetaData *meta);
+
+
+ /**
+ * Insert information about an auditor auditing a denomination key.
+ *
+ * @param cls closure
+ * @param h_denom_pub the audited denomination
+ * @param auditor_pub the auditor's key
+ * @param auditor_sig signature affirming the auditor's audit activity
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_auditor_denom_sig)(
+ void *cls,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ const struct TALER_AuditorSignatureP *auditor_sig);
+
+
+ /**
+ * Obtain information about an auditor auditing a denomination key.
+ *
+ * @param cls closure
+ * @param h_denom_pub the audited denomination
+ * @param auditor_pub the auditor's key
+ * @param[out] auditor_sig set to signature affirming the auditor's audit activity
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_auditor_denom_sig)(
+ void *cls,
+ const struct TALER_DenominationHashP *h_denom_pub,
+ const struct TALER_AuditorPublicKeyP *auditor_pub,
+ struct TALER_AuditorSignatureP *auditor_sig);
+
+
+ /**
+ * Lookup information about known wire fees.
+ *
+ * @param cls closure
+ * @param wire_method the wire method to lookup fees for
+ * @param start_time starting time of fee
+ * @param end_time end time of fee
+ * @param[out] fees set to wire fees for that time period; if
+ * different wire fee exists within this time
+ * period, an 'invalid' amount is returned.
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_wire_fee_by_time)(
+ void *cls,
+ const char *wire_method,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ struct TALER_WireFeeSet *fees);
+
+
+ /**
+ * Lookup information about known global fees.
+ *
+ * @param cls closure
+ * @param start_time starting time of fee
+ * @param end_time end time of fee
+ * @param[out] fees set to wire fees for that time period; if
+ * different global fee exists within this time
+ * period, an 'invalid' amount is returned.
+ * @param[out] purse_timeout set to when unmerged purses expire
+ * @param[out] history_expiration set to when we expire reserve histories
+ * @param[out] purse_account_limit set to number of free purses
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_global_fee_by_time)(
+ void *cls,
+ struct GNUNET_TIME_Timestamp start_time,
+ struct GNUNET_TIME_Timestamp end_time,
+ struct TALER_GlobalFeeSet *fees,
+ struct GNUNET_TIME_Relative *purse_timeout,
+ struct GNUNET_TIME_Relative *history_expiration,
+ uint32_t *purse_account_limit);
+
+
+ /**
+ * Lookup the latest serial number of @a table. Used in
+ * exchange-auditor database replication.
+ *
+ * @param cls closure
+ * @param table table for which we should return the serial
+ * @param[out] latest serial number in use
+ * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
+ * @a table does not have a serial number
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_serial_by_table)(void *cls,
+ enum TALER_EXCHANGEDB_ReplicatedTable table,
+ uint64_t *serial);
+
+ /**
+ * Lookup records above @a serial number in @a table. Used in
+ * exchange-auditor database replication.
+ *
+ * @param cls closure
+ * @param table table for which we should return the serial
+ * @param serial largest serial number to exclude
+ * @param cb function to call on the records
+ * @param cb_cls closure for @a cb
+ * @return transaction status code, GNUNET_DB_STATUS_HARD_ERROR if
+ * @a table does not have a serial number
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_records_by_table)(void *cls,
+ enum TALER_EXCHANGEDB_ReplicatedTable table,
+ uint64_t serial,
+ TALER_EXCHANGEDB_ReplicationCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Insert record set into @a table. Used in exchange-auditor database
+ * replication.
+ *
+ memset (&awc, 0, sizeof (awc));
+ * @param cls closure
+ * @param tb table data to insert
+ * @return transaction status code, #GNUNET_DB_STATUS_HARD_ERROR if
+ * @a table does not have a serial number
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_records_by_table)(void *cls,
+ const struct TALER_EXCHANGEDB_TableData *td);
+
+
+ /**
+ * Function called to grab a work shard on an operation @a op. Runs in its
+ * own transaction.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param job_name name of the operation to grab a word shard for
+ * @param delay minimum age of a shard to grab
+ * @param size desired shard size
+ * @param[out] start_row inclusive start row of the shard (returned)
+ * @param[out] end_row exclusive end row of the shard (returned)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*begin_shard)(void *cls,
+ const char *job_name,
+ struct GNUNET_TIME_Relative delay,
+ uint64_t shard_size,
+ uint64_t *start_row,
+ uint64_t *end_row);
+
+ /**
+ * Function called to abort work on a shard.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param job_name name of the operation to abort a word shard for
+ * @param start_row inclusive start row of the shard
+ * @param end_row exclusive end row of the shard
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*abort_shard)(void *cls,
+ const char *job_name,
+ uint64_t start_row,
+ uint64_t end_row);
+
+ /**
+ * Function called to persist that work on a shard was completed.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param job_name name of the operation to grab a word shard for
+ * @param start_row inclusive start row of the shard
+ * @param end_row exclusive end row of the shard
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*complete_shard)(void *cls,
+ const char *job_name,
+ uint64_t start_row,
+ uint64_t end_row);
+
+
+ /**
+ * Function called to grab a revolving work shard on an operation @a op. Runs
+ * in its own transaction. Returns the oldest inactive shard.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param job_name name of the operation to grab a revolving shard for
+ * @param shard_size desired shard size
+ * @param shard_limit exclusive end of the shard range
+ * @param[out] start_row inclusive start row of the shard (returned)
+ * @param[out] end_row inclusive end row of the shard (returned)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*begin_revolving_shard)(void *cls,
+ const char *job_name,
+ uint32_t shard_size,
+ uint32_t shard_limit,
+ uint32_t *start_row,
+ uint32_t *end_row);
+
+
+ /**
+ * Function called to release a revolving shard back into the work pool.
+ * Clears the "completed" flag.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param job_name name of the operation to grab a word shard for
+ * @param start_row inclusive start row of the shard
+ * @param end_row inclusive end row of the shard
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*release_revolving_shard)(void *cls,
+ const char *job_name,
+ uint32_t start_row,
+ uint32_t end_row);
+
+
+ /**
+ * Function called to delete all revolving shards.
+ * To be used after a crash or when the shard size is
+ * changed.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @return #GNUNET_OK on success
+ * #GNUNET_SYSERR on failure
+ */
+ enum GNUNET_GenericReturnValue
+ (*delete_shard_locks)(void *cls);
+
+
+ /**
+ * Function called to save the manifest of an extension
+ * (age-restriction, policy-extension, ...)
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param extension_name the name of the extension
+ * @param manifest JSON object of the Manifest as string, maybe NULL (== disabled extension)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*set_extension_manifest)(void *cls,
+ const char *extension_name,
+ const char *manifest);
+
+
+ /**
+ * Function called to retrieve the manifest of an extension
+ * (age-restriction, policy-extension, ...)
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param extension_name the name of the extension
+ * @param[out] manifest Manifest of the extension in JSON encoding, maybe NULL (== disabled extension)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_extension_manifest)(void *cls,
+ const char *extension_name,
+ char **manifest);
+
+
+ /**
+ * Function called to store configuration data about a partner
+ * exchange that we are federated with.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param master_pub public offline signing key of the partner exchange
+ * @param start_date when does the following data start to be valid
+ * @param end_date when does the validity end (exclusive)
+ * @param wad_frequency how often do we do exchange-to-exchange settlements?
+ * @param wad_fee how much do we charge for transfers to the partner
+ * @param partner_base_url base URL of the partner exchange
+ * @param master_sig signature with our offline signing key affirming the above
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_partner)(void *cls,
+ const struct TALER_MasterPublicKeyP *master_pub,
+ struct GNUNET_TIME_Timestamp start_date,
+ struct GNUNET_TIME_Timestamp end_date,
+ struct GNUNET_TIME_Relative wad_frequency,
+ const struct TALER_Amount *wad_fee,
+ const char *partner_base_url,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Function called to persist an encrypted contract associated with a reserve.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param econtract the encrypted contract
+ * @param[out] econtract_sig set to the signature over the encrypted contract
+ * @param[out] in_conflict set to true if @a econtract
+ * conflicts with an existing contract;
+ * in this case, the return value will be
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_contract)(void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_EncryptedContract *econtract,
+ bool *in_conflict);
+
+
+ /**
+ * Function called to retrieve an encrypted contract.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param pub_ckey set to the ephemeral DH used to encrypt the contract, key used to lookup the contract by
+ * @param[out] purse_pub public key of the purse of the contract
+ * @param[out] econtract_sig set to the signature over the encrypted contract
+ * @param[out] econtract_size set to the number of bytes in @a econtract
+ * @param[out] econtract set to the encrypted contract on success, to be freed by the caller
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_contract)(
+ void *cls,
+ const struct TALER_ContractDiffiePublicP *pub_ckey,
+ struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_PurseContractSignatureP *econtract_sig,
+ size_t *econtract_size,
+ void **econtract);
+
+
+ /**
+ * Function called to retrieve an encrypted contract.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub key to lookup the contract by
+ * @param[out] econtract set to the encrypted contract on success, to be freed by the caller
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_contract_by_purse)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_EncryptedContract *econtract);
+
+
+ /**
+ * Function called to create a new purse with certain meta data.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub public key of the new purse
+ * @param merge_pub public key providing the merge capability
+ * @param purse_expiration time when the purse will expire
+ * @param h_contract_terms hash of the contract for the purse
+ * @param age_limit age limit to enforce for payments into the purse
+ * @param flags flags for the operation
+ * @param purse_fee fee we are allowed to charge to the reserve (depending on @a flags)
+ * @param amount target amount (with fees) to be put into the purse
+ * @param purse_sig signature with @a purse_pub's private key affirming the above
+ * @param[out] in_conflict set to true if the meta data
+ * conflicts with an existing purse;
+ * in this case, the return value will be
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_purse_request)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ struct GNUNET_TIME_Timestamp purse_expiration,
+ const struct TALER_PrivateContractHashP *h_contract_terms,
+ uint32_t age_limit,
+ enum TALER_WalletAccountMergeFlags flags,
+ const struct TALER_Amount *purse_fee,
+ const struct TALER_Amount *amount,
+ const struct TALER_PurseContractSignatureP *purse_sig,
+ bool *in_conflict);
+
+
+ /**
+ * Function called to clean up one expired purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param start_time select purse expired after this time
+ * @param end_time select purse expired before this time
+ * @return transaction status code (#GNUNET_DB_STATUS_SUCCESS_NO_RESULTS if no purse expired in the given time interval).
+ */
+ enum GNUNET_DB_QueryStatus
+ (*expire_purse)(
+ void *cls,
+ struct GNUNET_TIME_Absolute start_time,
+ struct GNUNET_TIME_Absolute end_time);
+
+
+ /**
+ * Function called to obtain information about a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub public key of the new purse
+ * @param[out] purse_creation set to time when the purse was created
+ * @param[out] purse_expiration set to time when the purse will expire
+ * @param[out] amount set to target amount (with fees) to be put into the purse
+ * @param[out] deposited set to actual amount put into the purse so far
+ * @param[out] h_contract_terms set to hash of the contract for the purse
+ * @param[out] merge_timestamp set to time when the purse was merged, or NEVER if not
+ * @param[out] purse_deleted set to true if purse was deleted
+ * @param[out] purse_refunded set to true if purse was refunded (after expiration)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Timestamp *purse_creation,
+ struct GNUNET_TIME_Timestamp *purse_expiration,
+ struct TALER_Amount *amount,
+ struct TALER_Amount *deposited,
+ struct TALER_PrivateContractHashP *h_contract_terms,
+ struct GNUNET_TIME_Timestamp *merge_timestamp,
+ bool *purse_deleted,
+ bool *purse_refunded);
+
+
+ /**
+ * Function called to return meta data about a purse by the
+ * purse public key.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub public key of the purse
+ * @param[out] merge_pub public key representing the merge capability
+ * @param[out] purse_expiration when would an unmerged purse expire
+ * @param[out] h_contract_terms contract associated with the purse
+ * @param[out] age_limit the age limit for deposits into the purse
+ * @param[out] target_amount amount to be put into the purse
+ * @param[out] balance amount put so far into the purse
+ * @param[out] purse_sig signature of the purse over the initialization data
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_purse_request)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_PurseMergePublicKeyP *merge_pub,
+ struct GNUNET_TIME_Timestamp *purse_expiration,
+ struct TALER_PrivateContractHashP *h_contract_terms,
+ uint32_t *age_limit,
+ struct TALER_Amount *target_amount,
+ struct TALER_Amount *balance,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+ /**
+ * Function called to return meta data about a purse by the
+ * merge capability key.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param merge_pub public key representing the merge capability
+ * @param[out] purse_pub public key of the purse
+ * @param[out] purse_expiration when would an unmerged purse expire
+ * @param[out] h_contract_terms contract associated with the purse
+ * @param[out] age_limit the age limit for deposits into the purse
+ * @param[out] target_amount amount to be put into the purse
+ * @param[out] balance amount put so far into the purse
+ * @param[out] purse_sig signature of the purse over the initialization data
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_by_merge_pub)(
+ void *cls,
+ const struct TALER_PurseMergePublicKeyP *merge_pub,
+ struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct GNUNET_TIME_Timestamp *purse_expiration,
+ struct TALER_PrivateContractHashP *h_contract_terms,
+ uint32_t *age_limit,
+ struct TALER_Amount *target_amount,
+ struct TALER_Amount *balance,
+ struct TALER_PurseContractSignatureP *purse_sig);
+
+
+ /**
+ * Function called to execute a transaction crediting
+ * a purse with @a amount from @a coin_pub. Reduces the
+ * value of @a coin_pub and increase the balance of
+ * the @a purse_pub purse. If the balance reaches the
+ * target amount and the purse has been merged, triggers
+ * the updates of the reserve/account balance.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to credit
+ * @param coin_pub coin to deposit (debit)
+ * @param amount fraction of the coin's value to deposit
+ * @param coin_sig signature affirming the operation
+ * @param amount_minus_fee amount to add to the purse
+ * @param[out] balance_ok set to false if the coin's
+ * remaining balance is below @a amount;
+ * in this case, the return value will be
+ * #GNUNET_DB_STATUS_SUCCESS_ONE_RESULT despite the failure
+ * @param[out] too_late it is too late to deposit into this purse
+ * @param[out] conflict the same coin was deposited into
+ * this purse with a different amount already
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_purse_deposit)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ const struct TALER_Amount *amount,
+ const struct TALER_CoinSpendSignatureP *coin_sig,
+ const struct TALER_Amount *amount_minus_fee,
+ bool *balance_ok,
+ bool *too_late,
+ bool *conflict);
+
+
+ /**
+ * Function called to explicitly delete a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to delete
+ * @param purse_sig signature affirming the deletion
+ * @param[out] decided set to true if the purse was
+ * already decided and thus could not be deleted
+ * @param[out] found set to true if the purse was found
+ * (if false, purse could not be deleted)
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_purse_delete)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseContractSignatureP *purse_sig,
+ bool *decided,
+ bool *found);
+
+
+ /**
+ * Set the current @a balance in the purse
+ * identified by @a purse_pub. Used by the auditor
+ * to update the balance as calculated by the auditor.
+ *
+ * @param cls closure
+ * @param purse_pub public key of a purse
+ * @param balance new balance to store under the purse
+ * @return transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*set_purse_balance)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_Amount *balance);
+
+
+ /**
+ * Function called to obtain a coin deposit data from
+ * depositing the coin into a purse.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to credit
+ * @param coin_pub coin to deposit (debit)
+ * @param[out] amount set fraction of the coin's value that was deposited (with fee)
+ * @param[out] h_denom_pub set to hash of denomination of the coin
+ * @param[out] phac set to hash of age restriction on the coin
+ * @param[out] coin_sig set to signature affirming the operation
+ * @param[out] partner_url set to the URL of the partner exchange, or NULL for ourselves, must be freed by caller
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_purse_deposit)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_CoinSpendPublicKeyP *coin_pub,
+ struct TALER_Amount *amount,
+ struct TALER_DenominationHashP *h_denom_pub,
+ struct TALER_AgeCommitmentHash *phac,
+ struct TALER_CoinSpendSignatureP *coin_sig,
+ char **partner_url);
+
+
+ /**
+ * Function called to approve merging a purse into a
+ * reserve by the respective purse merge key. The purse
+ * must not have been merged into a different reserve.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to merge
+ * @param merge_sig signature affirming the merge
+ * @param merge_timestamp time of the merge
+ * @param reserve_sig signature of the reserve affirming the merge
+ * @param partner_url URL of the partner exchange, can be NULL if the reserves lives with us
+ * @param reserve_pub public key of the reserve to credit
+ * @param[out] no_partner set to true if @a partner_url is unknown
+ * @param[out] no_balance set to true if the @a purse_pub is not paid up yet
+ * @param[out] no_reserve set to true if the @a reserve_pub is not known
+ * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_purse_merge)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergeSignatureP *merge_sig,
+ const struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const char *partner_url,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ bool *no_partner,
+ bool *no_balance,
+ bool *in_conflict);
+
+
+ /**
+ * Function called insert request to merge a purse into a reserve by the
+ * respective purse merge key. The purse must not have been merged into a
+ * different reserve.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub purse to merge
+ * @param merge_sig signature affirming the merge
+ * @param merge_timestamp time of the merge
+ * @param reserve_sig signature of the reserve affirming the merge
+ * @param purse_fee amount to charge the reserve for the purse creation, NULL to use the quota
+ * @param reserve_pub public key of the reserve to credit
+ * @param[out] in_conflict set to true if @a purse_pub was merged into a different reserve already
+ * @param[out] no_reserve set to true if @a reserve_pub is not a known reserve
+ * @param[out] insufficient_funds set to true if @a reserve_pub has insufficient capacity to create another purse
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*do_reserve_purse)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ const struct TALER_PurseMergeSignatureP *merge_sig,
+ const struct GNUNET_TIME_Timestamp merge_timestamp,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ const struct TALER_Amount *purse_fee,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ bool *in_conflict,
+ bool *no_reserve,
+ bool *insufficient_funds);
+
+
+ /**
+ * Function called to approve merging of a purse with
+ * an account, made by the receiving account.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param purse_pub public key of the purse
+ * @param[out] merge_sig set to the signature confirming the merge
+ * @param[out] merge_timestamp set to the time of the merge
+ * @param[out] partner_url set to the URL of the target exchange, or NULL if the target exchange is us. To be freed by the caller.
+ * @param[out] reserve_pub set to the public key of the reserve/account being credited
+ * @param[out] refunded set to true if purse was refunded
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_purse_merge)(
+ void *cls,
+ const struct TALER_PurseContractPublicKeyP *purse_pub,
+ struct TALER_PurseMergeSignatureP *merge_sig,
+ struct GNUNET_TIME_Timestamp *merge_timestamp,
+ char **partner_url,
+ struct TALER_ReservePublicKeyP *reserve_pub,
+ bool *refunded);
+
+
+ /**
+ * Function called to initiate closure of an account.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param reserve_pub public key of the account to close
+ * @param payto_uri where to wire the funds
+ * @param reserve_sig signature affiming that the account is to be closed
+ * @param request_timestamp timestamp of the close request
+ * @param balance balance at the time of closing
+ * @param closing_fee closing fee to charge
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_close_request)(void *cls,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ const char *payto_uri,
+ const struct TALER_ReserveSignatureP *reserve_sig,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_Amount *balance,
+ const struct TALER_Amount *closing_fee);
+
+
+ /**
+ * Function called to persist a request to drain profits.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param wtid wire transfer ID to use
+ * @param account_section account to drain
+ * @param payto_uri account to wire funds to
+ * @param request_timestamp time of the signature
+ * @param amount amount to wire
+ * @param master_sig signature affirming the operation
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_drain_profit)(void *cls,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ const char *account_section,
+ const char *payto_uri,
+ struct GNUNET_TIME_Timestamp request_timestamp,
+ const struct TALER_Amount *amount,
+ const struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Function called to get information about a profit drain event.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param wtid wire transfer ID to look up drain event for
+ * @param[out] serial set to serial ID of the entry
+ * @param[out] account_section set to account to drain
+ * @param[out] payto_uri set to account to wire funds to
+ * @param[out] request_timestamp set to time of the signature
+ * @param[out] amount set to amount to wire
+ * @param[out] master_sig set to signature affirming the operation
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_drain_profit)(void *cls,
+ const struct TALER_WireTransferIdentifierRawP *wtid,
+ uint64_t *serial,
+ char **account_section,
+ char **payto_uri,
+ struct GNUNET_TIME_Timestamp *request_timestamp,
+ struct TALER_Amount *amount,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Get profit drain operation ready to execute.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param[out] serial set to serial ID of the entry
+ * @param[out] wtid set set to wire transfer ID to use
+ * @param[out] account_section set to account to drain
+ * @param[out] payto_uri set to account to wire funds to
+ * @param[out] request_timestamp set to time of the signature
+ * @param[out] amount set to amount to wire
+ * @param[out] master_sig set to signature affirming the operation
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*profit_drains_get_pending)(
+ void *cls,
+ uint64_t *serial,
+ struct TALER_WireTransferIdentifierRawP *wtid,
+ char **account_section,
+ char **payto_uri,
+ struct GNUNET_TIME_Timestamp *request_timestamp,
+ struct TALER_Amount *amount,
+ struct TALER_MasterSignatureP *master_sig);
+
+
+ /**
+ * Set profit drain operation to finished.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param serial serial ID of the entry to mark finished
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*profit_drains_set_finished)(
+ void *cls,
+ uint64_t serial);
+
+
+ /**
+ * Insert KYC requirement for @a h_payto account into table.
+ *
+ * @param cls closure
+ * @param requirements requirements that must be checked
+ * @param h_payto account that must be KYC'ed
+ * @param reserve_pub if account is a reserve, its public key, NULL otherwise
+ * @param[out] requirement_row set to legitimization requirement row for this check
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_kyc_requirement_for_account)(
+ void *cls,
+ const char *requirements,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_ReservePublicKeyP *reserve_pub,
+ uint64_t *requirement_row);
+
+
+ /**
+ * Begin KYC requirement process.
+ *
+ * @param cls closure
+ * @param h_payto account that must be KYC'ed
+ * @param provider_section provider that must be checked
+ * @param provider_account_id provider account ID
+ * @param provider_legitimization_id provider legitimization ID
+ * @param[out] process_row row the process is stored under
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_kyc_requirement_process)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *provider_section,
+ const char *provider_account_id,
+ const char *provider_legitimization_id,
+ uint64_t *process_row);
+
+
+ /**
+ * Fetch information about pending KYC requirement process.
+ *
+ * @param cls closure
+ * @param h_payto account that must be KYC'ed
+ * @param provider_section provider that must be checked
+ * @param[out] redirect_url set to redirect URL for the process
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*get_pending_kyc_requirement_process)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *provider_section,
+ char **redirect_url);
+
+
+ /**
+ * Update KYC process with updated provider-linkage and/or
+ * expiration data.
+ *
+ * @param cls closure
+ * @param process_row row to select by
+ * @param provider_section provider that must be checked (technically redundant)
+ * @param h_payto account that must be KYC'ed (helps access by shard, otherwise also redundant)
+ * @param provider_account_id provider account ID
+ * @param provider_legitimization_id provider legitimization ID
+ * @param redirect_url where the user should be redirected to start the KYC process
+ * @param expiration how long is this KYC check set to be valid (in the past if invalid)
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*update_kyc_process_by_row)(
+ void *cls,
+ uint64_t process_row,
+ const char *provider_section,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *provider_account_id,
+ const char *provider_legitimization_id,
+ const char *redirect_url,
+ struct GNUNET_TIME_Absolute expiration);
+
+
+ /**
+ * Lookup KYC requirement.
+ *
+ * @param cls closure
+ * @param legi_row identifies requirement to look up
+ * @param[out] requirements space-separated list of requirements
+ * @param[out] aml_status set to the AML status of the account
+ * @param[out] h_payto account that must be KYC'ed
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_kyc_requirement_by_row)(
+ void *cls,
+ uint64_t requirement_row,
+ char **requirements,
+ enum TALER_AmlDecisionState *aml_status,
+ struct TALER_PaytoHashP *h_payto);
+
+
+ /**
+ * Lookup KYC process meta data.
+ *
+ * @param cls closure
+ * @param provider_section provider that must be checked
+ * @param h_payto account that must be KYC'ed
+ * @param[out] process_row set to row with the legitimization data
+ * @param[out] expiration how long is this KYC check set to be valid (in the past if invalid)
+ * @param[out] provider_account_id provider account ID
+ * @param[out] provider_legitimization_id provider legitimization ID
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_kyc_process_by_account)(
+ void *cls,
+ const char *provider_section,
+ const struct TALER_PaytoHashP *h_payto,
+ uint64_t *process_row,
+ struct GNUNET_TIME_Absolute *expiration,
+ char **provider_account_id,
+ char **provider_legitimization_id);
+
+
+ /**
+ * Lookup an
+ * @a h_payto by @a provider_legitimization_id.
+ *
+ * @param cls closure
+ * @param provider_section
+ * @param provider_legitimization_id legi to look up
+ * @param[out] h_payto where to write the result
+ * @param[out] process_row identifies the legitimization process on our end
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*kyc_provider_account_lookup)(
+ void *cls,
+ const char *provider_section,
+ const char *provider_legitimization_id,
+ struct TALER_PaytoHashP *h_payto,
+ uint64_t *process_row);
+
+
+ /**
+ * Call us on KYC processes satisfied for the given
+ * account.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param spc function to call for each satisfied KYC process
+ * @param spc_cls closure for @a spc
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_satisfied_kyc_processes)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_SatisfiedProviderCallback spc,
+ void *spc_cls);
+
+
+ /**
+ * Call us on KYC legitimization processes satisfied and not expired for the
+ * given account.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param lpc function to call for each satisfied KYC legitimization process
+ * @param lpc_cls closure for @a lpc
+ * @return transaction status code
+ */
+ enum GNUNET_DB_QueryStatus
+ (*iterate_kyc_reference)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_LegitimizationProcessCallback lpc,
+ void *lpc_cls);
+
+
+ /**
+ * Call @a kac on withdrawn amounts after @a time_limit which are relevant
+ * for a KYC trigger for a the (debited) account identified by @a h_payto.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param time_limit oldest transaction that could be relevant
+ * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK).
+ * @param kac_cls closure for @a kac
+ * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_withdraw_amounts_for_kyc_check)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ struct GNUNET_TIME_Absolute time_limit,
+ TALER_EXCHANGEDB_KycAmountCallback kac,
+ void *kac_cls);
+
+
+ /**
+ * Call @a kac on aggregated amounts after @a time_limit which are relevant for a
+ * KYC trigger for a the (credited) account identified by @a h_payto.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param time_limit oldest transaction that could be relevant
+ * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK).
+ * @param kac_cls closure for @a kac
+ * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aggregation_amounts_for_kyc_check)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ struct GNUNET_TIME_Absolute time_limit,
+ TALER_EXCHANGEDB_KycAmountCallback kac,
+ void *kac_cls);
+
+
+ /**
+ * Call @a kac on merged reserve amounts after @a time_limit which are relevant for a
+ * KYC trigger for a the wallet identified by @a h_payto.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param time_limit oldest transaction that could be relevant
+ * @param kac function to call for each applicable amount, in reverse chronological order (or until @a kac aborts by returning anything except #GNUNET_OK).
+ * @param kac_cls closure for @a kac
+ * @return transaction status code, @a kac aborting with #GNUNET_NO is not an error
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_merge_amounts_for_kyc_check)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ struct GNUNET_TIME_Absolute time_limit,
+ TALER_EXCHANGEDB_KycAmountCallback kac,
+ void *kac_cls);
+
+
+ /**
+ * Store KYC attribute data, update KYC process status and
+ * AML status for the given account.
+ *
+ * @param cls closure
+ * @param process_row KYC process row to update
+ * @param h_payto account for which the attribute data is stored
+ * @param kyc_prox key for similarity search
+ * @param provider_section provider that must be checked
+ * @param num_checks how many checks do these attributes satisfy
+ * @param satisfied_checks array of checks satisfied by these attributes
+ * @param provider_account_id provider account ID
+ * @param provider_legitimization_id provider legitimization ID
+ * @param birthday birthdate of user, in days after 1990, or 0 if unknown or definitively adult
+ * @param collection_time when was the data collected
+ * @param expiration_time when does the data expire
+ * @param enc_attributes_size number of bytes in @a enc_attributes
+ * @param enc_attributes encrypted attribute data
+ * @param require_aml true to trigger AML
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_kyc_attributes)(
+ void *cls,
+ uint64_t process_row,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct GNUNET_ShortHashCode *kyc_prox,
+ const char *provider_section,
+ unsigned int num_checks,
+ const char *satisfied_checks[static num_checks],
+ uint32_t birthday,
+ struct GNUNET_TIME_Timestamp collection_time,
+ const char *provider_account_id,
+ const char *provider_legitimization_id,
+ struct GNUNET_TIME_Absolute expiration_time,
+ size_t enc_attributes_size,
+ const void *enc_attributes,
+ bool require_aml);
+
+
+ /**
+ * Lookup similar KYC attribute data.
+ *
+ * @param cls closure
+ * @param kyc_prox key for similarity search
+ * @param cb callback to invoke on each match
+ * @param cb_cls closure for @a cb
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_similar_kyc_attributes)(
+ void *cls,
+ const struct GNUNET_ShortHashCode *kyc_prox,
+ TALER_EXCHANGEDB_AttributeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Lookup KYC attribute data for a specific account.
+ *
+ * @param cls closure
+ * @param h_payto account for which the attribute data is stored
+ * @param cb callback to invoke on each match
+ * @param cb_cls closure for @a cb
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_kyc_attributes)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_AttributeCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Insert AML staff record.
+ *
+ * @param cls closure
+ * @param decider_pub public key of the staff member
+ * @param master_sig offline signature affirming the AML officer
+ * @param decider_name full name of the staff member
+ * @param is_active true to enable, false to set as inactive
+ * @param read_only true to set read-only access
+ * @param last_change when was the change made effective
+ * @param[out] previous_change when was the previous change made
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_aml_officer)(
+ void *cls,
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+ const struct TALER_MasterSignatureP *master_sig,
+ const char *decider_name,
+ bool is_active,
+ bool read_only,
+ struct GNUNET_TIME_Timestamp last_change,
+ struct GNUNET_TIME_Timestamp *previous_change);
+
+
+ /**
+ * Test if the given AML staff member is active
+ * (at least read-only).
+ *
+ * @param cls closure
+ * @param decider_pub public key of the staff member
+ * @return database transaction status, if member is unknown or not active, 1 if member is active
+ */
+ enum GNUNET_DB_QueryStatus
+ (*test_aml_officer)(
+ void *cls,
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub);
+
+
+ /**
+ * Fetch AML staff record.
+ *
+ * @param cls closure
+ * @param decider_pub public key of the staff member
+ * @param[out] master_sig offline signature affirming the AML officer
+ * @param[out] decider_name full name of the staff member
+ * @param[out] is_active true to enable, false to set as inactive
+ * @param[out] read_only true to set read-only access
+ * @param[out] last_change when was the change made effective
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*lookup_aml_officer)(
+ void *cls,
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+ struct TALER_MasterSignatureP *master_sig,
+ char **decider_name,
+ bool *is_active,
+ bool *read_only,
+ struct GNUNET_TIME_Absolute *last_change);
+
+
+ /**
+ * Obtain the current AML threshold set for an account.
+ *
+ * @param cls closure
+ * @param h_payto account for which the AML threshold is stored
+ * @param[out] decision set to current AML decision
+ * @param[out] threshold set to the existing threshold
+ * @return database transaction status, 0 if no threshold was set
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aml_threshold)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ enum TALER_AmlDecisionState *decision,
+ struct TALER_EXCHANGEDB_KycStatus *kyc,
+ struct TALER_Amount *threshold);
+
+
+ /**
+ * Trigger AML process, an account has crossed the threshold. Inserts or
+ * updates the AML status.
+ *
+ * @param cls closure
+ * @param h_payto account for which the attribute data is stored
+ * @param threshold_crossed existing threshold that was crossed
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*trigger_aml_process)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_Amount *threshold_crossed);
+
+
+ /**
+ * Lookup AML decisions that have a particular state.
+ *
+ * @param cls closure
+ * @param decision which decision states to filter by
+ * @param row_off offset to start from
+ * @param forward true to go forward in time, false to go backwards
+ * @param cb callback to invoke on each match
+ * @param cb_cls closure for @a cb
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aml_process)(
+ void *cls,
+ enum TALER_AmlDecisionState decision,
+ uint64_t row_off,
+ uint64_t limit,
+ bool forward,
+ TALER_EXCHANGEDB_AmlStatusCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Lookup AML decision history for a particular account.
+ *
+ * @param cls closure
+ * @param h_payto which account should we return the AML decision history for
+ * @param cb callback to invoke on each match
+ * @param cb_cls closure for @a cb
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*select_aml_history)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_AmlHistoryCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Insert an AML decision. Inserts into AML history and insert or updates AML
+ * status.
+ *
+ * @param cls closure
+ * @param h_payto account for which the attribute data is stored
+ * @param new_threshold new monthly threshold that would trigger an AML check
+ * @param new_status AML decision status
+ * @param decision_time when was the decision made
+ * @param justification human-readable text justifying the decision
+ * @param kyc_requirements specific KYC requirements being imposed
+ * @param requirements_row row in the KYC table for this process, 0 for none
+ * @param decider_pub public key of the staff member
+ * @param decider_sig signature of the staff member
+ * @param[out] invalid_officer set to TRUE if @a decider_pub is not allowed to make decisions right now
+ * @param[out] last_date set to the previous decision time;
+ * the INSERT is not performed if @a last_date is not before @a decision_time
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_aml_decision)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ const struct TALER_Amount *new_threshold,
+ enum TALER_AmlDecisionState new_status,
+ struct GNUNET_TIME_Timestamp decision_time,
+ const char *justification,
+ const json_t *kyc_requirements,
+ uint64_t requirements_row,
+ const struct TALER_AmlOfficerPublicKeyP *decider_pub,
+ const struct TALER_AmlOfficerSignatureP *decider_sig,
+ bool *invalid_officer,
+ struct GNUNET_TIME_Timestamp *last_date);
+
+
+ /**
+ * Update KYC process status to finished (and failed).
+ *
+ * @param cls closure
+ * @param process_row KYC process row to update
+ * @param h_payto account for which the attribute data is stored
+ * @param provider_section provider that must be checked
+ * @param provider_account_id provider account ID
+ * @param provider_legitimization_id provider legitimization ID
+ * @return database transaction status
+ */
+ enum GNUNET_DB_QueryStatus
+ (*insert_kyc_failure)(
+ void *cls,
+ uint64_t process_row,
+ const struct TALER_PaytoHashP *h_payto,
+ const char *provider_section,
+ const char *provider_account_id,
+ const char *provider_legitimization_id);
+
+ /**
+ * Function called to inject auditor triggers into the
+ * database, triggering the real-time auditor upon
+ * relevant INSERTs.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success,
+ * #GNUNET_SYSERR on DB errors
+ */
+ enum GNUNET_GenericReturnValue
+ (*inject_auditor_triggers)(void *cls);
};
diff --git a/src/include/taler_extensions.h b/src/include/taler_extensions.h
new file mode 100644
index 000000000..1eb567f72
--- /dev/null
+++ b/src/include/taler_extensions.h
@@ -0,0 +1,386 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file include/taler_extensions.h
+ * @brief Interface for extensions
+ * @author Özgür Kesim
+ */
+#ifndef TALER_EXTENSIONS_H
+#define TALER_EXTENSIONS_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+#include "taler_extensions_policy.h"
+
+
+#define TALER_EXTENSION_SECTION_PREFIX "exchange-extension-"
+
+enum TALER_Extension_Type
+{
+ TALER_Extension_PolicyNull = 0,
+
+ TALER_Extension_AgeRestriction = 1,
+ TALER_Extension_PolicyMerchantRefund = 2,
+ TALER_Extension_PolicyBrandtVickeryAuction = 3,
+ TALER_Extension_PolicyEscrowedPayment = 4,
+
+ TALER_Extension_MaxPredefined = 5 // Must be last of the predefined
+};
+
+
+/* Forward declarations */
+enum TALER_PolicyFulfillmentState;
+struct TALER_PolicyFulfillmentOutcome;
+
+/*
+ * @brief Represents the implementation of an extension.
+ *
+ * An "Extension" is an optional feature for the Exchange.
+ * There are only two types of extensions:
+ *
+ * a) Age restriction: This is a special feature that directly interacts with
+ * denominations and coins, but is not define policies during deposits, see b).
+ * The implementation of this extension doesn't have to implement any of the
+ * http- or depost-handlers in the struct.
+ *
+ * b) Policies for deposits: These are extensions that define policies (such
+ * as refund, escrow or auctions) for deposit requests. These extensions have
+ * to implement at least the deposit- and post-http-handler in the struct to be
+ * functional.
+ *
+ * In addition to the handlers defined in this struct, an extension must also
+ * be a plugin in the GNUNET_Plugin sense. That is, it must implement the
+ * functions
+ * 1: (void *ext)libtaler_extension_<name>_init(void *cfg)
+ * and
+ * 2: (void *)libtaler_extension_<name>_done(void *)
+ *
+ * In 1:, the input will be the GNUNET_CONFIGURATION_Handle to the TALER
+ * configuration and the output must be the struct TALER_Extension * on
+ * success, NULL otherwise.
+ *
+ * In 2:, no arguments are passed and NULL is expected to be returned.
+ */
+struct TALER_Extension
+{
+ /**
+ * Type of the extension. Only one extension of a type can be loaded
+ * at any time.
+ */
+ enum TALER_Extension_Type type;
+
+ /**
+ * The name of the extension, must be unique among all loaded extensions. It
+ * is used in URLs for /extension/$NAME as well.
+ */
+ char *name;
+
+ /**
+ * Criticality of the extension. It has the same semantics as "critical" has
+ * for extensions in X.509:
+ * - if "true", the client must "understand" the extension before proceeding,
+ * - if "false", clients can safely skip extensions they do not understand.
+ * (see https://datatracker.ietf.org/doc/html/rfc5280#section-4.2)
+ */
+ bool critical;
+
+ /**
+ * Version of the extension must be provided in Taler's protocol version ranges notation, see
+ * https://docs.taler.net/core/api-common.html#protocol-version-ranges
+ */
+ char *version;
+
+ /**
+ * If the extension is marked as enabled, it will be listed in the
+ * "extensions" field in the "/keys" response.
+ */
+ bool enabled;
+
+ /**
+ * Opaque (public) configuration object, set by the extension.
+ */
+ void *config;
+
+
+ /**
+ * @brief Handler to to disable the extension.
+ *
+ * @param ext The current extension object
+ */
+ void (*disable)(struct TALER_Extension *ext);
+
+ /**
+ * @brief Handler to read an extension-specific configuration in JSON
+ * encoding and enable the extension. Must be implemented by the extension.
+ *
+ * @param[in] ext The extension object. If NULL, the configuration will only be checked.
+ * @param[in,out] config A JSON blob
+ * @return GNUNET_OK if the json was a valid configuration for the extension.
+ */
+ enum GNUNET_GenericReturnValue (*load_config)(
+ const json_t *config,
+ struct TALER_Extension *ext);
+
+ /**
+ * @brief Handler to return the manifest of the extension in JSON encoding.
+ *
+ * See
+ * https://docs.taler.net/design-documents/006-extensions.html#tsref-type-Extension
+ * for the definition.
+ *
+ * @param ext The extension object
+ * @return The JSON encoding of the extension, if enabled, NULL otherwise.
+ */
+ json_t *(*manifest)(
+ const struct TALER_Extension *ext);
+
+ /* =========================
+ * Policy related handlers
+ * =========================
+ */
+
+ /**
+ * @brief Handler to check an incoming policy and create a
+ * TALER_PolicyDetails. Can be NULL;
+ *
+ * When a deposit request refers to this extension in its policy
+ * (see https://docs.taler.net/core/api-exchange.html#deposit), this handler
+ * will be called before the deposit transaction.
+ *
+ * @param[in] currency Currency used in the exchange
+ * @param[in] policy_json Details about the policy, provided by the client
+ * during a deposit request.
+ * @param[out] details On success, will contain the details to the policy,
+ * evaluated by the corresponding policy handler.
+ * @param[out] error_hint On error, will contain a hint
+ * @return GNUNET_OK if the data was accepted by the extension.
+ */
+ enum GNUNET_GenericReturnValue (*create_policy_details)(
+ const char *currency,
+ const json_t *policy_json,
+ struct TALER_PolicyDetails *details,
+ const char **error_hint);
+
+ /**
+ * @brief Handler for POST-requests to the /extensions/$name endpoint. Can be NULL.
+ *
+ * @param[in] root The JSON body from the request
+ * @param[in] args Additional query parameters of the request.
+ * @param[in,out] details List of policy details related to the incoming fulfillment proof
+ * @param[in] details_len Size of the list @e details
+ * @param[out] output JSON output to return to the client
+ * @return GNUNET_OK on success.
+ */
+ enum GNUNET_GenericReturnValue (*policy_post_handler)(
+ const json_t *root,
+ const char *const args[],
+ struct TALER_PolicyDetails *details,
+ size_t details_len,
+ json_t **output);
+
+ /**
+ * @brief Handler for GET-requests to the /extensions/$name endpoint. Can be NULL.
+ *
+ * @param connection The current connection
+ * @param root The JSON body from the request
+ * @param args Additional query parameters of the request.
+ * @return MDH result
+ */
+ MHD_RESULT (*policy_get_handler)(
+ struct MHD_Connection *connection,
+ const char *const args[]);
+};
+
+
+/*
+ * @brief simply linked list of extensions
+ */
+
+struct TALER_Extensions
+{
+ struct TALER_Extensions *next;
+ const struct TALER_Extension *extension;
+};
+
+/**
+ * Generic functions for extensions
+ */
+
+/**
+ * @brief Loads the extensions as shared libraries, as specified in the given
+ * TALER configuration.
+ *
+ * @param cfg Handle to the TALER configuration
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were found
+ * or any particular configuration couldn't be parsed.
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_init (
+ const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+/*
+ * @brief Parses a given JSON object as an extension manifest.
+ *
+ * @param[in] obj JSON object to parse as an extension manifest
+ * @param{out] critical will be set to 1 if the extension is critical according to obj
+ * @param[out] version will be set to the version of the extension according to obj
+ * @param[out] config will be set to the configuration of the extension according to obj
+ * @return OK on success, Error otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_parse_manifest (
+ json_t *obj,
+ int *critical,
+ const char **version,
+ json_t **config);
+
+/*
+ * @brief Loads extensions according to the manifests.
+ *
+ * The JSON object must be of type ExtensionsManifestsResponse as described
+ * in https://docs.taler.net/design-documents/006-extensions.html#exchange
+ *
+ * @param cfg JSON object containing the manifests for all extensions
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if unknown extensions were
+ * found or any particular configuration couldn't be parsed.
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_load_manifests (
+ const json_t *manifests);
+
+/*
+ * @brief Returns the head of the linked list of extensions.
+ */
+const struct TALER_Extensions *
+TALER_extensions_get_head (void);
+
+/**
+ * @brief Finds and returns a supported extension by a given type.
+ *
+ * @param type of the extension to lookup
+ * @return extension found, or NULL (should not happen!)
+ */
+const struct TALER_Extension *
+TALER_extensions_get_by_type (
+ enum TALER_Extension_Type type);
+
+
+/**
+ * @brief Finds and returns a supported extension by a given name.
+ *
+ * @param name name of the extension to lookup
+ * @return the extension, if found, NULL otherwise
+ */
+const struct TALER_Extension *
+TALER_extensions_get_by_name (
+ const char *name);
+
+/**
+ * @brief Check if a given type of an extension is enabled
+ *
+ * @param type type of to check
+ * @return true enabled, false if not enabled, will assert if type is not found.
+ */
+bool
+TALER_extensions_is_enabled_type (
+ enum TALER_Extension_Type type);
+
+/**
+ * @brief Check if an extension is enabled
+ *
+ * @param extension The extension handler.
+ * @return true enabled, false if not enabled, will assert if type is not found.
+ */
+bool
+TALER_extensions_is_enabled (
+ const struct TALER_Extension *extension);
+
+/*
+ * Verify the signature of a given JSON object for extensions with the master
+ * key of the exchange.
+ *
+ * The JSON object must be of type ExtensionsManifestsResponse as described in
+ * https://docs.taler.net/design-documents/006-extensions.html#exchange
+ *
+ * @param extensions JSON object with the extension configuration
+ * @param extensions_sig signature of the hash of the JSON object
+ * @param master_pub public key to verify the signature
+ * @return GNUNET_OK on success, GNUNET_SYSERR when hashing of the JSON fails
+ * and GNUNET_NO if the signature couldn't be verified.
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_verify_manifests_signature (
+ const json_t *manifests,
+ struct TALER_MasterSignatureP *extensions_sig,
+ struct TALER_MasterPublicKeyP *master_pub);
+
+
+/*
+ * TALER Age Restriction Extension
+ *
+ * This extension is special insofar as it directly interacts with coins and
+ * denominations.
+ *
+ * At the same time, it doesn't implement and http- or deposit-handlers.
+ */
+
+#define TALER_EXTENSION_SECTION_AGE_RESTRICTION (TALER_EXTENSION_SECTION_PREFIX \
+ "age_restriction")
+
+/**
+ * The default age mask represents the age groups
+ * 0-7, 8-9, 10-11, 12-13, 14-15, 16-17, 18-20, 21-...
+ */
+#define TALER_EXTENSION_AGE_RESTRICTION_DEFAULT_AGE_GROUPS "8:10:12:14:16:18:21"
+
+
+/*
+ * @brief Configuration for Age Restriction
+ */
+struct TALER_AgeRestrictionConfig
+{
+ struct TALER_AgeMask mask;
+ uint8_t num_groups;
+};
+
+
+/**
+ * @brief Retrieve the age restriction configuration
+ *
+ * @return age restriction configuration if present, otherwise NULL.
+ */
+const struct TALER_AgeRestrictionConfig *
+TALER_extensions_get_age_restriction_config (void);
+
+/**
+ * @brief Check if age restriction is enabled
+ *
+ * @return true, if age restriction is loaded, configured and enabled; otherwise false.
+ */
+bool
+TALER_extensions_is_age_restriction_enabled (void);
+
+/**
+ * @brief Return the age mask for age restriction
+ *
+ * @return configured age mask, if age restriction is loaded, configured and enabled; otherwise zero mask.
+ */
+struct TALER_AgeMask
+TALER_extensions_get_age_restriction_mask (void);
+
+#endif
diff --git a/src/include/taler_extensions_policy.h b/src/include/taler_extensions_policy.h
new file mode 100644
index 000000000..b10c0d8a2
--- /dev/null
+++ b/src/include/taler_extensions_policy.h
@@ -0,0 +1,205 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+/**
+ * @file include/taler_extensions_policy.h
+ * @brief Interface for policy extensions
+ * @author Özgür Kesim
+ */
+#ifndef TALER_EXTENSIONS_POLICY_H
+#define TALER_EXTENSIONS_POLICY_H
+
+#include <gnunet/gnunet_util_lib.h>
+#include "taler_util.h"
+#include "taler_json_lib.h"
+#include "taler_mhd_lib.h"
+
+/*
+ * @brief Describes the states of fulfillment of a policy bound to a deposit
+ * NOTE: These values must be in sync with their use in stored procedures, f.e.
+ * exchange_do_insert_or_update_policy_details.
+ */
+enum TALER_PolicyFulfillmentState
+{
+ /* Initial state of an fulfillment, before any other state. */
+ TALER_PolicyFulfillmentInitial = 0,
+
+ /* General error state of an fulfillment. */
+ TALER_PolicyFulfillmentFailure = 1,
+
+ /* The policy is not yet ready due to insufficient funding. More deposits are
+ * necessary for it to become ready . */
+ TALER_PolicyFulfillmentInsufficient = 2,
+
+ /* The policy is funded and ready, pending */
+ TALER_PolicyFulfillmentReady = 3,
+
+ /* Policy is provably fulfilled. */
+ TALER_PolicyFulfillmentSuccess = 4,
+
+ /* Policy fulfillment has timed out */
+ TALER_PolicyFulfillmentTimeout = 5,
+
+ TALER_PolicyFulfillmentStateCount = TALER_PolicyFulfillmentTimeout + 1
+};
+
+
+/*
+ * @brief Returns a string representation of the state of a policy fulfillment
+ */
+const char *
+TALER_policy_fulfillment_state_str (enum TALER_PolicyFulfillmentState state);
+
+
+/* @brief Details of a policy for a deposit request */
+struct TALER_PolicyDetails
+{
+ /* Hash code that should be used for the .policy_hash_code field when
+ * this policy is saved in the policy_details table. */
+ struct GNUNET_HashCode hash_code;
+
+ /* Content of the policy in its original JSON form */
+ json_t *policy_json;
+
+ /* When the deadline is met and the policy is still in "Ready" state,
+ * a timeout-handler will transfer the amount
+ * (total_amount - policy_fee - refreshable_amount)
+ * to the payto-URI from the corresponding deposit. The value
+ * amount_refreshable will be refreshable by the owner of the
+ * associated deposits's coins */
+ struct GNUNET_TIME_Timestamp deadline;
+
+ /* The amount to which this policy commits to. It must be at least as
+ * large as @e policy_fee. */
+ struct TALER_Amount commitment;
+
+ /* The total sum of contributions from coins so far to fund this
+ * policy. It must be at least as large as @commitment in order to be
+ * sufficiently funded. */
+ struct TALER_Amount accumulated_total;
+
+ /* The fee from the exchange for handling the policy. It is due when
+ * the state changes to Timeout or Success. */
+ struct TALER_Amount policy_fee;
+
+ /* The amount that will be transferred to the payto-URIs from the
+ * corresponding deposits when the fulfillment state changes to Timeout
+ * or Success. Note that a fulfillment handler can alter this upon
+ * arrival of a proof of fulfillment. The remaining amount
+ * (accumulated_amount - policy_amount - transferable_amount) */
+ struct TALER_Amount transferable_amount;
+
+ /* The state of fulfillment of a policy.
+ * - If the state is Insufficient, the client is required to call
+ * /deposit -maybe multiple times- with enough coins and the same
+ * policy details in order to reach the required amount. The state is
+ * then changed to Ready.
+ * - If the state changes to Timeout or Success, a handler will transfer
+ * the amount (total_amount - policy_fee - refreshable_amount) to the
+ * payto-URI from the corresponding deposit. The value
+ * amount_refreshable will be refreshable by the owner of the
+ * associated deposits's coins. */
+ enum TALER_PolicyFulfillmentState fulfillment_state;
+
+ /* If there is a proof of fulfillment, the row ID from the
+ * policy_fulfillment table */
+ uint64_t policy_fulfillment_id;
+ bool no_policy_fulfillment_id;
+};
+
+/*
+ * @brief All information required for the database transaction when handling a
+ * proof of fulfillment request.
+ */
+struct TALER_PolicyFulfillmentTransactionData
+{
+ /* The incoming proof, provided by a client */
+ const json_t *proof;
+
+ /* The Hash of the proof */
+ struct GNUNET_HashCode h_proof;
+
+ /* The timestamp of retrieval of the proof */
+ struct GNUNET_TIME_Timestamp timestamp;
+
+ /* The ID of the proof in the policy_fulfillment table. Will be set
+ * during the transaction. Needed to fill the table
+ * policy_details_fulfillments. */
+ uint64_t fulfillment_id;
+
+ /* The list of policy details. Will be updated by the policy handler */
+ struct TALER_PolicyDetails *details;
+ size_t details_count;
+};
+
+
+/*
+ * @brief Extracts policy details from the deposit's policy options and the policy extensions
+ *
+ * @param[in] currency Currency used in the exchange
+ * @param[in] policy_options JSON of the policy options from a deposit request
+ * @param[out] details On GNUNET_OK, the parsed details
+ * @param[out] error_hint On GNUNET_SYSERR, will contain a hint for the reason why it failed
+ * @return GNUNET_OK on success, GNUNET_NO, when no extension was found. GNUNET_SYSERR when the JSON was
+ * invalid, with *error_hint maybe non-NULL.
+ */
+enum GNUNET_GenericReturnValue
+TALER_extensions_create_policy_details (
+ const char *currency,
+ const json_t *policy_options,
+ struct TALER_PolicyDetails *details,
+ const char **error_hint);
+
+
+/*
+ * ================================
+ * Merchant refund policy
+ * ================================
+ */
+struct TALER_ExtensionPolicyMerchantRefundPolicyConfig
+{
+ struct GNUNET_TIME_Relative max_timeout;
+};
+
+/*
+ * ================================
+ * Brandt-Vickrey Auctions policy
+ * ================================
+ */
+/*
+ * @brief Configuration for Brandt-Vickrey auctions policy
+ */
+struct TALER_ExtensionPolicyBrandtVickreyAuctionConfig
+{
+ uint16_t max_bidders;
+ uint16_t max_prices;
+ struct TALER_Amount auction_fee;
+};
+
+
+/*
+ * ================================
+ * Escrowed Payments policy
+ * ================================
+ */
+/*
+ * @brief Configuration for escrowed payments policy
+ */
+struct TALER_ExtensionPolicyEscrowedPaymentsConfig
+{
+ struct GNUNET_TIME_Relative max_timeout;
+};
+
+#endif
diff --git a/src/include/taler_fakebank_lib.h b/src/include/taler_fakebank_lib.h
index bd4376695..6b34f4730 100644
--- a/src/include/taler_fakebank_lib.h
+++ b/src/include/taler_fakebank_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2016-2020 Taler Systems SA
+ (C) 2016-2021 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -53,61 +53,71 @@ TALER_FAKEBANK_start (uint16_t port,
/**
- * Check that no wire transfers were ordered (or at least none
- * that have not been taken care of via #TALER_FAKEBANK_check_debit()
- * or #TALER_FAKEBANK_check_credit()).
- * If any transactions are onrecord, return #GNUNET_SYSERR.
+ * Start the fake bank. The fake bank will, like the normal bank, listen for
+ * requests for /admin/add/incoming and /transfer. However, instead of
+ * executing or storing those requests, it will simply allow querying whether
+ * such a request has been made via #TALER_FAKEBANK_check_debit() and
+ * #TALER_FAKEBANK_check_credit() as well as the history API.
*
- * @param h bank instance
- * @return #GNUNET_OK on success
+ * This is useful for writing testcases to check whether the exchange
+ * would have issued the correct wire transfer orders.
+ *
+ * @param port port to listen to
+ * @param currency which currency should the bank offer
+ * @param ram_limit how much memory do we use at most
+ * @param num_threads size of the thread pool, 0 to use the GNUnet scheduler
+ * @return NULL on error
*/
-int
-TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h);
+struct TALER_FAKEBANK_Handle *
+TALER_FAKEBANK_start2 (uint16_t port,
+ const char *currency,
+ uint64_t ram_limit,
+ unsigned int num_threads);
/**
- * Tell the fakebank to create another wire transfer *from* an exchange.
+ * Start the fake bank. The fake bank will, like the normal bank, listen for
+ * requests for /admin/add/incoming and /transfer. However, instead of
+ * executing or storing those requests, it will simply allow querying whether
+ * such a request has been made via #TALER_FAKEBANK_check_debit() and
+ * #TALER_FAKEBANK_check_credit() as well as the history API.
+ *
+ * This is useful for writing testcases to check whether the exchange
+ * would have issued the correct wire transfer orders.
*
- * @param h fake bank handle
- * @param debit_account account to debit
- * @param credit_account account to credit
- * @param amount amount to transfer
- * @param subject wire transfer subject to use
- * @param exchange_base_url exchange URL
- * @param request_uid unique number to make the request unique, or NULL to create one
- * @param[out] ret_row_id pointer to store the row ID of this transaction
- * @return #GNUNET_YES if the transfer was successful,
- * #GNUNET_SYSERR if the request_uid was reused for a different transfer
+ * @param hostname hostname to use in URLs and URIs.
+ * @param port port to listen to
+ * @param exchange_url suggested exchange base URL
+ * @param currency which currency should the bank offer
+ * @param ram_limit how much memory do we use at most
+ * @param num_threads size of the thread pool, 0 to use the GNUnet scheduler
+ * @param signup_bonus how much to credit new users
+ * @return NULL on error
*/
-int
-TALER_FAKEBANK_make_transfer (
- struct TALER_FAKEBANK_Handle *h,
- const char *debit_account,
- const char *credit_account,
- const struct TALER_Amount *amount,
- const struct TALER_WireTransferIdentifierRawP *subject,
- const char *exchange_base_url,
- const struct GNUNET_HashCode *request_uid,
- uint64_t *ret_row_id);
+struct TALER_FAKEBANK_Handle *
+TALER_FAKEBANK_start3 (const char *hostname,
+ uint16_t port,
+ const char *exchange_url,
+ const char *currency,
+ uint64_t ram_limit,
+ unsigned int num_threads,
+ const struct TALER_Amount *signup_bonus);
/**
- * Tell the fakebank to create another wire transfer *to* an exchange.
+ * Check that no wire transfers were ordered (or at least none
+ * that have not been taken care of via #TALER_FAKEBANK_check_debit()
+ * or #TALER_FAKEBANK_check_credit()).
+ * If any transactions are onrecord, return #GNUNET_SYSERR.
+ *
+ * Note that this function only works in
+ * single-threaded mode while nothing else is happening.
*
- * @param h fake bank handle
- * @param debit_account account to debit
- * @param credit_account account to credit
- * @param amount amount to transfer
- * @param reserve_pub reserve public key to use in subject
- * @return serial_id of the transfer
+ * @param h bank instance
+ * @return #GNUNET_OK on success
*/
-uint64_t
-TALER_FAKEBANK_make_admin_transfer (
- struct TALER_FAKEBANK_Handle *h,
- const char *debit_account,
- const char *credit_account,
- const struct TALER_Amount *amount,
- const struct TALER_ReservePublicKeyP *reserve_pub);
+enum GNUNET_GenericReturnValue
+TALER_FAKEBANK_check_empty (struct TALER_FAKEBANK_Handle *h);
/**
@@ -116,16 +126,19 @@ TALER_FAKEBANK_make_admin_transfer (
* to the transfer identifier and remove the transaction from the
* list. If the transaction was not recorded, return #GNUNET_SYSERR.
*
+ * Note that this function only works in
+ * single-threaded mode while nothing else is happening.
+ *
* @param h bank instance
* @param want_amount transfer amount desired
* @param want_debit account that should have been debited
- * @param want_debit account that should have been credited
+ * @param want_credit account that should have been credited
* @param exchange_base_url expected base URL of the exchange,
* i.e. "https://example.com/"; may include a port
* @param[out] wtid set to the wire transfer identifier
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount,
const char *want_debit,
@@ -139,14 +152,17 @@ TALER_FAKEBANK_check_debit (struct TALER_FAKEBANK_Handle *h,
* @a want_credit account with the @a subject. If so, remove the transaction
* from the list. If the transaction was not recorded, return #GNUNET_SYSERR.
*
+ * Note that this function only works in
+ * single-threaded mode while nothing else is happening.
+ *
* @param h bank instance
* @param want_amount transfer amount desired
* @param want_debit account that should have been debited
- * @param want_debit account that should have been credited
+ * @param want_credit account that should have been credited
* @param reserve_pub reserve public key expected in wire subject
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TALER_FAKEBANK_check_credit (struct TALER_FAKEBANK_Handle *h,
const struct TALER_Amount *want_amount,
const char *want_debit,
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 094cbe2eb..98e565f0c 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -29,6 +29,40 @@
#include "taler_error_codes.h"
/**
+ * Version of this API, for compatibility tests.
+ */
+#define TALER_JSON_LIB_VERSION 0x00020000
+
+/**
+ * Details about an encrypted contract.
+ */
+struct TALER_EncryptedContract
+{
+
+ /**
+ * Signature of the client affiming this encrypted contract.
+ */
+ struct TALER_PurseContractSignatureP econtract_sig;
+
+ /**
+ * Contract decryption key for the purse.
+ */
+ struct TALER_ContractDiffiePublicP contract_pub;
+
+ /**
+ * Encrypted contract, can be NULL.
+ */
+ void *econtract;
+
+ /**
+ * Number of bytes in @e econtract.
+ */
+ size_t econtract_size;
+
+};
+
+
+/**
* Print JSON parsing related error information
* @deprecated
*/
@@ -37,14 +71,139 @@
"JSON parsing failed at %s:%u: %s (%s)\n", \
__FILE__, __LINE__, error.text, error.source)
+
/**
- * Convert a TALER amount to a JSON object.
+ * Generate packer instruction for a JSON field of type
+ * absolute time creating a human-readable timestamp.
*
- * @param amount the amount
- * @return a json object describing the amount
+ * @param name name of the field to add to the object
+ * @param at absolute time to pack
+ * @return json pack specification
*/
-json_t *
-TALER_JSON_from_amount (const struct TALER_Amount *amount);
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_time_abs_human (const char *name,
+ struct GNUNET_TIME_Absolute at);
+
+
+/**
+ * Put an error code into a JSON reply, including
+ * both the numeric value and the hint.
+ *
+ * @param ec error code to encode using canonical field names
+ */
+#define TALER_JSON_pack_ec(ec) \
+ GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec)), \
+ GNUNET_JSON_pack_uint64 ("code", ec)
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * denomination public key.
+ *
+ * @param name name of the field to add to the object
+ * @param pk public key
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_denom_pub (
+ const char *name,
+ const struct TALER_DenominationPublicKey *pk);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * denomination signature.
+ *
+ * @param name name of the field to add to the object
+ * @param sig signature
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_denom_sig (
+ const char *name,
+ const struct TALER_DenominationSignature *sig);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * blinded denomination signature (that needs to be
+ * unblinded before it becomes valid).
+ *
+ * @param name name of the field to add to the object
+ * @param sig signature
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_blinded_denom_sig (
+ const char *name,
+ const struct TALER_BlindedDenominationSignature *sig);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * blinded planchet.
+ *
+ * @param name name of the field to add to the object
+ * @param blinded_planchet blinded planchet
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_blinded_planchet (
+ const char *name,
+ const struct TALER_BlindedPlanchet *blinded_planchet);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * exchange withdraw values (/csr).
+ *
+ * @param name name of the field to add to the object
+ * @param ewv values to transmit
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_exchange_withdraw_values (
+ const char *name,
+ const struct TALER_ExchangeWithdrawValues *ewv);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * amount.
+ *
+ * @param name name of the field to add to the object
+ * @param amount valid amount to pack
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_amount (const char *name,
+ const struct TALER_Amount *amount);
+
+
+/**
+ * Generate packer instruction for a JSON field of type
+ * encrypted contract.
+ *
+ * @param name name of the field to add to the object
+ * @param econtract the encrypted contract
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_econtract (
+ const char *name,
+ const struct TALER_EncryptedContract *econtract);
+
+/**
+ * Generate packer instruction for a JSON field of type age_commitment
+ *
+ * @param name name of the field to add to the object
+ * @param age_commitment age commitment to add
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_age_commitment (
+ const char *name,
+ const struct TALER_AgeCommitment *age_commitment);
/**
@@ -54,31 +213,169 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount);
* @return a json object describing the amount
*/
json_t *
-TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount);
+TALER_JSON_from_amount (const struct TALER_Amount *amount);
/**
* Provide specification to parse given JSON object to an amount.
+ * The @a currency must be a valid pointer while the
+ * parsing is done, a copy is not made.
*
* @param name name of the amount field in the JSON
+ * @param currency the currency the amount must be in
* @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
*/
struct GNUNET_JSON_Specification
TALER_JSON_spec_amount (const char *name,
+ const char *currency,
struct TALER_Amount *r_amount);
/**
+ * Provide specification to parse given JSON object to
+ * a currency specification.
+ *
+ * @param name name of the amount field in the JSON
+ * @param currency_code currency code to parse
+ * @param[out] r_cspec where the currency spec has to be written
+ * @return spec for parsing an amount
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_currency_specification (
+ const char *name,
+ const char *currency_code,
+ struct TALER_CurrencySpecification *r_cspec);
+
+
+/**
* Provide specification to parse given JSON object to an amount
- * in network byte order.
+ * in any currency.
*
* @param name name of the amount field in the JSON
* @param[out] r_amount where the amount has to be written
+ * @return spec for parsing an amount
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_amount_any (const char *name,
+ struct TALER_Amount *r_amount);
+
+
+/**
+ * Provide specification to parse given JSON object to an encrypted contract.
+ *
+ * @param name name of the amount field in the JSON
+ * @param[out] econtract where to store the encrypted contract
+ * @return spec for parsing an amount
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_econtract (const char *name,
+ struct TALER_EncryptedContract *econtract);
+
+
+/**
+ * Provide specification to parse a given JSON object to an age commitment.
+ *
+ * @param name name of the age commitment field in the JSON
+ * @param[out] age_commitment where to store the age commitment
+ * @return spec for parsing an age commitment
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_age_commitment (const char *name,
+ struct TALER_AgeCommitment *age_commitment);
+
+
+/**
+ * Provide specification to parse an OTP key.
+ * An OTP key must be an RFC 3548 base32-encoded
+ * value (so NOT our usual Crockford-base32 encoding!).
+ *
+ * @param name name of the OTP key field in the JSON
+ * @param[out] otp_key where to store the OTP key
+ * @return spec for parsing an age commitment
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_otp_key (const char *name,
+ const char **otp_key);
+
+
+/**
+ * Provide specification to parse an OTP method type.
+ * The value could be provided as an integer or
+ * as a descriptive string.
+ *
+ * @param name name of the OTP method type in the JSON
+ * @param[out] mca where to store the method type
+ * @return spec for parsing an age commitment
*/
struct GNUNET_JSON_Specification
-TALER_JSON_spec_amount_nbo (const char *name,
- struct TALER_AmountNBO *r_amount);
+TALER_JSON_spec_otp_type (const char *name,
+ enum TALER_MerchantConfirmationAlgorithm *mca);
+
+
+/**
+ * Generate specification to parse all fees for
+ * a denomination under a prefix @a pfx.
+ *
+ * @param pfx string prefix to use
+ * @param currency which currency to expect
+ * @param[out] dfs a `struct TALER_DenomFeeSet` to initialize
+ */
+#define TALER_JSON_SPEC_DENOM_FEES(pfx,currency,dfs) \
+ TALER_JSON_spec_amount (pfx "_withdraw", (currency), &(dfs)->withdraw), \
+ TALER_JSON_spec_amount (pfx "_deposit", (currency), &(dfs)->deposit), \
+ TALER_JSON_spec_amount (pfx "_refresh", (currency), &(dfs)->refresh), \
+ TALER_JSON_spec_amount (pfx "_refund", (currency), &(dfs)->refund)
+
+
+/**
+ * Macro to pack all of a denominations' fees under
+ * a given @a pfx.
+ *
+ * @param pfx string prefix to use
+ * @param dfs a `struct TALER_DenomFeeSet` to pack
+ */
+#define TALER_JSON_PACK_DENOM_FEES(pfx, dfs) \
+ TALER_JSON_pack_amount (pfx "_withdraw", &(dfs)->withdraw), \
+ TALER_JSON_pack_amount (pfx "_deposit", &(dfs)->deposit), \
+ TALER_JSON_pack_amount (pfx "_refresh", &(dfs)->refresh), \
+ TALER_JSON_pack_amount (pfx "_refund", &(dfs)->refund)
+
+/**
+ * Generate specification to parse all global fees.
+ *
+ * @param currency which currency to expect
+ * @param[out] gfs a `struct TALER_GlobalFeeSet` to initialize
+ */
+#define TALER_JSON_SPEC_GLOBAL_FEES(currency,gfs) \
+ TALER_JSON_spec_amount ("history_fee", (currency), &(gfs)->history), \
+ TALER_JSON_spec_amount ("account_fee", (currency), &(gfs)->account), \
+ TALER_JSON_spec_amount ("purse_fee", (currency), &(gfs)->purse)
+
+/**
+ * Macro to pack all of the global fees.
+ *
+ * @param gfs a `struct TALER_GlobalFeeSet` to pack
+ */
+#define TALER_JSON_PACK_GLOBAL_FEES(gfs) \
+ TALER_JSON_pack_amount ("history_fee", &(gfs)->history), \
+ TALER_JSON_pack_amount ("account_fee", &(gfs)->account), \
+ TALER_JSON_pack_amount ("purse_fee", &(gfs)->purse)
+
+
+/**
+ * Generate a parser for a group of denominations.
+ *
+ * @param[in] field name of the field, maybe NULL
+ * @param[in] currency name of the currency
+ * @param[out] group denomination group information
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_denomination_group (const char *field,
+ const char *currency,
+ struct TALER_DenominationGroup *group);
/**
* Generate line in parser specification for denomination public key.
@@ -88,20 +385,206 @@ TALER_JSON_spec_amount_nbo (const char *name,
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
-TALER_JSON_spec_denomination_public_key (const char *field,
- struct TALER_DenominationPublicKey *pk);
+TALER_JSON_spec_denom_pub (const char *field,
+ struct TALER_DenominationPublicKey *pk);
+
+
+/**
+ * Generate line in parser specification for error codes.
+ *
+ * @param field name of the field
+ * @param[out] ec error code to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_ec (const char *field,
+ enum TALER_ErrorCode *ec);
+
+
+/**
+ * Generate line in parser specification for
+ * HTTP/HTTPS URLs.
+ *
+ * @param field name of the field
+ * @param[out] url web URL to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_web_url (const char *field,
+ const char **url);
+
+
+/**
+ * Generate line in parser specification for
+ * "payto://" URIs.
+ *
+ * @param field name of the field
+ * @param[out] payto_uri RFC 8905 URI to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_payto_uri (const char *field,
+ const char **payto_uri);
+
+
+/**
+ * Generate line in parser specification for AML decision states.
+ *
+ * @param field name of the field
+ * @param[out] aml_state AML state to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_aml_decision (const char *field,
+ enum TALER_AmlDecisionState *aml_state);
+
+
+/**
+ * Representation of a protocol version.
+ */
+struct TALER_JSON_ProtocolVersion
+{
+ /**
+ * Current version of the protocol.
+ */
+ unsigned int current;
+
+ /**
+ * Implementation revision for the @e current
+ * version.
+ */
+ unsigned int revision;
+
+ /**
+ * Number of protocol versions this @e revision is
+ * backwards-compatible with. Subtract this number
+ * from @e current to get the minimum protocol version
+ * required from the client.
+ */
+ unsigned int age;
+};
+
+
+/**
+ * Generate line in parser specification for protocol
+ * versions (``/config``). The field must be a string
+ * encoding the version as "$CURRENT:$REVISION:$AGE".
+ *
+ * @param field name of the field (usually "version")
+ * @param[out] ver protocol versions to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_version (const char *field,
+ struct TALER_JSON_ProtocolVersion *ver);
+
+
+/**
+ * Generate a parser specification for a denomination public key of a given
+ * cipher.
+ *
+ * @param field name of the field
+ * @param cipher which cipher type to parse for
+ * @param[out] pk key to fill
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_denom_pub_cipher (
+ const char *field,
+ enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher,
+ struct TALER_DenominationPublicKey *pk);
/**
* Generate line in parser specification for denomination signature.
*
* @param field name of the field
- * @param sig the signature to initialize
+ * @param[out] sig the signature to initialize
* @return corresponding field spec
*/
struct GNUNET_JSON_Specification
-TALER_JSON_spec_denomination_signature (const char *field,
- struct TALER_DenominationSignature *sig);
+TALER_JSON_spec_denom_sig (const char *field,
+ struct TALER_DenominationSignature *sig);
+
+
+/**
+ * Generate line in parser specification for a
+ * blinded denomination signature.
+ *
+ * @param field name of the field
+ * @param[out] sig the blinded signature to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_blinded_denom_sig (
+ const char *field,
+ struct TALER_BlindedDenominationSignature *sig);
+
+
+/**
+ * Generate line in parser specification for
+ * exchange withdraw values (/csr).
+ *
+ * @param field name of the field
+ * @param[out] ewv the exchange withdraw values to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_exchange_withdraw_values (
+ const char *field,
+ struct TALER_ExchangeWithdrawValues *ewv);
+
+
+/**
+ * Generate line in parser specification for a
+ * blinded planchet.
+ *
+ * @param field name of the field
+ * @param[out] blinded_planchet the blinded planchet to initialize
+ * @return corresponding field spec
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_blinded_planchet (const char *field,
+ struct TALER_BlindedPlanchet *blinded_planchet);
+
+
+/**
+ * The expected field stores a possibly internationalized string.
+ * Internationalization means that there is another field "$name_i18n"
+ * which is an object where the keys are languages. If this is
+ * present, and if @a language_pattern is non-NULL, this function
+ * should return the best match from @a language pattern from the
+ * "_i18n" field. If no language matches, the normal field under
+ * @a name is to be returned.
+ *
+ * The @a language_pattern is given using the format from
+ * https://tools.ietf.org/html/rfc7231#section-5.3.1
+ * so that #TALER_language_matches() can be used.
+ *
+ * @param name name of the JSON field
+ * @param language_pattern language pattern to use to find best match, possibly NULL
+ * @param[out] strptr where to store a pointer to the field with the best variant
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_i18n_string (const char *name,
+ const char *language_pattern,
+ const char **strptr);
+
+
+/**
+ * The expected field stores a possibly internationalized string.
+ * Internationalization means that there is another field "$name_i18n" which
+ * is an object where the keys are languages. If this is present, this
+ * function should return the best match based on the locale from the "_i18n"
+ * field. If no language matches, the normal field under @a name is to be
+ * returned.
+ *
+ * @param name name of the JSON field
+ * @param[out] strptr where to store a pointer to the field with the best variant
+ */
+struct GNUNET_JSON_Specification
+TALER_JSON_spec_i18n_str (const char *name,
+ const char **strptr);
/**
@@ -115,11 +598,87 @@ TALER_JSON_spec_denomination_signature (const char *field,
*
* @param[in] json some JSON value to hash
* @param[out] hc resulting hash code
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if @a json was malformed
+ * #GNUNET_SYSERR on internal error
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_contract_hash (const json_t *json,
+ struct TALER_PrivateContractHashP *hc);
+
+
+/**
+ * Take a given @a contract with "forgettable" fields marked in the @a spec
+ * with 'True' instead of a real salt. Replaces all 'True' values with proper
+ * random salts in the actual @a contract. Fails if any forgettable markers
+ * are neither 'True' nor valid salts.
+ *
+ * @param spec specification with forgettable fields
+ * @param[in,out] contract JSON contract to transform
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_contract_seed_forgettable (const json_t *spec,
+ json_t *contract);
+
+
+/**
+ * Mark part of a contract object as 'forgettable'.
+ *
+ * @param[in,out] json some JSON object to modify
+ * @param field name of the field to mark as forgettable
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
-int
-TALER_JSON_hash (const json_t *json,
- struct GNUNET_HashCode *hc);
+enum GNUNET_GenericReturnValue
+TALER_JSON_contract_mark_forgettable (json_t *json,
+ const char *field);
+
+
+/**
+ * Forget part of a contract object.
+ *
+ * @param[in,out] json some JSON object to modify
+ * @param field name of the field to forget
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if the field was already forgotten before
+ * #GNUNET_SYSERR on error
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_contract_part_forget (json_t *json,
+ const char *field);
+
+
+/**
+ * Called for each path found after expanding a path.
+ *
+ * @param cls the closure.
+ * @param object_id the name of the object that is pointed to.
+ * @param parent the parent of the object at @e object_id.
+ */
+typedef void
+(*TALER_JSON_ExpandPathCallback) (
+ void *cls,
+ const char *object_id,
+ json_t *parent);
+
+
+/**
+ * Expands a path for a json object. May call the callback several times
+ * if the path contains a wildcard.
+ *
+ * @param json the json object the path references.
+ * @param path the path to expand. Must begin with "$." and follow dot notation,
+ * and may include array indices and wildcards.
+ * @param cb the callback.
+ * @param cb_cls closure for the callback.
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if @e path is invalid.
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_expand_path (json_t *json,
+ const char *path,
+ TALER_JSON_ExpandPathCallback cb,
+ void *cb_cls);
+
/**
* Extract the Taler error code from the given @a json object.
@@ -167,36 +726,50 @@ TALER_JSON_get_error_code2 (const void *data,
* @param[out] hc set to the hash
* @return #GNUNET_OK on success, #GNUNET_SYSERR if @a wire_s is malformed
*/
-int
+enum GNUNET_GenericReturnValue
TALER_JSON_merchant_wire_signature_hash (const json_t *wire_s,
- struct GNUNET_HashCode *hc);
+ struct TALER_MerchantWireHashP *hc);
/**
- * Check the signature in @a wire_s. Also performs rudimentary
- * checks on the account data *if* supported.
+ * Extract a string from @a object under the field @a field, but respecting
+ * the Taler i18n rules and the language preferences expressed in @a
+ * language_pattern.
*
- * @param wire_s signed wire information of an exchange
- * @param master_pub master public key of the exchange
- * @return #GNUNET_OK if signature is valid
+ * Basically, the @a object may optionally contain a sub-object
+ * "${field}_i18n" with a map from IETF BCP 47 language tags to a localized
+ * version of the string. If this map exists and contains an entry that
+ * matches the @a language pattern, that object (usually a string) is
+ * returned. If the @a language_pattern does not match any entry, or if the
+ * i18n sub-object does not exist, we simply return @a field of @a object
+ * (also usually a string).
+ *
+ * If @a object does not have a member @a field we return NULL (error).
+ *
+ * @param object the object to extract internationalized
+ * content from
+ * @param language_pattern a language preferences string
+ * like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1", following
+ * https://tools.ietf.org/html/rfc7231#section-5.3.1
+ * @param field name of the field to extract
+ * @return NULL on error, otherwise the member from
+ * @a object. Note that the reference counter is
+ * NOT incremented.
*/
-int
-TALER_JSON_exchange_wire_signature_check (
- const json_t *wire_s,
- const struct TALER_MasterPublicKeyP *master_pub);
+const json_t *
+TALER_JSON_extract_i18n (const json_t *object,
+ const char *language_pattern,
+ const char *field);
/**
- * Create a signed wire statement for the given account.
+ * Check whether a given @a i18n object is wellformed.
*
- * @param payto_uri account specification
- * @param master_priv private key to sign with
- * @return NULL if @a payto_uri is malformed
+ * @param i18n object with internationalized content
+ * @return true if @a i18n is well-formed
*/
-json_t *
-TALER_JSON_exchange_wire_signature_make (
- const char *payto_uri,
- const struct TALER_MasterPrivateKeyP *master_priv);
+bool
+TALER_JSON_check_i18n (const json_t *i18n);
/**
@@ -221,6 +794,33 @@ char *
TALER_JSON_wire_to_payto (const json_t *wire_s);
+/**
+ * Hash @a policy extensions in deposits.
+ *
+ * @param policy contract policy extension to hash
+ * @param[out] ech where to write the policy hash
+ */
+void
+TALER_deposit_policy_hash (const json_t *policy,
+ struct TALER_ExtensionPolicyHashP *ech);
+
+/**
+ * Hash the @a manifests of extensions, given as JSON
+ *
+ * @param manifests Manifests of the extensions
+ * @param[out] eh where to write the hash
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_extensions_manifests_hash (const json_t *manifests,
+ struct TALER_ExtensionManifestsHashP *eh);
+
+/**
+ * Canonicalize a JSON input to a string according to RFC 8785.
+ */
+char *
+TALER_JSON_canonicalize (const json_t *input);
+
#endif /* TALER_JSON_LIB_H_ */
/* End of taler_json_lib.h */
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
new file mode 100644
index 000000000..4d0c18fa4
--- /dev/null
+++ b/src/include/taler_kyclogic_lib.h
@@ -0,0 +1,374 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler_kyclogic_lib.h
+ * @brief server-side KYC API
+ * @author Christian Grothoff
+ */
+#ifndef TALER_KYCLOGIC_LIB_H
+#define TALER_KYCLOGIC_LIB_H
+
+#include <microhttpd.h>
+#include "taler_exchangedb_plugin.h"
+#include "taler_kyclogic_plugin.h"
+
+
+/**
+ * Enumeration for our KYC user types.
+ */
+enum TALER_KYCLOGIC_KycUserType
+{
+ /**
+ * KYC rule is for an individual.
+ */
+ TALER_KYCLOGIC_KYC_UT_INDIVIDUAL = 0,
+
+ /**
+ * KYC rule is for a business.
+ */
+ TALER_KYCLOGIC_KYC_UT_BUSINESS = 1
+};
+
+
+/**
+ * Enumeration of possible events that may trigger
+ * KYC requirements.
+ */
+enum TALER_KYCLOGIC_KycTriggerEvent
+{
+
+ /**
+ * Customer withdraws coins.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW = 0,
+
+ /**
+ * Merchant deposits coins.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT = 1,
+
+ /**
+ * Wallet receives P2P payment.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 2,
+
+ /**
+ * Wallet balance exceeds threshold.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 3,
+
+ /**
+ * Reserve is being closed by force.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE = 4,
+
+ /**
+ * Customer withdraws coins via age-withdraw.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_AGE_WITHDRAW = 5,
+};
+
+
+/**
+ * Parse KYC trigger string value from a string
+ * into enumeration value.
+ *
+ * @param trigger_s string to parse
+ * @param[out] trigger set to the value found
+ * @return #GNUNET_OK on success, #GNUNET_NO if option
+ * does not exist, #GNUNET_SYSERR if option is
+ * malformed
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_kyc_trigger_from_string (
+ const char *trigger_s,
+ enum TALER_KYCLOGIC_KycTriggerEvent *trigger);
+
+
+/**
+ * Convert KYC trigger value to human-readable string.
+ *
+ * @param trigger value to convert
+ * @return human-readable representation of the @a trigger
+ */
+const char *
+TALER_KYCLOGIC_kyc_trigger2s (enum TALER_KYCLOGIC_KycTriggerEvent trigger);
+
+
+/**
+ * Parse user type string into enumeration value.
+ *
+ * @param ut_s string to parse
+ * @param[out] ut set to the value found
+ * @return #GNUNET_OK on success, #GNUNET_NO if option
+ * does not exist, #GNUNET_SYSERR if option is
+ * malformed
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_kyc_user_type_from_string (const char *ut_s,
+ enum TALER_KYCLOGIC_KycUserType *ut);
+
+
+/**
+ * Convert KYC user type to human-readable string.
+ *
+ * @param ut value to convert
+ * @return human-readable representation of the @a ut
+ */
+const char *
+TALER_KYCLOGIC_kyc_user_type2s (enum TALER_KYCLOGIC_KycUserType ut);
+
+
+/**
+ * Initialize KYC subsystem. Loads the KYC configuration.
+ *
+ * @param cfg configuration to parse
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_kyc_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+/**
+ * Shut down the KYC subsystem.
+ */
+void
+TALER_KYCLOGIC_kyc_done (void);
+
+
+/**
+ * Function called to iterate over KYC-relevant
+ * transaction amounts for a particular time range.
+ * Called within a database transaction, so must
+ * not start a new one.
+ *
+ * @param cls closure, identifies the event type and
+ * account to iterate over events for
+ * @param limit maximum time-range for which events
+ * should be fetched (timestamp in the past)
+ * @param cb function to call on each event found,
+ * events must be returned in reverse chronological
+ * order
+ * @param cb_cls closure for @a cb
+ */
+typedef void
+(*TALER_KYCLOGIC_KycAmountIterator)(void *cls,
+ struct GNUNET_TIME_Absolute limit,
+ TALER_EXCHANGEDB_KycAmountCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Function called to iterate over KYC-relevant
+ * transaction thresholds amounts.
+ *
+ * @param cls closure, identifies the event type and
+ * account to iterate over events for
+ * @param threshold a relevant threshold amount
+ */
+typedef void
+(*TALER_KYCLOGIC_KycThresholdIterator)(void *cls,
+ const struct TALER_Amount *threshold);
+
+
+/**
+ * Call us on KYC processes satisfied for the given
+ * account. Must match the ``select_satisfied_kyc_processes`` of the exchange database plugin.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param h_payto account identifier
+ * @param spc function to call for each satisfied KYC process
+ * @param spc_cls closure for @a spc
+ * @return transaction status code
+ */
+typedef enum GNUNET_DB_QueryStatus
+(*TALER_KYCLOGIC_KycSatisfiedIterator)(
+ void *cls,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_EXCHANGEDB_SatisfiedProviderCallback spc,
+ void *spc_cls);
+
+
+/**
+ * Check if KYC is provided for a particular operation. Returns the set of checks that still need to be satisfied.
+ *
+ * Called within a database transaction, so must
+ * not start a new one.
+ *
+ * @param event what type of operation is triggering the
+ * test if KYC is required
+ * @param h_payto account the event is about
+ * @param ki callback that returns list of already
+ * satisfied KYC checks, implemented by ``select_satisfied_kyc_processes`` of the exchangedb
+ * @param ki_cls closure for @a ki
+ * @param ai callback offered to inquire about historic
+ * amounts involved in this type of operation
+ * at the given account
+ * @param ai_cls closure for @a ai
+ * @param[out] required set to NULL if no check is needed,
+ * otherwise space-separated list of required checks
+ * @return transaction status
+ */
+enum GNUNET_DB_QueryStatus
+TALER_KYCLOGIC_kyc_test_required (enum TALER_KYCLOGIC_KycTriggerEvent event,
+ const struct TALER_PaytoHashP *h_payto,
+ TALER_KYCLOGIC_KycSatisfiedIterator ki,
+ void *ki_cls,
+ TALER_KYCLOGIC_KycAmountIterator ai,
+ void *ai_cls,
+ char **required);
+
+
+/**
+ * Check if the @a requirements are now satsified for
+ * @a h_payto account.
+ *
+ * @param[in,out] requirements space-spearated list of requirements,
+ * already satisfied requirements are removed from the list
+ * @param h_payto hash over the account
+ * @param[out] kyc_details if satisfied, set to what kind of
+ * KYC information was collected
+ * @param ki iterator over satisfied providers
+ * @param ki_cls closure for @a ki
+ * @param[out] satisfied set to true if the KYC check was satisfied
+ * @return transaction status (from @a ki)
+ */
+enum GNUNET_DB_QueryStatus
+TALER_KYCLOGIC_check_satisfied (char **requirements,
+ const struct TALER_PaytoHashP *h_payto,
+ json_t **kyc_details,
+ TALER_KYCLOGIC_KycSatisfiedIterator ki,
+ void *ki_cls,
+ bool *satisfied);
+
+
+/**
+ * Iterate over all thresholds that are applicable
+ * to a particular type of @a event
+ *
+ * @param event thresholds to look up
+ * @param it function to call on each
+ * @param it_cls closure for @a it
+ */
+void
+TALER_KYCLOGIC_kyc_iterate_thresholds (
+ enum TALER_KYCLOGIC_KycTriggerEvent event,
+ TALER_KYCLOGIC_KycThresholdIterator it,
+ void *it_cls);
+
+
+/**
+ * Function called with the provider details and
+ * associated plugin closures for matching logics.
+ *
+ * @param cls closure
+ * @param pd provider details of a matching logic
+ * @param plugin_cls closure of the plugin
+ * @return #GNUNET_OK to continue to iterate
+ */
+typedef enum GNUNET_GenericReturnValue
+(*TALER_KYCLOGIC_DetailsCallback)(
+ void *cls,
+ const struct TALER_KYCLOGIC_ProviderDetails *pd,
+ void *plugin_cls);
+
+
+/**
+ * Call @a cb for all logics with name @a logic_name,
+ * providing the plugin closure and the @a pd configurations.
+ *
+ * @param logic_name name of the logic to match
+ * @param cb function to call on matching results
+ * @param cb_cls closure for @a cb
+ */
+void
+TALER_KYCLOGIC_kyc_get_details (
+ const char *logic_name,
+ TALER_KYCLOGIC_DetailsCallback cb,
+ void *cb_cls);
+
+
+/**
+ * Check if a given @a check_name is a legal name (properly
+ * configured) and can be satisfied in principle.
+ *
+ * @param check_name name of the check to see if it is configured
+ * @return #GNUNET_OK if the check can be satisfied,
+ * #GNUNET_NO if the check can never be satisfied,
+ * #GNUNET_SYSERR if the type of the check is unknown
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_check_satisfiable (
+ const char *check_name);
+
+
+/**
+ * Return list of all KYC checks that are possible.
+ *
+ * @return JSON array of strings with the allowed KYC checks
+ */
+json_t *
+TALER_KYCLOGIC_get_satisfiable (void);
+
+
+/**
+ * Obtain the provider logic for a given set of @a requirements.
+ *
+ * @param requirements space-separated list of required checks
+ * @param ut type of the entity performing the check
+ * @param[out] plugin set to the KYC logic API
+ * @param[out] pd set to the specific operation context
+ * @param[out] configuration_section set to the name of the KYC logic configuration section * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_requirements_to_logic (const char *requirements,
+ enum TALER_KYCLOGIC_KycUserType ut,
+ struct TALER_KYCLOGIC_Plugin **plugin,
+ struct TALER_KYCLOGIC_ProviderDetails **pd,
+ const char **configuration_section);
+
+
+/**
+ * Obtain the provider logic for a given @a name.
+ *
+ * @param name name of the logic or provider section
+ * @param[out] plugin set to the KYC logic API
+ * @param[out] pd set to the specific operation context
+ * @param[out] configuration_section set to the name of the KYC logic configuration section
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_KYCLOGIC_lookup_logic (const char *name,
+ struct TALER_KYCLOGIC_Plugin **plugin,
+ struct TALER_KYCLOGIC_ProviderDetails **pd,
+ const char **configuration_section);
+
+
+/**
+ * Obtain array of KYC checks provided by the provider
+ * configured in @a section_name.
+ *
+ * @param section_name configuration section name
+ * @param[out] num_checks set to the length of the array
+ * @param[out] provided_checks set to an array with the
+ * names of the checks provided by this KYC provider
+ */
+void
+TALER_KYCLOGIC_lookup_checks (const char *section_name,
+ unsigned int *num_checks,
+ char ***provided_checks);
+
+#endif
diff --git a/src/include/taler_kyclogic_plugin.h b/src/include/taler_kyclogic_plugin.h
new file mode 100644
index 000000000..a9a4dd97a
--- /dev/null
+++ b/src/include/taler_kyclogic_plugin.h
@@ -0,0 +1,384 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file include/taler_kyclogic_plugin.h
+ * @brief KYC API specific logic C interface
+ * @author Christian Grothoff
+ */
+#ifndef TALER_KYCLOGIC_PLUGIN_H
+#define TALER_KYCLOGIC_PLUGIN_H
+
+#include <jansson.h>
+#include <gnunet/gnunet_util_lib.h>
+#include <gnunet/gnunet_db_lib.h>
+#include "taler_util.h"
+
+
+/**
+ * Possible states of a KYC check.
+ */
+enum TALER_KYCLOGIC_KycStatus
+{
+
+ /**
+ * The provider has passed the customer.
+ */
+ TALER_KYCLOGIC_STATUS_SUCCESS = 0,
+
+ /**
+ * Something to do with the user (bit!).
+ */
+ TALER_KYCLOGIC_STATUS_USER = 1,
+
+ /**
+ * Something to do with the provider (bit!).
+ */
+ TALER_KYCLOGIC_STATUS_PROVIDER = 2,
+
+ /**
+ * The interaction ended in definitive failure.
+ * (kind of with both parties).
+ */
+ TALER_KYCLOGIC_STATUS_FAILED
+ = TALER_KYCLOGIC_STATUS_USER
+ | TALER_KYCLOGIC_STATUS_PROVIDER,
+
+ /**
+ * The interaction is still ongoing.
+ */
+ TALER_KYCLOGIC_STATUS_PENDING = 4,
+
+ /**
+ * One of the parties hat a temporary failure.
+ */
+ TALER_KYCLOGIC_STATUS_ABORTED = 8,
+
+ /**
+ * The interaction with the user is ongoing.
+ */
+ TALER_KYCLOGIC_STATUS_USER_PENDING
+ = TALER_KYCLOGIC_STATUS_USER
+ | TALER_KYCLOGIC_STATUS_PENDING,
+
+ /**
+ * The provider is still checking.
+ */
+ TALER_KYCLOGIC_STATUS_PROVIDER_PENDING
+ = TALER_KYCLOGIC_STATUS_PROVIDER
+ | TALER_KYCLOGIC_STATUS_PENDING,
+
+ /**
+ * The user aborted the check (possibly recoverable)
+ * or made some other type of (recoverable) mistake.
+ */
+ TALER_KYCLOGIC_STATUS_USER_ABORTED
+ = TALER_KYCLOGIC_STATUS_USER
+ | TALER_KYCLOGIC_STATUS_ABORTED,
+
+ /**
+ * The provider had an (internal) failure.
+ */
+ TALER_KYCLOGIC_STATUS_PROVIDER_FAILED
+ = TALER_KYCLOGIC_STATUS_PROVIDER
+ | TALER_KYCLOGIC_STATUS_ABORTED,
+
+ /**
+ * Return code set to not update the KYC status
+ * at all.
+ */
+ TALER_KYCLOGIC_STATUS_KEEP = 16,
+
+ /**
+ * We had an internal logic failure.
+ */
+ TALER_KYCLOGIC_STATUS_INTERNAL_ERROR = 32
+
+};
+
+
+/**
+ * Plugin-internal specification of the configuration
+ * of the plugin for a given KYC provider.
+ */
+struct TALER_KYCLOGIC_ProviderDetails;
+
+/**
+ * Handle for an initiation operation.
+ */
+struct TALER_KYCLOGIC_InitiateHandle;
+
+/**
+ * Handle for an KYC proof operation.
+ */
+struct TALER_KYCLOGIC_ProofHandle;
+
+/**
+ * Handle for an KYC Web hook operation.
+ */
+struct TALER_KYCLOGIC_WebhookHandle;
+
+
+/**
+ * Function called with the result of a KYC initiation
+ * operation.
+ *
+ * @param cls closure
+ * @param ec #TALER_EC_NONE on success
+ * @param redirect_url set to where to redirect the user on success, NULL on failure
+ * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
+ * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown
+ * @param error_msg_hint set to additional details to return to user, NULL on success
+ */
+typedef void
+(*TALER_KYCLOGIC_InitiateCallback)(
+ void *cls,
+ enum TALER_ErrorCode ec,
+ const char *redirect_url,
+ const char *provider_user_id,
+ const char *provider_legitimization_id,
+ const char *error_msg_hint);
+
+
+/**
+ * Function called with the result of a proof check operation.
+ *
+ * Note that the "decref" for the @a response
+ * will be done by the callee and MUST NOT be done by the plugin.
+ *
+ * @param cls closure
+ * @param status KYC status
+ * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
+ * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown
+ * @param attributes user attributes returned by the provider
+ * @param expiration until when is the KYC check valid
+ * @param http_status HTTP status code of @a response
+ * @param[in] response to return to the HTTP client
+ */
+typedef void
+(*TALER_KYCLOGIC_ProofCallback)(
+ void *cls,
+ enum TALER_KYCLOGIC_KycStatus status,
+ const char *provider_user_id,
+ const char *provider_legitimization_id,
+ struct GNUNET_TIME_Absolute expiration,
+ const json_t *attributes,
+ unsigned int http_status,
+ struct MHD_Response *response);
+
+
+/**
+ * Function called with the result of a webhook operation.
+ *
+ * Note that the "decref" for the @a response will be done by the callee and
+ * MUST NOT be done by the plugin!
+ *
+ * @param cls closure
+ * @param process_row legitimization process the webhook was about
+ * @param account_id account the webhook was about
+ * @param provider_section name of the configuration section of the logic that was run
+ * @param provider_user_id set to user ID at the provider, or NULL if not supported or unknown
+ * @param provider_legitimization_id set to legitimization process ID at the provider, or NULL if not supported or unknown
+ * @param status KYC status
+ * @param expiration until when is the KYC check valid
+ * @param attributes user attributes returned by the provider
+ * @param http_status HTTP status code of @a response
+ * @param[in] response to return to the HTTP client
+ */
+typedef void
+(*TALER_KYCLOGIC_WebhookCallback)(
+ void *cls,
+ uint64_t process_row,
+ const struct TALER_PaytoHashP *account_id,
+ const char *provider_section,
+ const char *provider_user_id,
+ const char *provider_legitimization_id,
+ enum TALER_KYCLOGIC_KycStatus status,
+ struct GNUNET_TIME_Absolute expiration,
+ const json_t *attributes,
+ unsigned int http_status,
+ struct MHD_Response *response);
+
+
+/**
+ * Function the plugin can use to lookup an @a h_payto by @a
+ * provider_legitimization_id. Must match the `kyc_provider_account_lookup`
+ * of the exchange's database plugin.
+ *
+ * @param cls closure
+ * @param provider_section
+ * @param provider_legitimization_id legi to look up
+ * @param[out] h_payto where to write the result
+ * @param[out] process_row where to write the row of the entry
+ * @return database transaction status
+ */
+typedef enum GNUNET_DB_QueryStatus
+(*TALER_KYCLOGIC_ProviderLookupCallback)(
+ void *cls,
+ const char *provider_section,
+ const char *provider_legitimization_id,
+ struct TALER_PaytoHashP *h_payto,
+ uint64_t *process_row);
+
+
+/**
+ * @brief The plugin API, returned from the plugin's "init" function.
+ * The argument given to "init" is simply a configuration handle.
+ */
+struct TALER_KYCLOGIC_Plugin
+{
+
+ /**
+ * Closure for all callbacks.
+ */
+ void *cls;
+
+ /**
+ * Name of the library which generated this plugin. Set by the
+ * plugin loader.
+ */
+ char *library_name;
+
+ /**
+ * Name of the logic, for webhook matching. Set by the
+ * plugin loader.
+ */
+ char *name;
+
+ /**
+ * Load the configuration of the KYC provider.
+ *
+ * @param cls closure
+ * @param provider_section_name configuration section to parse
+ * @return NULL if configuration is invalid
+ */
+ struct TALER_KYCLOGIC_ProviderDetails *
+ (*load_configuration)(void *cls,
+ const char *provider_section_name);
+
+ /**
+ * Release configuration resources previously loaded
+ *
+ * @param[in] pd configuration to release
+ */
+ void
+ (*unload_configuration)(struct TALER_KYCLOGIC_ProviderDetails *pd);
+
+
+ /**
+ * Initiate KYC check.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param pd provider configuration details
+ * @param account_id which account to trigger process for
+ * @param process_row unique ID for the legitimization process
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return handle to cancel operation early
+ */
+ struct TALER_KYCLOGIC_InitiateHandle *
+ (*initiate)(void *cls,
+ const struct TALER_KYCLOGIC_ProviderDetails *pd,
+ const struct TALER_PaytoHashP *account_id,
+ uint64_t process_row,
+ TALER_KYCLOGIC_InitiateCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Cancel KYC check initiation.
+ *
+ * @param[in] ih handle of operation to cancel
+ */
+ void
+ (*initiate_cancel) (struct TALER_KYCLOGIC_InitiateHandle *ih);
+
+
+ /**
+ * Check KYC status and return status to human.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param pd provider configuration details
+ * @param connection MHD connection object (for HTTP headers)
+ * @param account_id which account to trigger process for
+ * @param process_row row in the legitimization processes table the legitimization is for
+ * @param provider_user_id user ID (or NULL) the proof is for
+ * @param provider_legitimization_id legitimization ID the proof is for
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return handle to cancel operation early
+ */
+ struct TALER_KYCLOGIC_ProofHandle *
+ (*proof)(void *cls,
+ const struct TALER_KYCLOGIC_ProviderDetails *pd,
+ struct MHD_Connection *connection,
+ const struct TALER_PaytoHashP *account_id,
+ uint64_t process_row,
+ const char *provider_user_id,
+ const char *provider_legitimization_id,
+ TALER_KYCLOGIC_ProofCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Cancel KYC proof.
+ *
+ * @param[in] ph handle of operation to cancel
+ */
+ void
+ (*proof_cancel) (struct TALER_KYCLOGIC_ProofHandle *ph);
+
+
+ /**
+ * Check KYC status and return result for Webhook.
+ *
+ * @param cls the @e cls of this struct with the plugin-specific state
+ * @param pd provider configuration details
+ * @param plc callback to lookup accounts with
+ * @param plc_cls closure for @a plc
+ * @param http_method HTTP method used for the webhook
+ * @param url_path rest of the URL after `/kyc-webhook/$LOGIC/`
+ * @param connection MHD connection object (for HTTP headers)
+ * @param body_size number of bytes in @a body
+ * @param body HTTP request body
+ * @param cb function to call with the result
+ * @param cb_cls closure for @a cb
+ * @return handle to cancel operation early
+ */
+ struct TALER_KYCLOGIC_WebhookHandle *
+ (*webhook)(void *cls,
+ const struct TALER_KYCLOGIC_ProviderDetails *pd,
+ TALER_KYCLOGIC_ProviderLookupCallback plc,
+ void *plc_cls,
+ const char *http_method,
+ const char *const url_path[],
+ struct MHD_Connection *connection,
+ const json_t *upload,
+ TALER_KYCLOGIC_WebhookCallback cb,
+ void *cb_cls);
+
+
+ /**
+ * Cancel KYC webhook execution.
+ *
+ * @param[in] wh handle of operation to cancel
+ */
+ void
+ (*webhook_cancel) (struct TALER_KYCLOGIC_WebhookHandle *wh);
+
+};
+
+
+#endif /* _TALER_KYCLOGIC_PLUGIN_H */
diff --git a/src/include/taler_mhd_lib.h b/src/include/taler_mhd_lib.h
index 71006e8bc..57d041758 100644
--- a/src/include/taler_mhd_lib.h
+++ b/src/include/taler_mhd_lib.h
@@ -27,10 +27,17 @@
#include <jansson.h>
#include <microhttpd.h>
#include "taler_error_codes.h"
+#include "taler_util.h"
#include <gnunet/gnunet_mhd_compat.h>
/**
+ * Maximum POST request size.
+ */
+#define TALER_MHD_REQUEST_BUFFER_MAX (1024 * 1024 * 16)
+
+
+/**
* Global options for response generation.
*/
enum TALER_MHD_GlobalOptions
@@ -97,6 +104,20 @@ TALER_MHD_can_compress (struct MHD_Connection *connection);
/**
+ * Check if @a mime matches the @a accept_pattern. For this function, the @a
+ * accept_pattern may include multiple values separated by ";".
+ *
+ * @param accept_pattern a mime pattern like "text/plain"
+ * or "image/STAR" or "text/plain; text/xml"
+ * @param mime the mime type to match
+ * @return true if @a mime matches the @a accept_pattern
+ */
+bool
+TALER_MHD_xmime_matches (const char *accept_pattern,
+ const char *mime);
+
+
+/**
* Send JSON object as response.
*
* @param connection the MHD connection
@@ -111,6 +132,21 @@ TALER_MHD_reply_json (struct MHD_Connection *connection,
/**
+ * Send JSON object as response, and free the @a json
+ * object.
+ *
+ * @param connection the MHD connection
+ * @param json the json object (freed!)
+ * @param response_code the http response code
+ * @return MHD result code
+ */
+MHD_RESULT
+TALER_MHD_reply_json_steal (struct MHD_Connection *connection,
+ json_t *json,
+ unsigned int response_code);
+
+
+/**
* Function to call to handle the request by building a JSON
* reply from a format string and varargs.
*
@@ -128,19 +164,60 @@ TALER_MHD_reply_json_pack (struct MHD_Connection *connection,
/**
+ * Function to call to handle the request by building a JSON
+ * reply from varargs.
+ *
+ * @param connection the MHD connection to handle
+ * @param response_code HTTP response code to use
+ * @param ... varargs of JSON pack specification
+ * @return MHD result code
+ */
+#define TALER_MHD_REPLY_JSON_PACK(connection,response_code,...) \
+ TALER_MHD_reply_json_steal (connection, GNUNET_JSON_PACK (__VA_ARGS__), \
+ response_code)
+
+
+/**
* Send a response indicating an error.
*
* @param connection the MHD connection to use
* @param ec error code uniquely identifying the error
* @param http_status HTTP status code to use
- * @param hint human readable hint about the error
+ * @param detail additional optional detail about the error
* @return a MHD result code
*/
MHD_RESULT
TALER_MHD_reply_with_error (struct MHD_Connection *connection,
unsigned int http_status,
enum TALER_ErrorCode ec,
- const char *hint);
+ const char *detail);
+
+
+/**
+ * Send a response indicating an error. The HTTP status code is
+ * to be derived from the @a ec.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
+ * @param detail additional optional detail about the error
+ * @return a MHD result code
+ */
+MHD_RESULT
+TALER_MHD_reply_with_ec (struct MHD_Connection *connection,
+ enum TALER_ErrorCode ec,
+ const char *detail);
+
+
+/**
+ * Produce HTTP "Date:" header.
+ *
+ * @param at time to write to @a date
+ * @param[out] date where to write the header, with
+ * at least 128 bytes available space.
+ */
+void
+TALER_MHD_get_date_string (struct GNUNET_TIME_Absolute at,
+ char date[128]);
/**
@@ -154,6 +231,16 @@ TALER_MHD_make_json (const json_t *json);
/**
+ * Make JSON response object and free @a json.
+ *
+ * @param json the json object, freed.
+ * @return MHD response object
+ */
+struct MHD_Response *
+TALER_MHD_make_json_steal (json_t *json);
+
+
+/**
* Make JSON response object.
*
* @param fmt format string for pack
@@ -166,15 +253,36 @@ TALER_MHD_make_json_pack (const char *fmt,
/**
+ * Make JSON response object.
+ *
+ * @param ... varargs
+ * @return MHD response object
+ */
+#define TALER_MHD_MAKE_JSON_PACK(...) \
+ TALER_MHD_make_json_steal (GNUNET_JSON_PACK (__VA_ARGS__))
+
+
+/**
+ * Pack Taler error code @a ec and associated hint into a
+ * JSON object.
+ *
+ * @param ec error code to pack
+ * @return packer array entries (two!)
+ */
+#define TALER_MHD_PACK_EC(ec) \
+ GNUNET_JSON_pack_uint64 ("code", ec), \
+ GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec))
+
+/**
* Create a response indicating an internal error.
*
* @param ec error code to return
- * @param hint hint about the internal error's nature
+ * @param detail additional optional detail about the error, can be NULL
* @return a MHD response object
*/
struct MHD_Response *
TALER_MHD_make_error (enum TALER_ErrorCode ec,
- const char *hint);
+ const char *detail);
/**
@@ -264,7 +372,8 @@ TALER_MHD_parse_post_cleanup_callback (void *con_cls);
/**
* Parse JSON object into components based on the given field
- * specification.
+ * specification. If parsing fails, we return an HTTP
+ * status code of 400 (#MHD_HTTP_BAD_REQUEST).
*
* @param connection the connection to send an error response to
* @param root the JSON node to start the navigation at.
@@ -283,6 +392,30 @@ TALER_MHD_parse_json_data (struct MHD_Connection *connection,
/**
+ * Parse JSON object that we (the server!) generated into components based on
+ * the given field specification. The difference to
+ * #TALER_MHD_parse_json_data() is that this function will fail
+ * with an HTTP failure of 500 (internal server error) in case
+ * parsing fails, instead of blaming it on the client with a
+ * 400 (#MHD_HTTP_BAD_REQUEST).
+ *
+ * @param connection the connection to send an error response to
+ * @param root the JSON node to start the navigation at.
+ * @param spec field specification for the parser
+ * @return
+ * #GNUNET_YES if navigation was successful (caller is responsible
+ * for freeing allocated variable-size data using
+ * GNUNET_JSON_parse_free() when done)
+ * #GNUNET_NO if json is malformed, error response was generated
+ * #GNUNET_SYSERR on internal error
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_internal_json_data (struct MHD_Connection *connection,
+ const json_t *root,
+ struct GNUNET_JSON_Specification *spec);
+
+
+/**
* Parse JSON array into components based on the given field
* specification. Generates error response on parse errors.
*
@@ -305,7 +438,201 @@ TALER_MHD_parse_json_array (struct MHD_Connection *connection,
/**
- * Extraxt fixed-size base32crockford encoded data from request.
+ * Extract optional "timeout_ms" argument from request.
+ *
+ * @param connection the MHD connection
+ * @param[out] expiration set to #GNUNET_TIME_UNIT_ZERO_ABS if there was no timeout,
+ * the current time plus the value given under "timeout_ms" otherwise
+ * @return #GNUNET_OK on success, #GNUNET_NO if an
+ * error was returned on @a connection (caller should return #MHD_YES) and
+ * #GNUNET_SYSERR if we failed to return an error (caller should return #MHD_NO)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_request_arg_timeout (struct MHD_Connection *connection,
+ struct GNUNET_TIME_Absolute *expiration);
+
+
+/**
+ * Extract optional "timeout_ms" argument from request.
+ * Macro that *returns* #MHD_YES/#MHD_NO if the "timeout_ms"
+ * argument existed but failed to parse.
+ *
+ * @param connection the MHD connection
+ * @param[out] expiration set to #GNUNET_TIME_UNIT_ZERO_ABS if there was no timeout,
+ * the current time plus the value given under "timeout_ms" otherwise
+ */
+#define TALER_MHD_parse_request_timeout(connection,expiration) \
+ do { \
+ switch (TALER_MHD_parse_request_arg_timeout (connection, \
+ expiration)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Extract optional numeric limit argument from request.
+ *
+ * @param connection the MHD connection
+ * @param name name of the query parameter
+ * @param[out] off set to the offset, unchanged if the
+ * option was not given
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if an error was returned on @a connection (caller should return #MHD_YES) and
+ * #GNUNET_SYSERR if we failed to return an error (caller should return #MHD_NO)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_request_arg_number (struct MHD_Connection *connection,
+ const char *name,
+ uint64_t *off);
+
+
+/**
+ * Extract optional numeric argument from request.
+ * Macro that *returns* #MHD_YES/#MHD_NO if the
+ * requested argument existed but failed to parse.
+ *
+ * @param connection the MHD connection
+ * @param name name of the argument to parse
+ * @param[out] off set to the given numeric value,
+ * unchanged if value was not specified
+ */
+#define TALER_MHD_parse_request_number(connection,name,off) \
+ do { \
+ switch (TALER_MHD_parse_request_arg_number (connection, \
+ name, \
+ off)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Extract optional signed numeric limit argument from request.
+ *
+ * @param connection the MHD connection
+ * @param name name of the query parameter
+ * @param[out] val set to the signed value, unchanged if the
+ * option was not given
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if an error was returned on @a connection (caller should return #MHD_YES) and
+ * #GNUNET_SYSERR if we failed to return an error (caller should return #MHD_NO)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_request_arg_snumber (struct MHD_Connection *connection,
+ const char *name,
+ int64_t *val);
+
+
+/**
+ * Extract optional numeric argument from request.
+ * Macro that *returns* #MHD_YES/#MHD_NO if the
+ * requested argument existed but failed to parse.
+ *
+ * @param connection the MHD connection
+ * @param name name of the argument to parse
+ * @param[out] val set to the given numeric value,
+ * unchanged if value was not specified
+ */
+#define TALER_MHD_parse_request_snumber(connection,name,val) \
+ do { \
+ switch (TALER_MHD_parse_request_arg_snumber (connection, \
+ name, \
+ val)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Extract optional amount argument from request.
+ *
+ * @param connection the MHD connection
+ * @param name name of the query parameter
+ * @param[out] val set to the amount, unchanged if the
+ * option was not given
+ * @return #GNUNET_OK on success,
+ * #GNUNET_NO if an error was returned on @a connection (caller should return #MHD_YES) and
+ * #GNUNET_SYSERR if we failed to return an error (caller should return #MHD_NO)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_request_arg_amount (struct MHD_Connection *connection,
+ const char *name,
+ struct TALER_Amount *val);
+
+
+/**
+ * Extract optional amount argument from request.
+ * Macro that *returns* #MHD_YES/#MHD_NO if the
+ * requested argument existed but failed to parse.
+ *
+ * @param connection the MHD connection
+ * @param name name of the argument to parse
+ * @param[out] val set to the given amount,
+ * unchanged if value was not specified
+ */
+#define TALER_MHD_parse_request_amount(connection,name,val) \
+ do { \
+ switch (TALER_MHD_parse_request_arg_amount (connection, \
+ name, \
+ val)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Determines which of the given choices is preferred
+ * by the client. Parses an HTTP header such as
+ * "Accept:" or "Language:" to find entries matching
+ * the list of strings given in the variadic argument
+ * list. Returns the index of the preferred choice.
+ *
+ * @param connection HTTP request handle
+ * @param header type of HTTP header to evaluate
+ * @param ... NULL-terminated list of choices to
+ * check for in the header
+ * @return -1 if none of the given choices is in
+ * the header, -2 if the header is missing,
+ * otherwise index of preferred choice in
+ * the varargs list
+ */
+int
+TALER_MHD_check_accept (struct MHD_Connection *connection,
+ const char *header,
+ ...);
+
+
+/**
+ * Extract fixed-size base32crockford encoded data from request argument.
*
* Queues an error response to the connection if the parameter is missing or
* invalid.
@@ -314,16 +641,195 @@ TALER_MHD_parse_json_array (struct MHD_Connection *connection,
* @param param_name the name of the parameter with the key
* @param[out] out_data pointer to store the result
* @param out_size expected size of @a out_data
+ * @param[out] present set to true if argument was found
* @return
* #GNUNET_YES if the the argument is present
- * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_NO if the argument is malformed
* #GNUNET_SYSERR on internal error (error response could not be sent)
*/
enum GNUNET_GenericReturnValue
TALER_MHD_parse_request_arg_data (struct MHD_Connection *connection,
const char *param_name,
void *out_data,
- size_t out_size);
+ size_t out_size,
+ bool *present);
+
+
+/**
+ * Extract fixed-size base32crockford encoded data from request header.
+ *
+ * Queues an error response to the connection if the parameter is missing or
+ * invalid.
+ *
+ * @param connection the MHD connection
+ * @param header_name the name of the HTTP header with the value
+ * @param[out] out_data pointer to store the result
+ * @param out_size expected size of @a out_data
+ * @param[out] present set to true if argument was found
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_parse_request_header_data (struct MHD_Connection *connection,
+ const char *header_name,
+ void *out_data,
+ size_t out_size,
+ bool *present);
+
+/**
+ * Extract fixed-size base32crockford encoded data from request.
+ *
+ * @param connection the MHD connection
+ * @param name the name of the parameter with the key
+ * @param[out] val pointer to store the result, type must determine size
+ * @param[in,out] required pass true to require presence of this argument; if 'false'
+ * set to true if the argument was found
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+#define TALER_MHD_parse_request_arg_auto(connection,name,val,required) \
+ do { \
+ bool p; \
+ switch (TALER_MHD_parse_request_arg_data (connection, name, \
+ val, sizeof (*val), &p)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ if (required & (! p)) \
+ return TALER_MHD_reply_with_error ( \
+ connection, \
+ MHD_HTTP_BAD_REQUEST, \
+ TALER_EC_GENERIC_PARAMETER_MISSING, \
+ name); \
+ required = p; \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Extract required fixed-size base32crockford encoded data from request.
+ *
+ * @param connection the MHD connection
+ * @param name the name of the parameter with the key
+ * @param[out] val pointer to store the result, type must determine size
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+#define TALER_MHD_parse_request_arg_auto_t(connection,name,val) \
+ do { \
+ bool b = true; \
+ TALER_MHD_parse_request_arg_auto (connection,name,val,b); \
+ } while (0)
+
+/**
+ * Extract fixed-size base32crockford encoded data from request.
+ *
+ * @param connection the MHD connection
+ * @param name the name of the header with the key
+ * @param[out] val pointer to store the result, type must determine size
+ * @param[in,out] required pass true to require presence of this argument; if 'false'
+ * set to true if the argument was found
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+#define TALER_MHD_parse_request_header_auto(connection,name,val,required) \
+ do { \
+ bool p; \
+ switch (TALER_MHD_parse_request_header_data (connection, name, \
+ val, sizeof (*val), &p)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ if (required & (! p)) \
+ return TALER_MHD_reply_with_error ( \
+ connection, \
+ MHD_HTTP_BAD_REQUEST, \
+ TALER_EC_GENERIC_PARAMETER_MISSING, \
+ name); \
+ required = p; \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Extract required fixed-size base32crockford encoded data from request.
+ *
+ * @param connection the MHD connection
+ * @param name the name of the header with the key
+ * @param[out] val pointer to store the result, type must determine size
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+#define TALER_MHD_parse_request_header_auto_t(connection,name,val) \
+ do { \
+ bool b = true; \
+ TALER_MHD_parse_request_header_auto (connection,name,val,b); \
+ } while (0)
+
+
+/**
+ * Check that the 'Content-Length' header is giving
+ * a length below @a max_len. If not, return an
+ * appropriate error response and return the
+ * correct #MHD_YES/#MHD_NO value from this function.
+ *
+ * @param connection the MHD connection
+ * @param max_len maximum allowed content length
+ * @return
+ * #GNUNET_YES if the the argument is present
+ * #GNUNET_NO if the argument is absent or malformed
+ * #GNUNET_SYSERR on internal error (error response could not be sent)
+ */
+enum GNUNET_GenericReturnValue
+TALER_MHD_check_content_length_ (struct MHD_Connection *connection,
+ unsigned long long max_len);
+
+
+/**
+ * Check that the 'Content-Length' header is giving
+ * a length below @a max_len. If not, return an
+ * appropriate error response and return the
+ * correct #MHD_YES/#MHD_NO value from this function.
+ *
+ * @param connection the MHD connection
+ * @param max_len maximum allowed content length
+ */
+#define TALER_MHD_check_content_length(connection,max_len) \
+ do { \
+ switch (TALER_MHD_check_content_length_ (connection, max_len)) \
+ { \
+ case GNUNET_SYSERR: \
+ GNUNET_break (0); \
+ return MHD_NO; \
+ case GNUNET_NO: \
+ GNUNET_break_op (0); \
+ return MHD_YES; \
+ case GNUNET_OK: \
+ break; \
+ } \
+ } while (0)
/**
@@ -390,6 +896,35 @@ TALER_MHD_bind (const struct GNUNET_CONFIGURATION_Handle *cfg,
/**
+ * Start to run an event loop for @a daemon.
+ * Only one daemon can be running per process
+ * using this API.
+ *
+ * @param daemon the MHD service to run
+ */
+void
+TALER_MHD_daemon_start (struct MHD_Daemon *daemon);
+
+
+/**
+ * Stop running the event loop for MHD.
+ *
+ * @return the daemon that we were previously running,
+ * or NULL if none was active
+ */
+struct MHD_Daemon *
+TALER_MHD_daemon_stop (void);
+
+
+/**
+ * Trigger MHD daemon that is running. Needed when
+ * a connection was resumed.
+ */
+void
+TALER_MHD_daemon_trigger (void);
+
+
+/**
* Prepared responses for legal documents
* (terms of service, privacy policy).
*/
@@ -398,7 +933,7 @@ struct TALER_MHD_Legal;
/**
* Load set of legal documents as specified in @a cfg in section @a section
- * where the Etag is given under the @param tagoption and the directory under
+ * where the Etag is given under the @a tagoption and the directory under
* the @a diroption.
*
* @param cfg configuration to use
diff --git a/src/include/taler_pq_lib.h b/src/include/taler_pq_lib.h
index 4545b6d5d..f45de61d9 100644
--- a/src/include/taler_pq_lib.h
+++ b/src/include/taler_pq_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016 Taler Systems SA
+ Copyright (C) 2014-2022 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -19,37 +19,112 @@
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
* @author Florian Dold
* @author Christian Grothoff
+ * @author Özgür Kesim
*/
#ifndef TALER_PQ_LIB_H_
#define TALER_PQ_LIB_H_
#include <libpq-fe.h>
#include <jansson.h>
+#include <gnunet/gnunet_common.h>
#include <gnunet/gnunet_pq_lib.h>
#include "taler_util.h"
/**
- * Generate query parameter for a currency, consisting of the three
- * components "value", "fraction" and "currency" in this order. The
- * types must be a 64-bit integer, 32-bit integer and a
- * #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
+ * API version. Bump on every change.
+ */
+#define TALER_PQ_VERSION 0x09040000
+
+/**
+ * Generate query parameter (as record tuple) for an amount, consisting
+ * of the two components "value" and "fraction" in this order. The
+ * types must be a 64-bit integer and a 32-bit integer
+ * respectively. The currency is dropped.
+ *
+ * @param db The database context for OID lookup
+ * @param amount pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_amount (
+ const struct GNUNET_PQ_Context *db,
+ const struct TALER_Amount *amount);
+
+
+/**
+ * Generate query parameter (as record tuple) for an amount, consisting of the
+ * three components "value", "fraction" and "currency" in this order. The
+ * types must be a 64-bit integer, a 32-bit integer and a TEXT field of 12
+ * characters respectively.
+ *
+ * @param db The database context for OID lookup
+ * @param amount pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_amount_with_currency (
+ const struct GNUNET_PQ_Context *db,
+ const struct TALER_Amount *amount);
+
+
+/**
+ * Generate query parameter for a denomination public
+ * key. Internally, the various attributes of the
+ * public key will be serialized into on variable-size
+ * BLOB.
+ *
+ * @param denom_pub pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_denom_pub (
+ const struct TALER_DenominationPublicKey *denom_pub);
+
+
+/**
+ * Generate query parameter for a denomination signature. Internally, the
+ * various attributes of the signature will be serialized into on
+ * variable-size BLOB.
+ *
+ * @param denom_sig pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_denom_sig (
+ const struct TALER_DenominationSignature *denom_sig);
+
+
+/**
+ * Generate query parameter for a blinded planchet.
+ * Internally, various attributes of the blinded
+ * planchet will be serialized into on
+ * variable-size BLOB.
+ *
+ * @param bp pointer to the query parameter to pass
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_blinded_planchet (
+ const struct TALER_BlindedPlanchet *bp);
+
+
+/**
+ * Generate query parameter for a blinded denomination signature. Internally,
+ * the various attributes of the signature will be serialized into on
+ * variable-size BLOB.
*
- * @param x pointer to the query parameter to pass
+ * @param denom_sig pointer to the query parameter to pass
*/
struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_amount_nbo (const struct TALER_AmountNBO *x);
+TALER_PQ_query_param_blinded_denom_sig (
+ const struct TALER_BlindedDenominationSignature *denom_sig);
/**
- * Generate query parameter for a currency, consisting of the three
- * components "value", "fraction" and "currency" in this order. The
- * types must be a 64-bit integer, 32-bit integer and a
- * #TALER_CURRENCY_LEN-sized BLOB/VARCHAR respectively.
+ * Generate query parameter for the exchange's contribution during a
+ * withdraw. Internally, the various attributes of the @a alg_values will be
+ * serialized into on variable-size BLOB.
*
- * @param x pointer to the query parameter to pass
+ * @param alg_values pointer to the query parameter to pass
*/
struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_amount (const struct TALER_Amount *x);
+TALER_PQ_query_param_exchange_withdraw_values (
+ const struct TALER_ExchangeWithdrawValues *alg_values);
/**
@@ -65,48 +140,115 @@ TALER_PQ_query_param_json (const json_t *x);
/**
- * Generate query parameter for an absolute time value.
- * In contrast to
- * #GNUNET_PQ_query_param_absolute_time(), this function
- * will abort (!) if the time given is not rounded!
- * The database must store a 64-bit integer.
+ * Generate query parameter for an array of blinded denomination signatures
+ *
+ * @param num number of elements in @e denom_sigs
+ * @param denom_sigs array of blinded denomination signatures
+ * @param db context for the db-connection
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_array_blinded_denom_sig (
+ size_t num,
+ const struct TALER_BlindedDenominationSignature *denom_sigs,
+ struct GNUNET_PQ_Context *db
+ );
+
+
+/**
+ * Generate query parameter for an array of blinded hashes of coin envelopes
+ *
+ * @param num number of elements in @e denom_sigs
+ * @param coin_evs array of blinded hashes of coin envelopes
+ * @param db context for the db-connection
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_array_blinded_coin_hash (
+ size_t num,
+ const struct TALER_BlindedCoinHashP *coin_evs,
+ struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Generate query parameter for an array of GNUNET_HashCode
+ *
+ * @param num number of elements in @e hash_codes
+ * @param hashes array of GNUNET_HashCode
+ * @param db context for the db-connection
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_array_hash_code (
+ size_t num,
+ const struct GNUNET_HashCode *hashes,
+ struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Generate query parameter for an array of amounts
+ *
+ * @param num of elements in @e amounts
+ * @param amounts continuous array of amounts
+ * @param db context for db-connection, needed for OID-lookup
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_array_amount (
+ size_t num,
+ const struct TALER_Amount *amounts,
+ struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Generate query parameter for an array of amounts
+ *
+ * @param num of elements in @e amounts
+ * @param amounts continuous array of amounts
+ * @param db context for db-connection, needed for OID-lookup
+ */
+struct GNUNET_PQ_QueryParam
+TALER_PQ_query_param_array_amount_with_currency (
+ size_t num,
+ const struct TALER_Amount *amounts,
+ struct GNUNET_PQ_Context *db);
+
+
+/**
+ * Generate query parameter for a blind sign public key of variable size.
*
- * @param x pointer to the query parameter to pass
+ * @param public_key pointer to the query parameter to pass
*/
struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
+TALER_PQ_query_param_blind_sign_pub (
+ const struct GNUNET_CRYPTO_BlindSignPublicKey *public_key);
/**
- * Generate query parameter for an absolute time value.
- * In contrast to
- * #GNUNET_PQ_query_param_absolute_time(), this function
- * will abort (!) if the time given is not rounded!
- * The database must store a 64-bit integer.
+ * Generate query parameter for a blind sign private key of variable size.
*
- * @param x pointer to the query parameter to pass
+ * @param private_key pointer to the query parameter to pass
*/
struct GNUNET_PQ_QueryParam
-TALER_PQ_query_param_absolute_time_nbo (const struct
- GNUNET_TIME_AbsoluteNBO *x);
+TALER_PQ_query_param_blind_sign_priv (
+ const struct GNUNET_CRYPTO_BlindSignPrivateKey *private_key);
/**
- * Currency amount expected.
+ * Currency amount expected, from a record-field of (DB)
+ * taler_amount_with_currency type. The currency must be stored in the
+ * database when using this function.
*
* @param name name of the field in the table
- * @param currency currency to use for @a amount
* @param[out] amount where to store the result
* @return array entry for the result specification to use
*/
struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_amount_nbo (const char *name,
- const char *currency,
- struct TALER_AmountNBO *amount);
+TALER_PQ_result_spec_amount_with_currency (
+ const char *name,
+ struct TALER_Amount *amount);
/**
- * Currency amount expected.
+ * Currency amount expected, from a record-field of (DB) taler_amount type.
+ * The currency is NOT stored in the database when using this function, but
+ * instead passed as the @a currency argument.
*
* @param name name of the field in the table
* @param currency currency to use for @a amount
@@ -120,6 +262,69 @@ TALER_PQ_result_spec_amount (const char *name,
/**
+ * Denomination public key expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] denom_pub where to store the public key
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_denom_pub (const char *name,
+ struct TALER_DenominationPublicKey *denom_pub);
+
+
+/**
+ * Denomination signature expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] denom_sig where to store the denomination signature
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_denom_sig (const char *name,
+ struct TALER_DenominationSignature *denom_sig);
+
+
+/**
+ * Blinded denomination signature expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] denom_sig where to store the denomination signature
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_blinded_denom_sig (
+ const char *name,
+ struct TALER_BlindedDenominationSignature *denom_sig);
+
+
+/**
+ * Exchange withdraw values expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] ewv where to store the exchange values
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_exchange_withdraw_values (
+ const char *name,
+ struct TALER_ExchangeWithdrawValues *ewv);
+
+
+/**
+ * Blinded planchet expected.
+ *
+ * @param name name of the field in the table
+ * @param[out] bp where to store the blinded planchet
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_blinded_planchet (
+ const char *name,
+ struct TALER_BlindedPlanchet *bp);
+
+
+/**
* json_t expected.
*
* @param name name of the field in the table
@@ -132,33 +337,89 @@ TALER_PQ_result_spec_json (const char *name,
/**
- * Rounded absolute time expected.
- * In contrast to #GNUNET_PQ_query_param_absolute_time_nbo(),
- * this function ensures that the result is rounded and can
- * be converted to JSON.
+ * Array of blinded denomination signature expected
+ *
+ * @param db context of the database connection
+ * @param name name of the field in the table
+ * @param[out] num number of elements in @e denom_sigs
+ * @param[out] denom_sigs where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_array_blinded_denom_sig (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ size_t *num,
+ struct TALER_BlindedDenominationSignature **denom_sigs);
+
+
+/**
+ * Array of blinded hashes of coin envelopes
*
+ * @param db context of the database connection
* @param name name of the field in the table
- * @param[out] at where to store the result
+ * @param[out] num number of elements in @e denom_sigs
+ * @param[out] h_coin_evs where to store the result
* @return array entry for the result specification to use
*/
struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_absolute_time (const char *name,
- struct GNUNET_TIME_Absolute *at);
+TALER_PQ_result_spec_array_blinded_coin_hash (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ size_t *num,
+ struct TALER_BlindedCoinHashP **h_coin_evs);
/**
- * Rounded absolute time expected.
- * In contrast to #GNUNET_PQ_result_spec_absolute_time_nbo(),
- * this function ensures that the result is rounded and can
- * be converted to JSON.
+ * Array of hashes of denominations
+ *
+ * @param db context of the database connection
+ * @param name name of the field in the table
+ * @param[out] num number of elements in @e denom_sigs
+ * @param[out] denom_hs where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_array_denom_hash (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ size_t *num,
+ struct TALER_DenominationHashP **denom_hs);
+
+
+/**
+ * Array of GNUNET_HashCode
+ *
+ * @param db context of the database connection
+ * @param name name of the field in the table
+ * @param[out] num number of elements in @e denom_sigs
+ * @param[out] hashes where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_PQ_ResultSpec
+TALER_PQ_result_spec_array_hash_code (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ size_t *num,
+ struct GNUNET_HashCode **hashes);
+
+/**
+ * Array of amounts
*
+ * @param db context of the database connection
* @param name name of the field in the table
- * @param[out] at where to store the result
+ * @param currency The currency
+ * @param[out] num number of elements in @e amounts
+ * @param[out] amounts where to store the result
* @return array entry for the result specification to use
*/
struct GNUNET_PQ_ResultSpec
-TALER_PQ_result_spec_absolute_time_nbo (const char *name,
- struct GNUNET_TIME_AbsoluteNBO *at);
+TALER_PQ_result_spec_array_amount (
+ struct GNUNET_PQ_Context *db,
+ const char *name,
+ const char *currency,
+ size_t *num,
+ struct TALER_Amount **amounts);
#endif /* TALER_PQ_LIB_H_ */
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
deleted file mode 100644
index f55f0c2e4..000000000
--- a/src/include/taler_signatures.h
+++ /dev/null
@@ -1,1417 +0,0 @@
-/*
- This file is part of TALER
- Copyright (C) 2014-2017 Taler Systems SA
-
- TALER is free software; you can redistribute it and/or modify it under the
- terms of the GNU General Public License as published by the Free Software
- Foundation; either version 3, or (at your option) any later version.
-
- TALER is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along with
- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
-*/
-/**
- * @file taler_signatures.h
- * @brief message formats and signature constants used to define
- * the binary formats of signatures in Taler
- * @author Florian Dold
- * @author Benedikt Mueller
- *
- * This file should define the constants and C structs that one needs
- * to know to implement Taler clients (wallets or merchants or
- * auditor) that need to produce or verify Taler signatures.
- */
-#ifndef TALER_SIGNATURES_H
-#define TALER_SIGNATURES_H
-
-#include <gnunet/gnunet_util_lib.h>
-#include "taler_amount_lib.h"
-#include "taler_crypto_lib.h"
-
-/**
- * Cut-and-choose size for refreshing. Client looses the gamble (of
- * unaccountable transfers) with probability 1/TALER_CNC_KAPPA. Refresh cost
- * increases linearly with TALER_CNC_KAPPA, and 3 is sufficient up to a
- * income/sales tax of 66% of total transaction value. As there is
- * no good reason to change this security parameter, we declare it
- * fixed and part of the protocol.
- */
-#define TALER_CNC_KAPPA 3
-
-
-/*********************************************/
-/* Exchange offline signatures (with master key) */
-/*********************************************/
-
-/**
- * Purpose for signing public keys signed by the exchange master key.
- */
-#define TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY 1024
-
-/**
- * Purpose for denomination keys signed by the exchange master key.
- */
-#define TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY 1025
-
-/**
- * Fees charged per (aggregate) wire transfer to the merchant.
- */
-#define TALER_SIGNATURE_MASTER_WIRE_FEES 1028
-
-/**
- * The given revocation key was revoked and must no longer be used.
- */
-#define TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED 1029
-
-/**
- * Signature where the Exchange confirms its IBAN details in
- * the /wire response.
- */
-#define TALER_SIGNATURE_MASTER_WIRE_DETAILS 1030
-
-/*********************************************/
-/* Exchange online signatures (with signing key) */
-/*********************************************/
-
-/**
- * Purpose for the state of a reserve, signed by the exchange's signing
- * key.
- */
-#define TALER_SIGNATURE_EXCHANGE_RESERVE_STATUS 1032
-
-/**
- * Signature where the Exchange confirms a deposit request.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT 1033
-
-/**
- * Signature where the exchange (current signing key) confirms the
- * no-reveal index for cut-and-choose and the validity of the melted
- * coins.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT 1034
-
-/**
- * Signature where the Exchange confirms the full /keys response set.
- */
-#define TALER_SIGNATURE_EXCHANGE_KEY_SET 1035
-
-/**
- * Signature where the Exchange confirms the /track/transaction response.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE 1036
-
-/**
- * Signature where the Exchange confirms the /wire/deposit response.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT 1037
-
-/**
- * Signature where the Exchange confirms a refund request.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND 1038
-
-/**
- * Signature where the Exchange confirms a recoup.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP 1039
-
-/**
- * Signature where the Exchange confirms it closed a reserve.
- */
-#define TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED 1040
-
-/**
- * Signature where the Exchange confirms a recoup-refresh operation.
- */
-#define TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH 1041
-
-
-/**********************/
-/* Auditor signatures */
-/**********************/
-
-/**
- * Signature where the auditor confirms that he is
- * aware of certain denomination keys from the exchange.
- */
-#define TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS 1064
-
-
-/***********************/
-/* Merchant signatures */
-/***********************/
-
-/**
- * Signature where the merchant confirms a contract (to the customer).
- */
-#define TALER_SIGNATURE_MERCHANT_CONTRACT 1101
-
-/**
- * Signature where the merchant confirms a refund (of a coin).
- */
-#define TALER_SIGNATURE_MERCHANT_REFUND 1102
-
-/**
- * Signature where the merchant confirms that he needs the wire
- * transfer identifier for a deposit operation.
- */
-#define TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION 1103
-
-/**
- * Signature where the merchant confirms that the payment was
- * successful
- */
-#define TALER_SIGNATURE_MERCHANT_PAYMENT_OK 1104
-
-/**
- * Signature where the merchant confirms that the user replayed
- * a payment for a browser session.
- */
-#define TALER_SIGNATURE_MERCHANT_PAY_SESSION 1106
-
-/**
- * Signature where the merchant confirms its own (salted)
- * wire details (not yet really used).
- */
-#define TALER_SIGNATURE_MERCHANT_WIRE_DETAILS 1107
-
-
-/*********************/
-/* Wallet signatures */
-/*********************/
-
-/**
- * Signature where the reserve key confirms a withdraw request.
- */
-#define TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW 1200
-
-/**
- * Signature made by the wallet of a user to confirm a deposit of a coin.
- */
-#define TALER_SIGNATURE_WALLET_COIN_DEPOSIT 1201
-
-/**
- * Signature using a coin key confirming the melting of a coin.
- */
-#define TALER_SIGNATURE_WALLET_COIN_MELT 1202
-
-/**
- * Signature using a coin key requesting recoup.
- */
-#define TALER_SIGNATURE_WALLET_COIN_RECOUP 1203
-
-/**
- * Signature using a coin key authenticating link data.
- */
-#define TALER_SIGNATURE_WALLET_COIN_LINK 1204
-
-
-/*******************/
-/* Test signatures */
-/*******************/
-
-/**
- * EdDSA test signature.
- */
-#define TALER_SIGNATURE_CLIENT_TEST_EDDSA 1302
-
-/**
- * EdDSA test signature.
- */
-#define TALER_SIGNATURE_EXCHANGE_TEST_EDDSA 1303
-
-
-/************************/
-/* Anastasis signatures */
-/************************/
-
-/**
- * EdDSA signature for a policy upload.
- */
-#define TALER_SIGNATURE_ANASTASIS_POLICY_UPLOAD 1400
-
-/**
- * EdDSA signature for a policy download.
- */
-#define TALER_SIGNATURE_ANASTASIS_POLICY_DOWNLOAD 1401
-
-
-/*******************/
-/* Sync signatures */
-/*******************/
-
-
-/**
- * EdDSA signature for a backup upload.
- */
-#define TALER_SIGNATURE_SYNC_BACKUP_UPLOAD 1450
-
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * @brief Format used for to allow the wallet to authenticate
- * link data provided by the exchange.
- */
-struct TALER_LinkDataPS
-{
-
- /**
- * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK.
- * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash of the denomination public key of the new coin.
- */
- struct GNUNET_HashCode h_denom_pub;
-
- /**
- * Public key of the old coin being refreshed.
- */
- struct TALER_CoinSpendPublicKeyP old_coin_pub;
-
- /**
- * Transfer public key (for which the private key was not revealed)
- */
- struct TALER_TransferPublicKeyP transfer_pub;
-
- /**
- * Hash of the blinded new coin.
- */
- struct GNUNET_HashCode coin_envelope_hash;
-};
-
-
-/**
- * @brief Format used for to generate the signature on a request to withdraw
- * coins from a reserve.
- */
-struct TALER_WithdrawRequestPS
-{
-
- /**
- * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
- * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Reserve public key (which reserve to withdraw from). This is
- * the public key which must match the signature.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Value of the coin being exchangeed (matching the denomination key)
- * plus the transaction fee. We include this in what is being
- * signed so that we can verify a reserve's remaining total balance
- * without needing to access the respective denomination key
- * information each time.
- */
- struct TALER_AmountNBO amount_with_fee;
-
- /**
- * Withdrawal fee charged by the exchange. This must match the Exchange's
- * denomination key's withdrawal fee. If the client puts in an
- * invalid withdrawal fee (too high or too low) that does not match
- * the Exchange's denomination key, the withdraw operation is invalid
- * and will be rejected by the exchange. The @e amount_with_fee minus
- * the @e withdraw_fee is must match the value of the generated
- * coin. We include this in what is being signed so that we can
- * verify a exchange's accounting without needing to access the
- * respective denomination key information each time.
- */
- struct TALER_AmountNBO withdraw_fee;
-
- /**
- * Hash of the denomination public key for the coin that is withdrawn.
- */
- struct GNUNET_HashCode h_denomination_pub GNUNET_PACKED;
-
- /**
- * Hash of the (blinded) message to be signed by the Exchange.
- */
- struct GNUNET_HashCode h_coin_envelope GNUNET_PACKED;
-};
-
-
-/**
- * @brief Format used to generate the signature on a request to deposit
- * a coin into the account of a merchant.
- */
-struct TALER_DepositRequestPS
-{
- /**
- * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
- * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the contract for which this deposit is made.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * Hash over the wiring information of the merchant.
- */
- struct GNUNET_HashCode h_wire GNUNET_PACKED;
-
- /**
- * Time when this request was generated. Used, for example, to
- * assess when (roughly) the income was achieved for tax purposes.
- * Note that the Exchange will only check that the timestamp is not "too
- * far" into the future (i.e. several days). The fact that the
- * timestamp falls within the validity period of the coin's
- * denomination key is irrelevant for the validity of the deposit
- * request, as obviously the customer and merchant could conspire to
- * set any timestamp. Also, the Exchange must accept very old deposit
- * requests, as the merchant might have been unable to transmit the
- * deposit request in a timely fashion (so back-dating is not
- * prevented).
- */
- struct GNUNET_TIME_AbsoluteNBO timestamp;
-
- /**
- * How much time does the merchant have to issue a refund request?
- * Zero if refunds are not allowed. After this time, the coin
- * cannot be refunded.
- */
- struct GNUNET_TIME_AbsoluteNBO refund_deadline;
-
- /**
- * Amount to be deposited, including deposit fee charged by the
- * exchange. This is the total amount that the coin's value at the exchange
- * will be reduced by.
- */
- struct TALER_AmountNBO amount_with_fee;
-
- /**
- * Depositing fee charged by the exchange. This must match the Exchange's
- * denomination key's depositing fee. If the client puts in an
- * invalid deposit fee (too high or too low) that does not match the
- * Exchange's denomination key, the deposit operation is invalid and
- * will be rejected by the exchange. The @e amount_with_fee minus the
- * @e deposit_fee is the amount that will be transferred to the
- * account identified by @e h_wire.
- */
- struct TALER_AmountNBO deposit_fee;
-
- /**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
- */
- struct TALER_MerchantPublicKeyP merchant;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange. The deposit request is to be
- * signed by the corresponding private key (using EdDSA).
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a confirmation
- * from the exchange that a deposit request succeeded.
- */
-struct TALER_DepositConfirmationPS
-{
- /**
- * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT. Signed
- * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the contract for which this deposit is made.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * Hash over the wiring information of the merchant.
- */
- struct GNUNET_HashCode h_wire GNUNET_PACKED;
-
- /**
- * Time when this confirmation was generated.
- */
- struct GNUNET_TIME_AbsoluteNBO timestamp;
-
- /**
- * How much time does the @e merchant have to issue a refund
- * request? Zero if refunds are not allowed. After this time, the
- * coin cannot be refunded. Note that the wire transfer will not be
- * performed by the exchange until the refund deadline. This value
- * is taken from the original deposit request.
- */
- struct GNUNET_TIME_AbsoluteNBO refund_deadline;
-
- /**
- * Amount to be deposited, excluding fee. Calculated from the
- * amount with fee and the fee from the deposit request.
- */
- struct TALER_AmountNBO amount_without_fee;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange. The deposit request is to be
- * signed by the corresponding private key (using EdDSA).
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
- */
- struct TALER_MerchantPublicKeyP merchant;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a request to refund
- * a coin into the account of the customer.
- */
-struct TALER_RefundRequestPS
-{
- /**
- * Purpose must be #TALER_SIGNATURE_MERCHANT_REFUND.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the proposal data to identify the contract
- * which is being refunded.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
- */
- struct TALER_MerchantPublicKeyP merchant;
-
- /**
- * Merchant-generated transaction ID for the refund.
- */
- uint64_t rtransaction_id GNUNET_PACKED;
-
- /**
- * Amount to be refunded, including refund fee charged by the
- * exchange to the customer.
- */
- struct TALER_AmountNBO refund_amount;
-
- /**
- * Refund fee charged by the exchange. This must match the
- * Exchange's denomination key's refund fee. If the client puts in
- * an invalid refund fee (too high or too low) that does not match
- * the Exchange's denomination key, the refund operation is invalid
- * and will be rejected by the exchange. The @e amount_with_fee
- * minus the @e refund_fee is the amount that will be credited to
- * the original coin.
- */
- struct TALER_AmountNBO refund_fee;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a request to refund
- * a coin into the account of the customer.
- */
-struct TALER_RefundConfirmationPS
-{
- /**
- * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the proposal data to identify the contract
- * which is being refunded.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * The Merchant's public key. Allows the merchant to later refund
- * the transaction or to inquire about the wire transfer identifier.
- */
- struct TALER_MerchantPublicKeyP merchant;
-
- /**
- * Merchant-generated transaction ID for the refund.
- */
- uint64_t rtransaction_id GNUNET_PACKED;
-
- /**
- * Amount to be refunded, including refund fee charged by the
- * exchange to the customer.
- */
- struct TALER_AmountNBO refund_amount;
-
- /**
- * Refund fee charged by the exchange. This must match the
- * Exchange's denomination key's refund fee. If the client puts in
- * an invalid refund fee (too high or too low) that does not match
- * the Exchange's denomination key, the refund operation is invalid
- * and will be rejected by the exchange. The @e amount_with_fee
- * minus the @e refund_fee is the amount that will be credited to
- * the original coin.
- */
- struct TALER_AmountNBO refund_fee;
-
-};
-
-
-/**
- * @brief Message signed by a coin to indicate that the coin should be
- * melted.
- */
-struct TALER_RefreshMeltCoinAffirmationPS
-{
- /**
- * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT.
- * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Which melt commitment is made by the wallet.
- */
- struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
-
- /**
- * How much of the value of the coin should be melted? This amount
- * includes the fees, so the final amount contributed to the melt is
- * this value minus the fee for melting the coin. We include the
- * fee in what is being signed so that we can verify a reserve's
- * remaining total balance without needing to access the respective
- * denomination key information each time.
- */
- struct TALER_AmountNBO amount_with_fee;
-
- /**
- * Melting fee charged by the exchange. This must match the Exchange's
- * denomination key's melting fee. If the client puts in an invalid
- * melting fee (too high or too low) that does not match the Exchange's
- * denomination key, the melting operation is invalid and will be
- * rejected by the exchange. The @e amount_with_fee minus the @e
- * melt_fee is the amount that will be credited to the melting
- * session.
- */
- struct TALER_AmountNBO melt_fee;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange. The deposit request is to be
- * signed by the corresponding private key (using EdDSA).
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-};
-
-
-/**
- * @brief Format of the block signed by the Exchange in response to a successful
- * "/refresh/melt" request. Hereby the exchange affirms that all of the
- * coins were successfully melted. This also commits the exchange to a
- * particular index to not be revealed during the refresh.
- */
-struct TALER_RefreshMeltConfirmationPS
-{
- /**
- * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT. Signed
- * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Commitment made in the /refresh/melt.
- */
- struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
-
- /**
- * Index that the client will not have to reveal, in NBO.
- * Must be smaller than #TALER_CNC_KAPPA.
- */
- uint32_t noreveal_index GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Information about a signing key of the exchange. Signing keys are used
- * to sign exchange messages other than coins, i.e. to confirm that a
- * deposit was successful or that a refresh was accepted.
- */
-struct TALER_ExchangeSigningKeyValidityPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Master public key of the exchange corresponding to @e signature.
- * This is the long-term offline master key of the exchange.
- */
- struct TALER_MasterPublicKeyP master_public_key;
-
- /**
- * When does this signing key begin to be valid?
- */
- struct GNUNET_TIME_AbsoluteNBO start;
-
- /**
- * When does this signing key expire? Note: This is currently when
- * the Exchange will definitively stop using it. Signatures made with
- * the key remain valid until @e end. When checking validity periods,
- * clients should allow for some overlap between keys and tolerate
- * the use of either key during the overlap time (due to the
- * possibility of clock skew).
- */
- struct GNUNET_TIME_AbsoluteNBO expire;
-
- /**
- * When do signatures with this signing key become invalid? After
- * this point, these signatures cannot be used in (legal) disputes
- * anymore, as the Exchange is then allowed to destroy its side of the
- * evidence. @e end is expected to be significantly larger than @e
- * expire (by a year or more).
- */
- struct GNUNET_TIME_AbsoluteNBO end;
-
- /**
- * The public online signing key that the exchange will use
- * between @e start and @e expire.
- */
- struct TALER_ExchangePublicKeyP signkey_pub;
-};
-
-
-/**
- * @brief Signature made by the exchange over the full set of keys, used
- * to detect cheating exchanges that give out different sets to
- * different users.
- */
-struct TALER_ExchangeKeySetPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET. Signed
- * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Time of the key set issue.
- */
- struct GNUNET_TIME_AbsoluteNBO list_issue_date;
-
- /**
- * Hash over the various denomination signing keys returned.
- */
- struct GNUNET_HashCode hc GNUNET_PACKED;
-};
-
-
-/**
- * @brief Information about a denomination key. Denomination keys
- * are used to sign coins of a certain value into existence.
- */
-struct TALER_DenominationKeyValidityPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * The long-term offline master key of the exchange that was
- * used to create @e signature.
- */
- struct TALER_MasterPublicKeyP master;
-
- /**
- * Start time of the validity period for this key.
- */
- struct GNUNET_TIME_AbsoluteNBO start;
-
- /**
- * The exchange will sign fresh coins between @e start and this time.
- * @e expire_withdraw will be somewhat larger than @e start to
- * ensure a sufficiently large anonymity set, while also allowing
- * the Exchange to limit the financial damage in case of a key being
- * compromised. Thus, exchanges with low volume are expected to have a
- * longer withdraw period (@e expire_withdraw - @e start) than exchanges
- * with high transaction volume. The period may also differ between
- * types of coins. A exchange may also have a few denomination keys
- * with the same value with overlapping validity periods, to address
- * issues such as clock skew.
- */
- struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
-
- /**
- * Coins signed with the denomination key must be spent or refreshed
- * between @e start and this expiration time. After this time, the
- * exchange will refuse transactions involving this key as it will
- * "drop" the table with double-spending information (shortly after)
- * this time. Note that wallets should refresh coins significantly
- * before this time to be on the safe side. @e expire_deposit must be
- * significantly larger than @e expire_withdraw (by months or even
- * years).
- */
- struct GNUNET_TIME_AbsoluteNBO expire_deposit;
-
- /**
- * When do signatures with this denomination key become invalid?
- * After this point, these signatures cannot be used in (legal)
- * disputes anymore, as the Exchange is then allowed to destroy its side
- * of the evidence. @e expire_legal is expected to be significantly
- * larger than @e expire_deposit (by a year or more).
- */
- struct GNUNET_TIME_AbsoluteNBO expire_legal;
-
- /**
- * The value of the coins signed with this denomination key.
- */
- struct TALER_AmountNBO value;
-
- /**
- * The fee the exchange charges when a coin of this type is withdrawn.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_withdraw;
-
- /**
- * The fee the exchange charges when a coin of this type is deposited.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_deposit;
-
- /**
- * The fee the exchange charges when a coin of this type is refreshed.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_refresh;
-
- /**
- * The fee the exchange charges when a coin of this type is refunded.
- * (can be zero). Note that refund fees are charged to the customer;
- * if a refund is given, the deposit fee is also refunded.
- */
- struct TALER_AmountNBO fee_refund;
-
- /**
- * Hash code of the denomination public key. (Used to avoid having
- * the variable-size RSA key in this struct.)
- */
- struct GNUNET_HashCode denom_hash GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Information signed by an auditor affirming
- * the master public key and the denomination keys
- * of a exchange.
- */
-struct TALER_ExchangeKeyValidityPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash of the auditor's URL (including 0-terminator).
- */
- struct GNUNET_HashCode auditor_url_hash;
-
- /**
- * The long-term offline master key of the exchange, affirmed by the
- * auditor. Hashed string, including 0-terminator.
- */
- struct TALER_MasterPublicKeyP master;
-
- /**
- * Start time of the validity period for this key.
- */
- struct GNUNET_TIME_AbsoluteNBO start;
-
- /**
- * The exchange will sign fresh coins between @e start and this time.
- * @e expire_withdraw will be somewhat larger than @e start to
- * ensure a sufficiently large anonymity set, while also allowing
- * the Exchange to limit the financial damage in case of a key being
- * compromised. Thus, exchanges with low volume are expected to have a
- * longer withdraw period (@e expire_withdraw - @e start) than exchanges
- * with high transaction volume. The period may also differ between
- * types of coins. A exchange may also have a few denomination keys
- * with the same value with overlapping validity periods, to address
- * issues such as clock skew.
- */
- struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
-
- /**
- * Coins signed with the denomination key must be spent or refreshed
- * between @e start and this expiration time. After this time, the
- * exchange will refuse transactions involving this key as it will
- * "drop" the table with double-spending information (shortly after)
- * this time. Note that wallets should refresh coins significantly
- * before this time to be on the safe side. @e expire_deposit must be
- * significantly larger than @e expire_withdraw (by months or even
- * years).
- */
- struct GNUNET_TIME_AbsoluteNBO expire_deposit;
-
- /**
- * When do signatures with this denomination key become invalid?
- * After this point, these signatures cannot be used in (legal)
- * disputes anymore, as the Exchange is then allowed to destroy its side
- * of the evidence. @e expire_legal is expected to be significantly
- * larger than @e expire_deposit (by a year or more).
- */
- struct GNUNET_TIME_AbsoluteNBO expire_legal;
-
- /**
- * The value of the coins signed with this denomination key.
- */
- struct TALER_AmountNBO value;
-
- /**
- * The fee the exchange charges when a coin of this type is withdrawn.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_withdraw;
-
- /**
- * The fee the exchange charges when a coin of this type is deposited.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_deposit;
-
- /**
- * The fee the exchange charges when a coin of this type is refreshed.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_refresh;
-
- /**
- * The fee the exchange charges when a coin of this type is refreshed.
- * (can be zero).
- */
- struct TALER_AmountNBO fee_refund;
-
- /**
- * Hash code of the denomination public key. (Used to avoid having
- * the variable-size RSA key in this struct.)
- */
- struct GNUNET_HashCode denom_hash GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Information signed by the exchange's master
- * key affirming the IBAN details for the exchange.
- */
-struct TALER_MasterWireDetailsPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_WIRE_DETAILS.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the account holder's payto:// URL and
- * the salt, as done by #TALER_exchange_wire_signature_hash().
- */
- struct GNUNET_HashCode h_wire_details GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Information signed by the exchange's master
- * key stating the wire fee to be paid per wire transfer.
- */
-struct TALER_MasterWireFeePS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_WIRE_FEES.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the wire method (yes, H("x-taler-bank") or H("iban")), in lower
- * case, including 0-terminator. Used to uniquely identify which
- * wire method these fees apply to.
- */
- struct GNUNET_HashCode h_wire_method;
-
- /**
- * Start date when the fee goes into effect.
- */
- struct GNUNET_TIME_AbsoluteNBO start_date;
-
- /**
- * End date when the fee stops being in effect (exclusive)
- */
- struct GNUNET_TIME_AbsoluteNBO end_date;
-
- /**
- * Fee charged to the merchant per wire transfer.
- */
- struct TALER_AmountNBO wire_fee;
-
- /**
- * Closing fee charged when we wire back funds of a reserve.
- */
- struct TALER_AmountNBO closing_fee;
-
-};
-
-
-/**
- * @brief Message confirming that a denomination key was revoked.
- */
-struct TALER_MasterDenominationKeyRevocationPS
-{
- /**
- * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash of the denomination key.
- */
- struct GNUNET_HashCode h_denom_pub;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a request to obtain
- * the wire transfer identifier associated with a deposit.
- */
-struct TALER_DepositTrackPS
-{
- /**
- * Purpose must be #TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the proposal data of the contract for which this deposit is made.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * Hash over the wiring information of the merchant.
- */
- struct GNUNET_HashCode h_wire GNUNET_PACKED;
-
- /**
- * The Merchant's public key. The deposit inquiry request is to be
- * signed by the corresponding private key (using EdDSA).
- */
- struct TALER_MerchantPublicKeyP merchant;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
-};
-
-
-/**
- * @brief Format internally used for packing the detailed information
- * to generate the signature for /track/transfer signatures.
- */
-struct TALER_WireDepositDetailP
-{
-
- /**
- * Hash of the contract
- */
- struct GNUNET_HashCode h_contract_terms;
-
- /**
- * Time when the wire transfer was performed by the exchange.
- */
- struct GNUNET_TIME_AbsoluteNBO execution_time;
-
- /**
- * Coin's public key.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Total value of the coin.
- */
- struct TALER_AmountNBO deposit_value;
-
- /**
- * Fees charged by the exchange for the deposit.
- */
- struct TALER_AmountNBO deposit_fee;
-
-};
-
-
-/**
- * @brief Format used to generate the signature for /wire/deposit
- * replies.
- */
-struct TALER_WireDepositDataPS
-{
- /**
- * Purpose header for the signature over the contract with
- * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Total amount that was transferred.
- */
- struct TALER_AmountNBO total;
-
- /**
- * Wire fee that was charged.
- */
- struct TALER_AmountNBO wire_fee;
-
- /**
- * Public key of the merchant (for all aggregated transactions).
- */
- struct TALER_MerchantPublicKeyP merchant_pub;
-
- /**
- * Hash of wire details of the merchant.
- */
- struct GNUNET_HashCode h_wire;
-
- /**
- * Hash of the individual deposits that were aggregated,
- * each in the format of a `struct TALER_WireDepositDetailP`.
- */
- struct GNUNET_HashCode h_details;
-
-};
-
-/**
- * The contract sent by the merchant to the wallet.
- */
-struct TALER_ProposalDataPS
-{
- /**
- * Purpose header for the signature over the proposal data
- * with purpose #TALER_SIGNATURE_MERCHANT_CONTRACT.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash of the JSON contract in UTF-8 including 0-termination,
- * using JSON_COMPACT | JSON_SORT_KEYS
- */
- struct GNUNET_HashCode hash;
-};
-
-/**
- * Used by merchants to return signed responses to /pay requests.
- * Currently only used to return 200 OK signed responses.
- */
-struct PaymentResponsePS
-{
- /**
- * Set to TALER_SIGNATURE_MERCHANT_PAYMENT_OK so far. Note that
- * unsuccessful payments are usually proven by some exchange's signature,
- * thus it is unlikely that a merchant needs to set a purpose other than
- * the above mentioned
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash of the proposal data associated with this confirmation
- */
- struct GNUNET_HashCode h_contract_terms;
-};
-
-
-/**
- * Details affirmed by the exchange about a wire transfer the exchange
- * claims to have done with respect to a deposit operation.
- */
-struct TALER_ConfirmWirePS
-{
- /**
- * Purpose header for the signature over the contract with
- * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hash over the wiring information of the merchant.
- */
- struct GNUNET_HashCode h_wire GNUNET_PACKED;
-
- /**
- * Hash over the contract for which this deposit is made.
- */
- struct GNUNET_HashCode h_contract_terms GNUNET_PACKED;
-
- /**
- * Raw value (binary encoding) of the wire transfer subject.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-
- /**
- * The coin's public key. This is the value that must have been
- * signed (blindly) by the Exchange.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * When did the exchange execute this transfer? Note that the
- * timestamp may not be exactly the same on the wire, i.e.
- * because the wire has a different timezone or resolution.
- */
- struct GNUNET_TIME_AbsoluteNBO execution_time;
-
- /**
- * The contribution of @e coin_pub to the total transfer volume.
- * This is the value of the deposit minus the fee.
- */
- struct TALER_AmountNBO coin_contribution;
-
-};
-
-
-/**
- * Signed data to request that a coin should be refunded as part of
- * the "emergency" /recoup protocol. The refund will go back to the bank
- * account that created the reserve.
- */
-struct TALER_RecoupRequestPS
-{
- /**
- * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Public key of the coin to be refunded.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Hash of the denomination public key of the coin.
- */
- struct GNUNET_HashCode h_denom_pub;
-
- /**
- * Blinding factor that was used to withdraw the coin.
- */
- struct TALER_DenominationBlindingKeyP coin_blind;
-};
-
-
-/**
- * Response by which the exchange affirms that it will
- * refund a coin as part of the emergency /recoup
- * protocol. The recoup will go back to the bank
- * account that created the reserve.
- */
-struct TALER_RecoupConfirmationPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * When did the exchange receive the recoup request?
- * Indirectly determines when the wire transfer is (likely)
- * to happen.
- */
- struct GNUNET_TIME_AbsoluteNBO timestamp;
-
- /**
- * How much of the coin's value will the exchange transfer?
- * (Needed in case the coin was partially spent.)
- */
- struct TALER_AmountNBO recoup_amount;
-
- /**
- * Public key of the coin.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Public key of the reserve that will receive the recoup.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-};
-
-
-/**
- * Response by which the exchange affirms that it will refund a refreshed coin
- * as part of the emergency /recoup protocol. The recoup will go back to the
- * old coin's balance.
- */
-struct TALER_RecoupRefreshConfirmationPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * When did the exchange receive the recoup request?
- * Indirectly determines when the wire transfer is (likely)
- * to happen.
- */
- struct GNUNET_TIME_AbsoluteNBO timestamp;
-
- /**
- * How much of the coin's value will the exchange transfer?
- * (Needed in case the coin was partially spent.)
- */
- struct TALER_AmountNBO recoup_amount;
-
- /**
- * Public key of the refreshed coin.
- */
- struct TALER_CoinSpendPublicKeyP coin_pub;
-
- /**
- * Public key of the old coin that will receive the recoup.
- */
- struct TALER_CoinSpendPublicKeyP old_coin_pub;
-};
-
-
-/**
- * Response by which the exchange affirms that it has
- * closed a reserve and send back the funds.
- */
-struct TALER_ReserveCloseConfirmationPS
-{
-
- /**
- * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * When did the exchange initiate the wire transfer.
- */
- struct GNUNET_TIME_AbsoluteNBO timestamp;
-
- /**
- * How much did the exchange send?
- */
- struct TALER_AmountNBO closing_amount;
-
- /**
- * How much did the exchange charge for closing the reserve?
- */
- struct TALER_AmountNBO closing_fee;
-
- /**
- * Public key of the reserve that received the recoup.
- */
- struct TALER_ReservePublicKeyP reserve_pub;
-
- /**
- * Hash of the receiver's bank account.
- */
- struct GNUNET_HashCode h_wire;
-
- /**
- * Wire transfer subject.
- */
- struct TALER_WireTransferIdentifierRawP wtid;
-};
-
-
-/**
- * Used by the merchant to confirm with a signature that the refund has
- * been successfully done. Even though the frontend doesn't usually do crypto,
- * this signature may turn useful in court.
- */
-struct TALER_MerchantRefundConfirmationPS
-{
- /**
- * Set to #TALER_SIGNATURE_MERCHANT_REFUND_OK.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hashed order id; in case frontend wants to check it.
- * Hashed without the 0-termination.
- */
- struct GNUNET_HashCode h_order_id GNUNET_PACKED;
-
-};
-
-/**
- * Used by the merchant to confirm to the frontend that
- * the user did a payment replay with the current browser session.
- */
-struct TALER_MerchantPaySessionSigPS
-{
- /**
- * Set to #TALER_SIGNATURE_MERCHANT_PAY_SESSION.
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
- /**
- * Hashed order id.
- * Hashed without the 0-termination.
- */
- struct GNUNET_HashCode h_order_id GNUNET_PACKED;
-
- /**
- * Hashed session id.
- * Hashed without the 0-termination.
- */
- struct GNUNET_HashCode h_session_id GNUNET_PACKED;
-
-};
-
-
-GNUNET_NETWORK_STRUCT_END
-
-#endif
diff --git a/src/include/taler_sq_lib.h b/src/include/taler_sq_lib.h
new file mode 100644
index 000000000..b5749308e
--- /dev/null
+++ b/src/include/taler_sq_lib.h
@@ -0,0 +1,99 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2020 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file include/taler_sq_lib.h
+ * @brief helper functions for DB interactions with SQLite
+ * @author Jonathan Buchanan
+ */
+#ifndef TALER_SQ_LIB_H_
+#define TALER_SQ_LIB_H_
+
+#include <sqlite3.h>
+#include <jansson.h>
+#include <gnunet/gnunet_sq_lib.h>
+#include "taler_util.h"
+
+/**
+ * Generate query parameter for a currency, consisting of the
+ * components "value", "fraction" in this order. The
+ * types must be a 64-bit integer and a 64-bit integer.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct GNUNET_SQ_QueryParam
+TALER_SQ_query_param_amount_nbo (const struct TALER_AmountNBO *x);
+
+
+/**
+ * Generate query parameter for a currency, consisting of the
+ * components "value", "fraction" in this order. The
+ * types must be a 64-bit integer and a 64-bit integer.
+ *
+ * @param x pointer to the query parameter to pass
+ */
+struct GNUNET_SQ_QueryParam
+TALER_SQ_query_param_amount (const struct TALER_Amount *x);
+
+
+/**
+ * Generate query parameter for a JSON object (stored as a string
+ * in the DB). Note that @a x must really be a JSON object or array,
+ * passing just a value (string, integer) is not supported and will
+ * result in an abort.
+ *
+ * @param x pointer to the json object to pass
+ */
+struct GNUNET_SQ_QueryParam
+TALER_SQ_query_param_json (const json_t *x);
+
+
+/**
+ * Currency amount expected.
+ *
+ * @param currency currency to use for @a amount
+ * @param[out] amount where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_SQ_ResultSpec
+TALER_SQ_result_spec_amount_nbo (const char *currency,
+ struct TALER_AmountNBO *amount);
+
+
+/**
+ * Currency amount expected.
+ *
+ * @param currency currency to use for @a amount
+ * @param[out] amount where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_SQ_ResultSpec
+TALER_SQ_result_spec_amount (const char *currency,
+ struct TALER_Amount *amount);
+
+
+/**
+ * json_t expected.
+ *
+ * @param[out] jp where to store the result
+ * @return array entry for the result specification to use
+ */
+struct GNUNET_SQ_ResultSpec
+TALER_SQ_result_spec_json (json_t **jp);
+
+
+#endif /* TALER_SQ_LIB_H_ */
+
+/* end of include/taler_sq_lib.h */
diff --git a/src/include/taler_templating_lib.h b/src/include/taler_templating_lib.h
new file mode 100644
index 000000000..6af6db715
--- /dev/null
+++ b/src/include/taler_templating_lib.h
@@ -0,0 +1,130 @@
+/*
+ This file is part of TALER
+ Copyright (C) 2020, 2022 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file taler_templating_lib.h
+ * @brief logic to load and complete HTML templates
+ * @author Christian Grothoff
+ */
+#ifndef TALER_TEMPLATING_LIB_H
+#define TALER_TEMPLATING_LIB_H
+
+#include <microhttpd.h>
+#include "taler_mhd_lib.h"
+
+/**
+ * Fill in Mustach template @a tmpl using the data from @a root
+ * and return the result in @a result.
+ *
+ * @param tmpl 0-terminated string with Mustach template
+ * @param root JSON data to fill into the template
+ * @param[out] result where to write the result
+ * @param[out] result_size where to write the length of the result
+ * @return 0 on success, otherwise Mustach-specific error code
+ */
+int
+TALER_TEMPLATING_fill (const char *tmpl,
+ const json_t *root,
+ void **result,
+ size_t *result_size);
+
+
+/**
+ * Load a @a template and substitute using @a root, returning the result in a
+ * @a reply encoded suitable for the @a connection with the given @a
+ * http_status code. On errors, the @a http_status code
+ * is updated to reflect the type of error encoded in the
+ * @a reply.
+ *
+ * @param connection the connection we act upon
+ * @param[in,out] http_status code to use on success,
+ * set to alternative code on failure
+ * @param template basename of the template to load
+ * @param instance_id instance ID, used to compute static files URL
+ * @param taler_uri value for "Taler:" header to set, or NULL
+ * @param root JSON object to pass as the root context
+ * @param[out] reply where to write the response object
+ * @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
+ * #GNUNET_SYSERR on failure (to queue an error)
+ */
+enum GNUNET_GenericReturnValue
+TALER_TEMPLATING_build (struct MHD_Connection *connection,
+ unsigned int *http_status,
+ const char *template,
+ const char *instance_id,
+ const char *taler_uri,
+ const json_t *root,
+ struct MHD_Response **reply);
+
+
+/**
+ * Load a @a template and substitute using @a root, returning
+ * the result to the @a connection with the given
+ * @a http_status code.
+ *
+ * @param connection the connection we act upon
+ * @param http_status code to use on success
+ * @param template basename of the template to load
+ * @param instance_id instance ID, used to compute static files URL
+ * @param taler_uri value for "Taler:" header to set, or NULL
+ * @param root JSON object to pass as the root context
+ * @return #GNUNET_OK on success (reply queued), #GNUNET_NO if an error was queued,
+ * #GNUNET_SYSERR on failure (to queue an error)
+ */
+enum GNUNET_GenericReturnValue
+TALER_TEMPLATING_reply (struct MHD_Connection *connection,
+ unsigned int http_status,
+ const char *template,
+ const char *instance_id,
+ const char *taler_uri,
+ const json_t *root);
+
+
+/**
+ * Load a @a template and substitute an error message based on @a ec and @a
+ * detail, returning the result to the @a connection with the given @a
+ * http_status code.
+ *
+ * @param connection the connection we act upon
+ * @param template_basename basename of the template to load
+ * @param http_status code to use on success
+ * @param ec error code to return
+ * @param detail optional text to add to the template
+ * @return #MHD_YES on success, #MHD_NO to just close the connection
+ */
+MHD_RESULT
+TALER_TEMPLATING_reply_error (struct MHD_Connection *connection,
+ const char *template_basename,
+ unsigned int http_status,
+ enum TALER_ErrorCode ec,
+ const char *detail);
+
+/**
+ * Preload templates.
+ *
+ * @param subsystem name of the subsystem, "merchant" or "exchange"
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_TEMPLATING_init (const char *subsystem);
+
+
+/**
+ * Nicely shut down templating subsystem.
+ */
+void
+TALER_TEMPLATING_done (void);
+
+#endif
diff --git a/src/include/taler_testing_lib.h b/src/include/taler_testing_lib.h
index 1194cb4b4..f07d9be20 100644
--- a/src/include/taler_testing_lib.h
+++ b/src/include/taler_testing_lib.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- (C) 2018 Taler Systems SA
+ (C) 2018-2023 Taler Systems SA
TALER is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as
@@ -20,6 +20,8 @@
/**
* @file include/taler_testing_lib.h
* @brief API for writing an interpreter to test Taler components
+ * This library is not thread-safe, all APIs must only be used from a single thread.
+ * This library calls abort() if it runs out of memory. Be aware of these limitations.
* @author Christian Grothoff <christian@grothoff.org>
* @author Marcello Stanisci
*/
@@ -27,11 +29,13 @@
#define TALER_TESTING_LIB_H
#include "taler_util.h"
-#include "taler_exchange_service.h"
+#include <microhttpd.h>
#include <gnunet/gnunet_json_lib.h>
#include "taler_json_lib.h"
+#include "taler_auditor_service.h"
#include "taler_bank_service.h"
-#include <microhttpd.h>
+#include "taler_exchange_service.h"
+#include "taler_fakebank_lib.h"
/* ********************* Helper functions ********************* */
@@ -50,133 +54,156 @@
/**
- * Allocate and return a piece of wire-details. Combines
- * a @a payto -URL and adds some salt to create the JSON.
+ * Log an error message about us receiving an unexpected HTTP
+ * status code at the current command and fail the test.
*
- * @param payto payto://-URL to encapsulate
- * @return JSON describing the account, including the
- * payto://-URL of the account, must be manually decref'd
+ * @param is interpreter to fail
+ * @param status unexpected HTTP status code received
+ * @param expected expected HTTP status code
*/
-json_t *
-TALER_TESTING_make_wire_details (const char *payto);
+#define TALER_TESTING_unexpected_status(is,status,expected) \
+ do { \
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
+ "Unexpected response code %u (expected: %u) to command %s in %s:%u\n", \
+ status, \
+ expected, \
+ TALER_TESTING_interpreter_get_current_label (is), \
+ __FILE__, \
+ __LINE__); \
+ TALER_TESTING_interpreter_fail (is); \
+ } while (0)
+
+/**
+ * Log an error message about us receiving an unexpected HTTP
+ * status code at the current command and fail the test and print the response
+ * body (expected as json).
+ *
+ * @param is interpreter to fail
+ * @param status unexpected HTTP status code received
+ * @param expected expected HTTP status code
+ * @param body received JSON-reply
+ */
+#define TALER_TESTING_unexpected_status_with_body(is,status,expected,body) \
+ do { \
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
+ "Unexpected response code %u (expected: %u) to " \
+ "command %s in %s:%u\nwith body:\n>>%s<<\n", \
+ status, \
+ expected, \
+ TALER_TESTING_interpreter_get_current_label (is), \
+ __FILE__, \
+ __LINE__, \
+ json_dumps (body, JSON_INDENT (2))); \
+ TALER_TESTING_interpreter_fail (is); \
+ } while (0)
/**
- * Find denomination key matching the given amount.
+ * Log an error message about a command not having
+ * run to completion.
*
- * @param keys array of keys to search
- * @param amount coin value to look for
- * @return NULL if no matching key was found
+ * @param is interpreter
+ * @param label command label of the incomplete command
*/
-const struct TALER_EXCHANGE_DenomPublicKey *
-TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys,
- const struct TALER_Amount *amount);
+#define TALER_TESTING_command_incomplete(is,label) \
+ do { \
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
+ "Command %s (%s:%u) did not complete (at %s)\n", \
+ label, \
+ __FILE__, \
+ __LINE__, \
+ TALER_TESTING_interpreter_get_current_label (is)); \
+ } while (0)
/**
- * Configuration data for an exchange.
+ * Common credentials used in a test.
*/
-struct TALER_TESTING_ExchangeConfiguration
+struct TALER_TESTING_Credentials
{
/**
- * Exchange base URL as it appears in the configuration. Note
- * that it might differ from the one where the exchange actually
- * listens from.
+ * Bank authentication details for the exchange bank
+ * account.
*/
- char *exchange_url;
+ struct TALER_BANK_AuthenticationData ba;
/**
- * Auditor base URL as it appears in the configuration. Note
- * that it might differ from the one where the auditor actually
- * listens from.
+ * Bank authentication details for the admin bank
+ * account.
*/
- char *auditor_url;
+ struct TALER_BANK_AuthenticationData ba_admin;
-};
+ /**
+ * Configuration file data.
+ */
+ struct GNUNET_CONFIGURATION_Handle *cfg;
-/**
- * Connection to the database: aggregates
- * plugin and session handles.
- */
-struct TALER_TESTING_DatabaseConnection
-{
/**
- * Database plugin.
+ * Base URL of the exchange.
*/
- struct TALER_EXCHANGEDB_Plugin *plugin;
+ char *exchange_url;
/**
- * Session with the database.
+ * Base URL of the auditor.
*/
- struct TALER_EXCHANGEDB_Session *session;
-};
+ char *auditor_url;
-/**
- * Prepare launching an exchange. Checks that the configured
- * port is available, runs taler-exchange-keyup,
- * taler-auditor-sign and taler-exchange-dbinit. Does not
- * launch the exchange process itself.
- *
- * @param config_filename configuration file to use
- * @param reset_db should we reset the database
- * @param[out] ec will be set to the exchange configuration data
- * @return #GNUNET_OK on success, #GNUNET_NO if test should be
- * skipped, #GNUNET_SYSERR on test failure
- */
-int
-TALER_TESTING_prepare_exchange (const char *config_filename,
- int reset_db,
- struct TALER_TESTING_ExchangeConfiguration *ec);
+ /**
+ * RFC 8905 URI of the exchange.
+ */
+ char *exchange_payto;
+ /**
+ * RFC 8905 URI of a user.
+ */
+ char *user42_payto;
-/**
- * "Canonical" cert_cb used when we are connecting to the
- * Exchange.
- *
- * @param cls closure, typically, the "run" method containing
- * all the commands to be run, and a closure for it.
- * @param hr http response details
- * @param keys the exchange's keys.
- * @param compat protocol compatibility information.
- */
-void
-TALER_TESTING_cert_cb (void *cls,
- const struct TALER_EXCHANGE_HttpResponse *hr,
- const struct TALER_EXCHANGE_Keys *keys,
- enum TALER_EXCHANGE_VersionCompatibility compat);
+ /**
+ * RFC 8905 URI of a user.
+ */
+ char *user43_payto;
+};
/**
- * Wait for the exchange to have started. Waits for at
- * most 10s, after that returns 77 to indicate an error.
- *
- * @param base_url what URL should we expect the exchange
- * to be running at
- * @return 0 on success
+ * What type of bank are we using?
*/
-int
-TALER_TESTING_wait_exchange_ready (const char *base_url);
+enum TALER_TESTING_BankSystem
+{
+ TALER_TESTING_BS_FAKEBANK = 1,
+ TALER_TESTING_BS_IBAN = 2
+};
/**
- * Wait for the auditor to have started. Waits for at
- * most 10s, after that returns 77 to indicate an error.
+ * Obtain bank credentials for a given @a cfg_file using
+ * @a exchange_account_section as the basis for the
+ * exchange account.
*
- * @param base_url what URL should we expect the auditor
- * to be running at
- * @return 0 on success
+ * @param cfg_file name of configuration to parse
+ * @param exchange_account_section configuration section name for the exchange account to use
+ * @param bs type of bank to use
+ * @param[out] ua where to write user account details
+ * and other credentials
*/
-int
-TALER_TESTING_wait_auditor_ready (const char *base_url);
+enum GNUNET_GenericReturnValue
+TALER_TESTING_get_credentials (
+ const char *cfg_file,
+ const char *exchange_account_section,
+ enum TALER_TESTING_BankSystem bs,
+ struct TALER_TESTING_Credentials *ua);
/**
- * Remove files from previous runs
+ * Allocate and return a piece of wire-details. Combines
+ * a @a payto -URL and adds some salt to create the JSON.
*
- * @param config_name configuration file to use+
+ * @param payto payto://-URL to encapsulate
+ * @return JSON describing the account, including the
+ * payto://-URL of the account, must be manually decref'd
*/
-void
-TALER_TESTING_cleanup_files (const char *config_name);
+json_t *
+TALER_TESTING_make_wire_details (const char *payto);
/**
@@ -186,75 +213,23 @@ TALER_TESTING_cleanup_files (const char *config_name);
* @param cfg configuration
* @return #GNUNET_OK on success
*/
-int
+enum GNUNET_GenericReturnValue
TALER_TESTING_cleanup_files_cfg (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg);
/**
- * Run `taler-exchange-keyup`.
- *
- * @param config_filename configuration file to use
- * @param output_filename where to write the output for the auditor
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_run_keyup (const char *config_filename,
- const char *output_filename);
-
-
-/**
- * Run `taler-auditor-dbinit -r` (reset auditor database).
- *
- * @param config_filename configuration file to use
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_auditor_db_reset (const char *config_filename);
-
-
-/**
- * Run `taler-exchange-dbinit -r` (reset exchange database).
- *
- * @param config_filename configuration file to use
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_exchange_db_reset (const char *config_filename);
-
-
-/**
- * Run `taler-auditor-sign`.
- *
- * @param config_filename configuration file to use
- * @param exchange_master_pub master public key of the exchange
- * @param auditor_base_url what is the base URL of the auditor
- * @param signdata_in where is the information from taler-exchange-keyup
- * @param signdata_out where to write the output for the exchange
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_run_auditor_sign (const char *config_filename,
- const char *exchange_master_pub,
- const char *auditor_base_url,
- const char *signdata_in,
- const char *signdata_out);
-
-
-/**
- * Run `taler-auditor-exchange`.
+ * Find denomination key matching the given amount.
*
- * @param config_filename configuration file to use
- * @param exchange_master_pub master public key of the exchange
- * @param exchange_base_url what is the base URL of the exchange
- * @param do_remove #GNUNET_NO to add exchange, #GNUNET_YES to remove
- * @return #GNUNET_OK on success
+ * @param keys array of keys to search
+ * @param amount coin value to look for
+ * @param age_restricted must the denomination be age restricted?
+ * @return NULL if no matching key was found
*/
-int
-TALER_TESTING_run_auditor_exchange (const char *config_filename,
- const char *exchange_master_pub,
- const char *exchange_base_url,
- int do_remove);
+const struct TALER_EXCHANGE_DenomPublicKey *
+TALER_TESTING_find_pk (const struct TALER_EXCHANGE_Keys *keys,
+ const struct TALER_Amount *amount,
+ bool age_restricted);
/**
@@ -263,176 +238,17 @@ TALER_TESTING_run_auditor_exchange (const char *config_filename,
* @param url URL to extract port from, 80 is default
* @return #GNUNET_OK if the port is free
*/
-int
+enum GNUNET_GenericReturnValue
TALER_TESTING_url_port_free (const char *url);
-/**
- * Configuration data for a bank.
- */
-struct TALER_TESTING_BankConfiguration
-{
-
- /**
- * Authentication data for the exchange user at the bank.
- */
- struct TALER_BANK_AuthenticationData exchange_auth;
-
- /**
- * Payto URL of the exchange's account ("2")
- */
- char *exchange_payto;
-
- /**
- * Payto URL of a user account ("42")
- */
- char *user42_payto;
-
- /**
- * Payto URL of another user's account ("43")
- */
- char *user43_payto;
-
-};
-
-/**
- * Prepare launching a fakebank. Check that the configuration
- * file has the right option, and that the port is available.
- * If everything is OK, return the configuration data of the fakebank.
- *
- * @param config_filename configuration file to use
- * @param config_section which account to use
- * (must match x-taler-bank)
- * @param[out] bc set to the bank's configuration data
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_prepare_fakebank (const char *config_filename,
- const char *config_section,
- struct TALER_TESTING_BankConfiguration *bc);
-
-
/* ******************* Generic interpreter logic ************ */
/**
* Global state of the interpreter, used by a command
* to access information about other commands.
*/
-struct TALER_TESTING_Interpreter
-{
-
- /**
- * Commands the interpreter will run.
- */
- struct TALER_TESTING_Command *commands;
-
- /**
- * Interpreter task (if one is scheduled).
- */
- struct GNUNET_SCHEDULER_Task *task;
-
- /**
- * ID of task called whenever we get a SIGCHILD.
- * Used for #TALER_TESTING_wait_for_sigchld().
- */
- struct GNUNET_SCHEDULER_Task *child_death_task;
-
- /**
- * Main execution context for the main loop.
- */
- struct GNUNET_CURL_Context *ctx;
-
- /**
- * Our configuration.
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Context for running the CURL event loop.
- */
- struct GNUNET_CURL_RescheduleContext *rc;
-
- /**
- * Handle to our fakebank, if #TALER_TESTING_run_with_fakebank()
- * was used. Otherwise NULL.
- */
- struct TALER_FAKEBANK_Handle *fakebank;
-
- /**
- * Task run on timeout.
- */
- struct GNUNET_SCHEDULER_Task *timeout_task;
-
- /**
- * Function to call for cleanup at the end. Can be NULL.
- */
- GNUNET_SCHEDULER_TaskCallback final_cleanup_cb;
-
- /**
- * Closure for #final_cleanup_cb().
- */
- void *final_cleanup_cb_cls;
-
- /**
- * Instruction pointer. Tells #interpreter_run() which
- * instruction to run next. Need (signed) int because
- * it gets -1 when rewinding the interpreter to the first
- * CMD.
- */
- int ip;
-
- /**
- * Result of the testcases, #GNUNET_OK on success
- */
- int result;
-
- /**
- * Handle to the exchange.
- */
- struct TALER_EXCHANGE_Handle *exchange;
-
- /**
- * Handle to the auditor. NULL unless specifically initialized
- * as part of #TALER_TESTING_auditor_setup().
- */
- struct TALER_AUDITOR_Handle *auditor;
-
- /**
- * Handle to exchange process; some commands need it
- * to send signals. E.g. to trigger the key state reload.
- */
- struct GNUNET_OS_Process *exchanged;
-
- /**
- * GNUNET_OK if key state should be reloaded. NOTE: this
- * field can be removed because a new "send signal" command
- * has been introduced.
- */
- int reload_keys;
-
- /**
- * Is the interpreter running (#GNUNET_YES) or waiting
- * for /keys (#GNUNET_NO)?
- */
- int working;
-
- /**
- * Is the auditor running (#GNUNET_YES) or waiting
- * for /version (#GNUNET_NO)?
- */
- int auditor_working;
-
- /**
- * How often have we gotten a /keys response so far?
- */
- unsigned int key_generation;
-
- /**
- * Exchange keys from last download.
- */
- const struct TALER_EXCHANGE_Keys *keys;
-
-};
+struct TALER_TESTING_Interpreter;
/**
@@ -453,6 +269,11 @@ struct TALER_TESTING_Command
const char *label;
/**
+ * Variable name for the command, NULL for none.
+ */
+ const char *name;
+
+ /**
* Runs the command. Note that upon return, the interpreter
* will not automatically run the next command, as the command
* may continue asynchronously in other scheduler tasks. Thus,
@@ -462,12 +283,12 @@ struct TALER_TESTING_Command
*
* @param cls closure
* @param cmd command being run
- * @param i interpreter state
+ * @param is interpreter state
*/
void
(*run)(void *cls,
const struct TALER_TESTING_Command *cmd,
- struct TALER_TESTING_Interpreter *i);
+ struct TALER_TESTING_Interpreter *is);
/**
@@ -491,7 +312,7 @@ struct TALER_TESTING_Command
* @param index index number of the object to extract.
* @return #GNUNET_OK on success
*/
- int
+ enum GNUNET_GenericReturnValue
(*traits)(void *cls,
const void **ret,
const char *trait,
@@ -534,8 +355,43 @@ const struct TALER_TESTING_Command *
TALER_TESTING_interpreter_lookup_command (struct TALER_TESTING_Interpreter *is,
const char *label);
+
/**
- * Obtain main execution context for the main loop.
+ * Get command from hash map by variable name.
+ *
+ * @param is interpreter state.
+ * @param name name of the variable to get command by
+ * @return the command, if it is found, or NULL.
+ */
+const struct TALER_TESTING_Command *
+TALER_TESTING_interpreter_get_command (struct TALER_TESTING_Interpreter *is,
+ const char *name);
+
+
+/**
+ * Update the last request time of the current command
+ * to the current time.
+ *
+ * @param[in,out] is interpreter state where to show
+ * that we are doing something
+ */
+void
+TALER_TESTING_touch_cmd (struct TALER_TESTING_Interpreter *is);
+
+
+/**
+ * Increment the 'num_tries' counter for the current
+ * command.
+ *
+ * @param[in,out] is interpreter state where to
+ * increment the counter
+ */
+void
+TALER_TESTING_inc_tries (struct TALER_TESTING_Interpreter *is);
+
+
+/**
+ * Obtain CURL context for the main loop.
*
* @param is interpreter state.
* @return CURL execution context.
@@ -543,6 +399,7 @@ TALER_TESTING_interpreter_lookup_command (struct TALER_TESTING_Interpreter *is,
struct GNUNET_CURL_Context *
TALER_TESTING_interpreter_get_context (struct TALER_TESTING_Interpreter *is);
+
/**
* Obtain label of the command being now run.
*
@@ -555,15 +412,6 @@ TALER_TESTING_interpreter_get_current_label (
/**
- * Get connection handle to the fakebank.
- *
- * @param is interpreter state.
- * @return the handle.
- */
-struct TALER_FAKEBANK_Handle *
-TALER_TESTING_interpreter_get_fakebank (struct TALER_TESTING_Interpreter *is);
-
-/**
* Current command is done, run the next one.
*
* @param is interpreter state.
@@ -579,13 +427,20 @@ TALER_TESTING_interpreter_next (struct TALER_TESTING_Interpreter *is);
void
TALER_TESTING_interpreter_fail (struct TALER_TESTING_Interpreter *is);
+
/**
- * Create command array terminator.
+ * Make the instruction pointer point to @a target_label
+ * only if @a counter is greater than zero.
*
- * @return a end-command.
+ * @param label command label
+ * @param target_label label of the new instruction pointer's destination after the jump;
+ * must be before the current instruction
+ * @param counter counts how many times the rewinding is to happen.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_end ();
+TALER_TESTING_cmd_rewind_ip (const char *label,
+ const char *target_label,
+ unsigned int counter);
/**
@@ -628,20 +483,6 @@ TALER_TESTING_run2 (struct TALER_TESTING_Interpreter *is,
/**
- * First launch the fakebank, then schedule the first CMD
- * in the array of all the CMDs to execute.
- *
- * @param is interpreter state.
- * @param commands array of all the commands to execute.
- * @param bank_url base URL of the fake bank.
- */
-void
-TALER_TESTING_run_with_fakebank (struct TALER_TESTING_Interpreter *is,
- struct TALER_TESTING_Command *commands,
- const char *bank_url);
-
-
-/**
* The function that contains the array of all the CMDs to run,
* which is then on charge to call some fashion of
* TALER_TESTING_run*. In all the test cases, this function is
@@ -656,233 +497,212 @@ typedef void
/**
- * Install signal handlers plus schedules the main wrapper
- * around the "run" method.
+ * Run Taler testing loop. Starts the GNUnet SCHEDULER (event loop).
*
- * @param main_cb the "run" method which coontains all the
- * commands.
- * @param main_cb_cls a closure for "run", typically NULL.
- * @param cfg configuration to use
- * @param exchanged exchange process handle: will be put in the
- * state as some commands - e.g. revoke - need to send
- * signal to it, for example to let it know to reload the
- * key state.. if NULL, the interpreter will run without
- * trying to connect to the exchange first.
- * @param exchange_connect GNUNET_YES if the test should connect
- * to the exchange, GNUNET_NO otherwise
- * @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise.
- * non-GNUNET_OK codes are #GNUNET_SYSERR most of the
- * times.
+ * @param main_cb main function to run
+ * @param main_cb_cls closure for @a main_cb
*/
-int
-TALER_TESTING_setup (TALER_TESTING_Main main_cb,
- void *main_cb_cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_OS_Process *exchanged,
- int exchange_connect);
+enum GNUNET_GenericReturnValue
+TALER_TESTING_loop (TALER_TESTING_Main main_cb,
+ void *main_cb_cls);
/**
- * Install signal handlers plus schedules the main wrapper
- * around the "run" method.
+ * Convenience function to run a test.
*
- * @param main_cb the "run" method which contains all the
- * commands.
- * @param main_cb_cls a closure for "run", typically NULL.
- * @param config_filename configuration filename.
- * @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise.
- * non-GNUNET_OK codes are #GNUNET_SYSERR most of the
- * times.
+ * @param argv command-line arguments given
+ * @param loglevel log level to use
+ * @param cfg_file configuration file to use
+ * @param exchange_account_section configuration section
+ * with exchange bank account to use
+ * @param bs bank system to use
+ * @param[in,out] cred global credentials to initialize
+ * @param main_cb main test function to run
+ * @param main_cb_cls closure for @a main_cb
+ * @return 0 on success, 77 on setup trouble, non-zero process status code otherwise
*/
int
-TALER_TESTING_auditor_setup (TALER_TESTING_Main main_cb,
- void *main_cb_cls,
- const char *config_filename);
+TALER_TESTING_main (char *const *argv,
+ const char *loglevel,
+ const char *cfg_file,
+ const char *exchange_account_section,
+ enum TALER_TESTING_BankSystem bs,
+ struct TALER_TESTING_Credentials *cred,
+ TALER_TESTING_Main main_cb,
+ void *main_cb_cls);
/**
- * Closure for #TALER_TESTING_setup_with_exchange_cfg().
+ * Callback over commands of an interpreter.
+ *
+ * @param cls closure
+ * @param cmd a command to process
*/
-struct TALER_TESTING_SetupContext
-{
- /**
- * Main function of the test to run.
- */
- TALER_TESTING_Main main_cb;
-
- /**
- * Closure for @e main_cb.
- */
- void *main_cb_cls;
-
- /**
- * Name of the configuration file.
- */
- const char *config_filename;
-};
+typedef void
+(*TALER_TESTING_CommandIterator)(
+ void *cls,
+ const struct TALER_TESTING_Command *cmd);
/**
- * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the exchange using the given
- * configuration file.
+ * Iterates over all of the top-level commands of an
+ * interpreter.
*
- * @param cls must be a `struct TALER_TESTING_SetupContext *`
- * @param cfg configuration to use.
- * @return #GNUNET_OK if no errors occurred.
+ * @param[in] is interpreter to iterate over
+ * @param asc true in execution order, false for reverse execution order
+ * @param cb function to call on each command
+ * @param cb_cls closure for cb
*/
-int
-TALER_TESTING_setup_with_exchange_cfg (
- void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg);
+void
+TALER_TESTING_iterate (struct TALER_TESTING_Interpreter *is,
+ bool asc,
+ TALER_TESTING_CommandIterator cb,
+ void *cb_cls);
/**
- * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the exchange using the given
- * configuration file.
+ * Look for substring in a programs' name.
*
- * @param main_cb main method.
- * @param main_cb_cls main method closure.
- * @param config_file configuration file name. Is is used
- * by both this function and the exchange itself. In the
- * first case it gives out the exchange port number and
- * the exchange base URL so as to check whether the port
- * is available and the exchange responds when requested
- * at its base URL.
- * @return #GNUNET_OK if no errors occurred.
+ * @param prog program's name to look into
+ * @param marker chunk to find in @a prog
+ * @return true if @a marker is in @a prog
*/
-int
-TALER_TESTING_setup_with_exchange (TALER_TESTING_Main main_cb,
- void *main_cb_cls,
- const char *config_file);
+bool
+TALER_TESTING_has_in_name (const char *prog,
+ const char *marker);
/**
- * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the auditor and exchange using
- * the given configuration file.
+ * Wait for an HTTPD service to have started. Waits for at
+ * most 10s, after that returns 77 to indicate an error.
*
- * @param cls must be a `struct TALER_TESTING_SetupContext *`
- * @param cfg configuration to use.
- * @return #GNUNET_OK if no errors occurred.
+ * @param base_url what URL should we expect the exchange
+ * to be running at
+ * @return 0 on success
*/
int
-TALER_TESTING_setup_with_auditor_and_exchange_cfg (
- void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg);
+TALER_TESTING_wait_httpd_ready (const char *base_url);
/**
- * Initialize scheduler loop and curl context for the test case
- * including starting and stopping the auditor and exchange using
- * the given configuration file.
+ * Parse reference to a coin.
*
- * @param main_cb main method.
- * @param main_cb_cls main method closure.
- * @param config_file configuration file name. Is is used
- * by both this function and the exchange itself. In the
- * first case it gives out the exchange port number and
- * the exchange base URL so as to check whether the port
- * is available and the exchange responds when requested
- * at its base URL.
- * @return #GNUNET_OK if no errors occurred.
+ * @param coin_reference of format $LABEL['#' $INDEX]?
+ * @param[out] cref where we return a copy of $LABEL
+ * @param[out] idx where we set $INDEX
+ * @return #GNUNET_SYSERR if $INDEX is present but not numeric
*/
-int
-TALER_TESTING_setup_with_auditor_and_exchange (TALER_TESTING_Main main_cb,
- void *main_cb_cls,
- const char *config_file);
+enum GNUNET_GenericReturnValue
+TALER_TESTING_parse_coin_reference (
+ const char *coin_reference,
+ char **cref,
+ unsigned int *idx);
+
+
+/* ************** Specific interpreter commands ************ */
/**
- * Start the (Python) bank process. Assume the port
- * is available and the database is clean. Use the "prepare
- * bank" function to do such tasks.
- *
- * @param config_filename configuration filename.
- * @param bank_url base URL of the bank, used by `wget' to check
- * that the bank was started right.
+ * Create command array terminator.
*
- * @return the process, or NULL if the process could not
- * be started.
+ * @return a end-command.
*/
-struct GNUNET_OS_Process *
-TALER_TESTING_run_bank (const char *config_filename,
- const char *bank_url);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_end (void);
+
/**
- * Start the (nexus) bank process. Assume the port
- * is available and the database is clean. Use the "prepare
- * bank" function to do such tasks. This function is also
- * responsible to create the exchange EBICS subscriber at
- * the nexus.
+ * Set variable to command as side-effect of
+ * running a command.
*
- * @param bank_url base URL of the bank, used by `wget' to check
- * that the bank was started right.
- * @return the process, or NULL if the process could not
- * be started.
+ * @param name name of the variable to set
+ * @param cmd command to set to variable when run
+ * @return modified command
*/
-struct GNUNET_OS_Process *
-TALER_TESTING_run_nexus (const struct TALER_TESTING_BankConfiguration *bc);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_set_var (const char *name,
+ struct TALER_TESTING_Command cmd);
+
/**
- * Runs the Fakebank by guessing / extracting the portnumber
- * from the base URL.
+ * Launch GNU Taler setup.
*
- * @param bank_url bank's base URL.
- * @param currency currency the bank uses
- * @return the fakebank process handle, or NULL if any
- * error occurs.
+ * @param label command label.
+ * @param config_file configuration file to use
+ * @param ... NULL-terminated (const char *) arguments to pass to taler-benchmark-setup.sh
+ * @return the command.
*/
-struct TALER_FAKEBANK_Handle *
-TALER_TESTING_run_fakebank (const char *bank_url,
- const char *currency);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_system_start (
+ const char *label,
+ const char *config_file,
+ ...);
/**
- * Prepare the bank execution. Check if the port is available
- * and reset database.
+ * Connects to the exchange.
*
- * @param config_filename configuration file name.
- * @param reset_db should we reset the bank's database
- * @param[out] bc set to the bank's configuration data
- * @return #GNUNET_OK on success
+ * @param label command label
+ * @param cfg configuration to use
+ * @param last_keys_ref reference to command with prior /keys response, NULL for none
+ * @param wait_for_keys block until we got /keys
+ * @param load_private_key obtain private key from file indicated in @a cfg
+ * @return the command.
*/
-int
-TALER_TESTING_prepare_bank (const char *config_filename,
- int reset_db,
- const char *config_section,
- struct TALER_TESTING_BankConfiguration *bc);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_get_exchange (
+ const char *label,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *last_keys_ref,
+ bool wait_for_keys,
+ bool load_private_key);
+
/**
- * Prepare the Nexus execution. Check if the port is available
- * and delete old database.
+ * Connects to the auditor.
*
- * @param config_filename configuration file name.
- * @param reset_db should we reset the bank's database
- * @param config_section section of the configuration with the exchange's account
- * @param[out] bc set to the bank's configuration data
- * @return the base url, or NULL upon errors. Must be freed
- * by the caller.
+ * @param label command label
+ * @param cfg configuration to use
+ * @param load_auditor_keys obtain auditor keys from file indicated in @a cfg
+ * @return the command.
*/
-int
-TALER_TESTING_prepare_nexus (const char *config_filename,
- int reset_db,
- const char *config_section,
- struct TALER_TESTING_BankConfiguration *bc);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_get_auditor (
+ const char *label,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ bool load_auditor_keys);
+
/**
- * Look for substring in a programs' name.
+ * Runs the Fakebank in-process by guessing / extracting the portnumber
+ * from the base URL.
*
- * @param prog program's name to look into
- * @param marker chunk to find in @a prog
+ * @param label command label
+ * @param cfg configuration to use
+ * @param exchange_account_section configuration section
+ * to use to determine bank account of the exchange
+ * @return the command.
*/
-int
-TALER_TESTING_has_in_name (const char *prog,
- const char *marker);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_run_fakebank (
+ const char *label,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *exchange_account_section);
-/* ************** Specific interpreter commands ************ */
+/**
+ * Command to modify authorization header used in the CURL context.
+ * This will destroy the existing CURL context and create a fresh
+ * one. The command will fail (badly) if the existing CURL context
+ * still has active HTTP requests associated with it.
+ *
+ * @param label command label.
+ * @param auth_token auth token to use henceforth, can be NULL
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_set_authorization (const char *label,
+ const char *auth_token);
/**
@@ -926,10 +746,11 @@ TALER_TESTING_cmd_bank_debits (const char *label,
/**
* Create transfer command.
*
- * @param label command label.
- * @param amount amount to transfer.
+ * @param label command label
+ * @param amount amount to transfer
* @param auth authentication data to use
- * @param payto_credit_account which account receives money.
+ * @param payto_debit_account which account to withdraw money from
+ * @param payto_credit_account which account receives money
* @param wtid wire transfer identifier to use
* @param exchange_base_url exchange URL to use
* @return the command.
@@ -945,6 +766,17 @@ TALER_TESTING_cmd_transfer (const char *label,
/**
+ * Modify a transfer command to enable retries when the reserve is not yet
+ * full or we get other transient errors from the bank.
+ *
+ * @param cmd a fakebank transfer command
+ * @return the command with retries enabled
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_transfer_retry (struct TALER_TESTING_Command cmd);
+
+
+/**
* Make the "exec-auditor" CMD.
*
* @param label command label.
@@ -972,24 +804,20 @@ TALER_TESTING_cmd_exec_auditor_dbinit (const char *label,
* Create a "deposit-confirmation" command.
*
* @param label command label.
- * @param auditor auditor connection.
* @param deposit_reference reference to any operation that can
* provide a coin.
- * @param coin_index if @a deposit_reference offers an array of
- * coins, this parameter selects which one in that array.
- * This value is currently ignored, as only one-coin
- * deposits are implemented.
+ * @param num_coins number of coins expected in the batch deposit
* @param amount_without_fee deposited amount without the fee
* @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_deposit_confirmation (const char *label,
- struct TALER_AUDITOR_Handle *auditor,
- const char *deposit_reference,
- unsigned int coin_index,
- const char *amount_without_fee,
- unsigned int expected_response_code);
+TALER_TESTING_cmd_deposit_confirmation (
+ const char *label,
+ const char *deposit_reference,
+ unsigned int num_coins,
+ const char *amount_without_fee,
+ unsigned int expected_response_code);
/**
@@ -1001,53 +829,10 @@ TALER_TESTING_cmd_deposit_confirmation (const char *label,
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_deposit_confirmation_with_retry (
- struct TALER_TESTING_Command
- cmd);
-
-
-/**
- * Create a "list exchanges" command.
- *
- * @param label command label.
- * @param auditor auditor connection.
- * @param expected_response_code expected HTTP response code.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_exchanges (const char *label,
- struct TALER_AUDITOR_Handle *auditor,
- unsigned int expected_response_code);
+ struct TALER_TESTING_Command cmd);
/**
- * Create a "list exchanges" command and check whether
- * a particular exchange belongs to the returned bundle.
- *
- * @param label command label.
- * @param expected_response_code expected HTTP response code.
- * @param exchange_url URL of the exchange supposed to
- * be included in the response.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_exchanges_with_url (const char *label,
- unsigned int expected_response_code,
- const char *exchange_url);
-
-/**
- * Modify an exchanges command to enable retries when we get
- * transient errors from the auditor.
- *
- * @param cmd a deposit confirmation command
- * @return the command with retries enabled
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_exchanges_with_retry (struct TALER_TESTING_Command cmd);
-
-
-/* ***** Commands ONLY for testing (/admin-API) **** */
-
-/**
* Create /admin/add-incoming command.
*
* @param label command label.
@@ -1075,7 +860,8 @@ TALER_TESTING_cmd_admin_add_incoming (
* @param payto_debit_account which account sends money.
* @param auth authentication data
* @param ref reference to a command that can offer a reserve
- * private key.
+ * private key or public key.
+ * @param http_status expected HTTP status
* @return the command.
*/
struct TALER_TESTING_Command
@@ -1084,35 +870,8 @@ TALER_TESTING_cmd_admin_add_incoming_with_ref (
const char *amount,
const struct TALER_BANK_AuthenticationData *auth,
const char *payto_debit_account,
- const char *ref);
-
-
-/**
- * Create "fakebank transfer" CMD, letting the caller specifying
- * the merchant instance. This version is useful when a tip
- * reserve should be topped up, in fact the interpreter will need
- * the "tipping instance" in order to get the instance public key
- * and make a wire transfer subject out of it.
- *
- * @param label command label.
- * @param amount amount to transfer.
- * @param payto_debit_account which account sends money.
- * @param auth authentication data
- * @param instance the instance that runs the tipping. Under this
- * instance, the configuration file will provide the private
- * key of the tipping reserve. This data will then used to
- * construct the wire transfer subject line.
- * @param config_filename configuration file to use.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_admin_add_incoming_with_instance (
- const char *label,
- const char *amount,
- const struct TALER_BANK_AuthenticationData *auth,
- const char *payto_debit_account,
- const char *instance,
- const char *config_filename);
+ const char *ref,
+ unsigned int http_status);
/**
@@ -1132,15 +891,65 @@ TALER_TESTING_cmd_admin_add_incoming_retry (struct TALER_TESTING_Command cmd);
*
* @param label command label.
* @param config_filename configuration filename.
- *
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_exec_wirewatch (const char *label,
const char *config_filename);
+
+/**
+ * Make a "wirewatch" CMD.
+ *
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @param account_section section to run wirewatch against
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_wirewatch2 (const char *label,
+ const char *config_filename,
+ const char *account_section);
+
+
+/**
+ * Request URL via "wget".
+ *
+ * @param label command label.
+ * @param url URL to fetch
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_wget (const char *label,
+ const char *url);
+
+
+/**
+ * Make a "expire" CMD.
+ *
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_expire (const char *label,
+ const char *config_filename);
+
+
+/**
+ * Make a "router" CMD.
+ *
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_router (const char *label,
+ const char *config_filename);
+
+
/**
- * Make a "aggregator" CMD.
+ * Run a "taler-exchange-aggregator" CMD.
*
* @param label command label.
* @param config_filename configuration file for the
@@ -1153,6 +962,32 @@ TALER_TESTING_cmd_exec_aggregator (const char *label,
/**
+ * Run a "taler-auditor-offline" CMD.
+ *
+ * @param label command label.
+ * @param config_filename configuration file for the
+ * aggregator to use.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_auditor_offline (const char *label,
+ const char *config_filename);
+
+
+/**
+ * Make a "aggregator" CMD and do not disable KYC checks.
+ *
+ * @param label command label.
+ * @param config_filename configuration file for the
+ * aggregator to use.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_aggregator_with_kyc (const char *label,
+ const char *config_filename);
+
+
+/**
* Make a "closer" CMD. Note that it is right now not supported to run the
* closer to close multiple reserves in combination with a subsequent reserve
* status call, as we cannot generate the traits necessary for multiple closed
@@ -1190,81 +1025,145 @@ TALER_TESTING_cmd_exec_transfer (const char *label,
/**
- * Make the "keyup" CMD.
+ * Create a withdraw command, letting the caller specify
+ * the desired amount as string.
*
* @param label command label.
- * @param config_filename configuration filename.
- * @return the command.
+ * @param reserve_reference command providing us with a reserve to withdraw from
+ * @param amount how much we withdraw.
+ * @param age if > 0, age restriction applies
+ * @param expected_response_code which HTTP response code
+ * we expect from the exchange.
+ * @return the withdraw command to be executed by the interpreter.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_exec_keyup (const char *label,
- const char *config_filename);
+TALER_TESTING_cmd_withdraw_amount (const char *label,
+ const char *reserve_reference,
+ const char *amount,
+ uint8_t age,
+ unsigned int expected_response_code);
/**
- * Make the "keyup" CMD, with "--timestamp" option.
+ * Create a batch withdraw command, letting the caller specify the type of
+ * conflict between the coins and the desired amounts as string.
+ *
+ * Takes a variable, non-empty list of the denomination amounts via VARARGS,
+ * similar to #TALER_TESTING_cmd_withdraw_amount(), just using a batch
+ * withdraw.
*
* @param label command label.
- * @param config_filename configuration filename.
- * @param now Unix timestamp representing the fake "now".
- * @return the command.
+ * @param reserve_reference command providing us with a reserve to withdraw from
+ * @param conflict if true, enforce a conflict (same priv key, different denom and age commiment)
+ * @param age if > 0, age restriction applies (same for all coins)
+ * @param expected_response_code which HTTP response code
+ * we expect from the exchange.
+ * @param amount how much we withdraw for the first coin
+ * @param ... NULL-terminated list of additional amounts to withdraw (one per coin)
+ * @return the withdraw command to be executed by the interpreter.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_exec_keyup_with_now (const char *label,
- const char *config_filename,
- struct GNUNET_TIME_Absolute now);
-
+TALER_TESTING_cmd_batch_withdraw_with_conflict (
+ const char *label,
+ const char *reserve_reference,
+ bool conflict,
+ uint8_t age,
+ unsigned int expected_response_code,
+ const char *amount,
+ ...);
/**
- * Make a "check keys" command. This type of command
- * checks whether the number of denomination keys from
- * @a exchange matches @a num_denom_keys.
+ * Create a batch withdraw command, letting the caller specify
+ * the desired amounts as string. Takes a variable, non-empty
+ * list of the denomination amounts via VARARGS, similar to
+ * #TALER_TESTING_cmd_withdraw_amount(), just using a batch withdraw.
+ * The coins are generated without a conflict (different private keys).
*
- * @param label command label
- * @param generation when this command is run, exactly @a
- * generation /keys downloads took place. If the number
- * of downloads is less than @a generation, the logic will
- * first make sure that @a generation downloads are done,
- * and _then_ execute the rest of the command.
- * @param num_denom_keys expected number of denomination keys.
- * @param now timestamp to use when fetching keys
- * @return the command.
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw from
+ * @param age if > 0, age restriction applies (same for all coins)
+ * @param expected_response_code which HTTP response code
+ * we expect from the exchange.
+ * @param amount how much we withdraw for the first coin
+ * @param ... NULL-terminated list of additional amounts to withdraw (one per coin)
+ * @return the withdraw command to be executed by the interpreter.
+ */
+#define TALER_TESTING_cmd_batch_withdraw(label, \
+ reserve_reference, \
+ age, \
+ expected_response_code, \
+ amount, \
+ ...) \
+ TALER_TESTING_cmd_batch_withdraw_with_conflict ( \
+ (label), \
+ (reserve_reference), \
+ false, \
+ (age), \
+ (expected_response_code), \
+ (amount), \
+ __VA_ARGS__)
+
+/**
+ * Create an age-withdraw command, letting the caller specify
+ * the maximum agend and desired amounts as string. Takes a variable,
+ * non-empty list of the denomination amounts via VARARGS, similar to
+ * #TALER_TESTING_cmd_withdraw_amount(), just using a batch withdraw.
+ *
+ * @param label command label.
+ * @param reserve_reference command providing us with a reserve to withdraw from
+ * @param max_age maximum allowed age, same for each coin
+ * @param expected_response_code which HTTP response code
+ * we expect from the exchange.
+ * @param amount how much we withdraw for the first coin
+ * @param ... NULL-terminated list of additional amounts to withdraw (one per coin)
+ * @return the withdraw command to be executed by the interpreter.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_check_keys_with_now (const char *label,
- unsigned int generation,
- unsigned int num_denom_keys,
- struct GNUNET_TIME_Absolute now);
-
+TALER_TESTING_cmd_age_withdraw (const char *label,
+ const char *reserve_reference,
+ uint8_t max_age,
+ unsigned int expected_response_code,
+ const char *amount,
+ ...);
/**
- * Make a "auditor sign" CMD.
+ * Create a "age-withdraw reveal" command.
*
- * @param label command label
- * @param config_filename configuration filename
+ * @param label command label.
+ * @param age_withdraw_reference reference to a "age-withdraw" command.
+ * @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_exec_auditor_sign (const char *label,
- const char *config_filename);
-
+TALER_TESTING_cmd_age_withdraw_reveal (
+ const char *label,
+ const char *age_withdraw_reference,
+ unsigned int expected_response_code);
/**
* Create a withdraw command, letting the caller specify
- * the desired amount as string.
+ * the desired amount as string and also re-using an existing
+ * coin private key in the process (violating the specification,
+ * which will result in an error when spending the coin!).
*
* @param label command label.
* @param reserve_reference command providing us with a reserve to withdraw from
* @param amount how much we withdraw.
+ * @param age if > 0, age restriction applies.
+ * @param coin_ref reference to (withdraw/reveal) command of a coin
+ * from which we should reuse the private key
* @param expected_response_code which HTTP response code
* we expect from the exchange.
* @return the withdraw command to be executed by the interpreter.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_withdraw_amount (const char *label,
- const char *reserve_reference,
- const char *amount,
- unsigned int expected_response_code);
+TALER_TESTING_cmd_withdraw_amount_reuse_key (
+ const char *label,
+ const char *reserve_reference,
+ const char *amount,
+ uint8_t age,
+ const char *coin_ref,
+ unsigned int expected_response_code);
/**
@@ -1299,37 +1198,155 @@ TALER_TESTING_cmd_withdraw_with_retry (struct TALER_TESTING_Command cmd);
/**
- * Create a "wire" command.
+ * Create a GET "reserves" command.
*
* @param label the command label.
- * @param expected_method which wire-transfer method is expected
- * to be offered by the exchange.
- * @param expected_fee the fee the exchange should charge.
- * @param expected_response_code the HTTP response the exchange
- * should return.
+ * @param reserve_reference reference to the reserve to check.
+ * @param expected_balance expected balance for the reserve.
+ * @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_wire (const char *label,
- const char *expected_method,
- const char *expected_fee,
- unsigned int expected_response_code);
+TALER_TESTING_cmd_status (const char *label,
+ const char *reserve_reference,
+ const char *expected_balance,
+ unsigned int expected_response_code);
/**
- * Create a GET "reserves" command.
+ * Create a GET "reserves" command with a @a timeout.
*
* @param label the command label.
* @param reserve_reference reference to the reserve to check.
* @param expected_balance expected balance for the reserve.
+ * @param timeout how long to long-poll for the reserve to exist.
* @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_status (const char *label,
- const char *reserve_reference,
- const char *expected_balance,
- unsigned int expected_response_code);
+TALER_TESTING_cmd_reserve_poll (const char *label,
+ const char *reserve_reference,
+ const char *expected_balance,
+ struct GNUNET_TIME_Relative timeout,
+ unsigned int expected_response_code);
+
+
+/**
+ * Wait for #TALER_TESTING_cmd_reserve_poll() to finish.
+ * Fail if it did not conclude by the timeout.
+ *
+ * @param label our label
+ * @param timeout how long to give the long poll to finish
+ * @param poll_reference reference to a #TALER_TESTING_cmd_reserve_poll() command
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_poll_finish (const char *label,
+ struct GNUNET_TIME_Relative timeout,
+ const char *poll_reference);
+
+
+/**
+ * Create a GET "/reserves/$RID/history" command.
+ *
+ * @param label the command label.
+ * @param reserve_reference reference to the reserve to check.
+ * @param expected_balance expected balance for the reserve.
+ * @param expected_response_code expected HTTP response code.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_history (const char *label,
+ const char *reserve_reference,
+ const char *expected_balance,
+ unsigned int expected_response_code);
+
+
+/**
+ * Create a GET "/coins/$COIN_PUB/history" command.
+ *
+ * @param label the command label.
+ * @param coin_reference reference to the coin to check.
+ * @param expected_balance expected balance for the coin.
+ * @param expected_response_code expected HTTP response code.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_coin_history (const char *label,
+ const char *coin_reference,
+ const char *expected_balance,
+ unsigned int expected_response_code);
+
+
+/**
+ * Create a POST "/reserves/$RID/open" command.
+ *
+ * @param label the command label.
+ * @param reserve_reference reference to the reserve to open.
+ * @param reserve_pay amount to pay from the reserve balance
+ * @param expiration_time how long into the future should the reserve remain open
+ * @param min_purses minimum number of purses to allow
+ * @param expected_response_code expected HTTP response code.
+ * @param ... NULL terminated list of pairs of coin references and amounts
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_open (const char *label,
+ const char *reserve_reference,
+ const char *reserve_pay,
+ struct GNUNET_TIME_Relative expiration_time,
+ uint32_t min_purses,
+ unsigned int expected_response_code,
+ ...);
+
+
+/**
+ * Create a GET "/reserves/$RID/attest" command.
+ *
+ * @param label the command label.
+ * @param reserve_reference reference to the reserve to get attestable attributes of.
+ * @param expected_response_code expected HTTP response code.
+ * @param ... NULL-terminated list of attributes expected
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_get_attestable (const char *label,
+ const char *reserve_reference,
+ unsigned int expected_response_code,
+ ...);
+
+
+/**
+ * Create a POST "/reserves/$RID/attest" command.
+ *
+ * @param label the command label.
+ * @param reserve_reference reference to the reserve to get attests for
+ * @param expected_response_code expected HTTP response code.
+ * @param ... NULL-terminated list of attributes that should be attested
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_attest (const char *label,
+ const char *reserve_reference,
+ unsigned int expected_response_code,
+ ...);
+
+
+/**
+ * Create a POST "/reserves/$RID/close" command.
+ *
+ * @param label the command label.
+ * @param reserve_reference reference to the reserve to close.
+ * @param target_account where to wire funds remaining, can be NULL
+ * @param expected_response_code expected HTTP response code.
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_reserve_close (const char *label,
+ const char *reserve_reference,
+ const char *target_account,
+ unsigned int expected_response_code);
+
/**
* Create a "deposit" command.
@@ -1422,6 +1439,31 @@ TALER_TESTING_cmd_deposit_replay (const char *label,
/**
+ * Create a "batch deposit" command.
+ *
+ * @param label command label.
+ * @param target_account_payto target account for the "deposit"
+ * request.
+ * @param contract_terms contract terms to be signed over by the
+ * coin.
+ * @param refund_deadline refund deadline, zero means 'no refunds'.
+ * @param expected_response_code expected HTTP response code.
+ * @param ... NULL-terminated list with an even number of
+ * strings that alternate referring to coins
+ * (possibly with index using label#index notation)
+ * and the amount of that coin to deposit
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_batch_deposit (const char *label,
+ const char *target_account_payto,
+ const char *contract_terms,
+ struct GNUNET_TIME_Relative refund_deadline,
+ unsigned int expected_response_code,
+ ...);
+
+
+/**
* Create a "refresh melt" command.
*
* @param label command label.
@@ -1526,7 +1568,6 @@ TALER_TESTING_cmd_refresh_link_with_retry (struct TALER_TESTING_Command cmd);
* @param bank_transfer_reference reference to a command that
* can offer a WTID so as to check that against what WTID
* the tracked operation has. Set as NULL if not needed.
- *
* @return the command.
*/
struct TALER_TESTING_Command
@@ -1547,15 +1588,12 @@ TALER_TESTING_cmd_track_transaction (const char *label,
* a wtid. If NULL is given, then a all zeroed WTID is
* used that will at 99.9999% probability NOT match any
* existing WTID known to the exchange.
- * @param index index number of the WTID to track, in case there
- * are multiple on offer.
* @param expected_response_code expected HTTP response code.
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_track_transfer_empty (const char *label,
const char *wtid_reference,
- unsigned int index,
unsigned int expected_response_code);
@@ -1566,8 +1604,6 @@ TALER_TESTING_cmd_track_transfer_empty (const char *label,
* @param label the command label.
* @param wtid_reference reference to any command which can provide
* a wtid. Will be the one tracked.
- * @param index in case there are multiple WTID offered, this
- * parameter selects a particular one.
* @param expected_response_code expected HTTP response code.
* @param expected_total_amount how much money we expect being moved
* with this wire-transfer.
@@ -1577,11 +1613,11 @@ TALER_TESTING_cmd_track_transfer_empty (const char *label,
struct TALER_TESTING_Command
TALER_TESTING_cmd_track_transfer (const char *label,
const char *wtid_reference,
- unsigned int index,
unsigned int expected_response_code,
const char *expected_total_amount,
const char *expected_wire_fee);
+
/**
* Make a "bank check" CMD. It checks whether a particular wire transfer from
* the exchange (debit) has been made or not.
@@ -1656,20 +1692,17 @@ TALER_TESTING_cmd_check_bank_empty (const char *label);
* @param label command label.
* @param expected_response_code expected HTTP status code.
* @param refund_amount the amount to ask a refund for.
- * @param refund_fee expected refund fee.
* @param coin_reference reference to a command that can
* provide a coin to be refunded.
* @param refund_transaction_id transaction id to use
* in the request.
- *
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_refund_with_id (const char *label,
unsigned int expected_response_code,
const char *refund_amount,
- const char *refund_fee,
- const char *deposit_reference,
+ const char *coin_reference,
uint64_t refund_transaction_id);
@@ -1679,18 +1712,15 @@ TALER_TESTING_cmd_refund_with_id (const char *label,
* @param label command label.
* @param expected_response_code expected HTTP status code.
* @param refund_amount the amount to ask a refund for.
- * @param refund_fee expected refund fee.
* @param coin_reference reference to a command that can
* provide a coin to be refunded.
- *
* @return the command.
*/
struct TALER_TESTING_Command
TALER_TESTING_cmd_refund (const char *label,
unsigned int expected_response_code,
const char *refund_amount,
- const char *refund_fee,
- const char *deposit_reference);
+ const char *coin_reference);
/**
@@ -1702,7 +1732,6 @@ TALER_TESTING_cmd_refund (const char *label,
* offers a coin and reserve private key. May specify
* the index of the coin using "$LABEL#$INDEX" syntax.
* Here, $INDEX must be a non-negative number.
- * @param melt_reference NULL if coin was not refreshed, otherwise label of the melt operation
* @param amount how much do we expect to recoup, NULL for nothing
* @return the command.
*/
@@ -1710,11 +1739,31 @@ struct TALER_TESTING_Command
TALER_TESTING_cmd_recoup (const char *label,
unsigned int expected_response_code,
const char *coin_reference,
- const char *melt_reference,
const char *amount);
/**
+ * Make a "recoup-refresh" command.
+ *
+ * @param label the command label
+ * @param expected_response_code expected HTTP status code
+ * @param coin_reference reference to any command which
+ * offers a coin and reserve private key. May specify
+ * the index of the coin using "$LABEL#$INDEX" syntax.
+ * Here, $INDEX must be a non-negative number.
+ * @param melt_reference label of the melt operation
+ * @param amount how much do we expect to recoup, NULL for nothing
+ * @return the command.
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_recoup_refresh (const char *label,
+ unsigned int expected_response_code,
+ const char *coin_reference,
+ const char *melt_reference,
+ const char *amount);
+
+
+/**
* Make a "revoke" command.
*
* @param label the command label.
@@ -1770,71 +1819,6 @@ struct TALER_TESTING_Command
TALER_TESTING_cmd_wait_service (const char *label,
const char *url);
-
-/**
- * Make a "check keys" command. This type of command
- * checks whether the number of denomination keys from
- * @a exchange matches @a num_denom_keys.
- *
- * @param label command label
- * @param generation how many /keys responses are expected to
- * have been returned when this CMD will be run.
- * @param num_denom_keys expected number of denomination keys.
- *
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_check_keys (const char *label,
- unsigned int generation,
- unsigned int num_denom_keys);
-
-
-/**
- * Make a "check keys" command that forcedly does NOT cherry pick;
- * just redownload the whole /keys. Then checks whether the number
- * of denomination keys from @a exchange matches @a num_denom_keys.
- *
- * @param label command label
- * @param generation when this command is run, exactly @a
- * generation /keys downloads took place. If the number
- * of downloads is less than @a generation, the logic will
- * first make sure that @a generation downloads are done,
- * and _then_ execute the rest of the command.
- * @param num_denom_keys expected number of denomination keys.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_check_keys_pull_all_keys (const char *label,
- unsigned int generation,
- unsigned int num_denom_keys);
-
-
-/**
- * Make a "check keys" command. This type of command
- * checks whether the number of denomination keys from
- * @a exchange matches @a num_denom_keys. Additionally,
- * it lets the user set a last denom issue date to be
- * used in the request for /keys.
- *
- * @param label command label
- * @param generation when this command is run, exactly @a
- * generation /keys downloads took place. If the number
- * of downloads is less than @a generation, the logic will
- * first make sure that @a generation downloads are done,
- * and _then_ execute the rest of the command.
- * @param num_denom_keys expected number of denomination keys.
- * @param last_denom_date date to be set in the "last_denom_issue"
- * URL parameter of /keys.
- * @return the command.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_check_keys_with_last_denom (const char *label,
- unsigned int generation,
- unsigned int num_denom_keys,
- struct GNUNET_TIME_Absolute
- last_denom_date);
-
-
/**
* Create a "batch" command. Such command takes a
* end_CMD-terminated array of CMDs and executed them.
@@ -1857,16 +1841,21 @@ TALER_TESTING_cmd_batch (const char *label,
*
* @return false if not, true if it is a batch command
*/
-int
+bool
TALER_TESTING_cmd_is_batch (const struct TALER_TESTING_Command *cmd);
+
/**
* Advance internal pointer to next command.
*
* @param is interpreter state.
+ * @param[in,out] cls closure of the batch
+ * @return true to advance IP in parent
*/
-void
-TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is);
+bool
+TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is,
+ void *cls);
+
/**
* Obtain what command the batch is at.
@@ -1876,37 +1865,26 @@ TALER_TESTING_cmd_batch_next (struct TALER_TESTING_Interpreter *is);
struct TALER_TESTING_Command *
TALER_TESTING_cmd_batch_get_current (const struct TALER_TESTING_Command *cmd);
-/**
- * Make a serialize-keys CMD.
- *
- * @param label CMD label
- * @return the CMD.
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_serialize_keys (const char *label);
-
/**
- * Make a connect-with-state CMD. This command
- * will use a serialized key state to reconnect
- * to the exchange.
+ * Set what command the batch should be at.
*
- * @param label command label
- * @param state_reference label of a CMD offering
- * a serialized key state.
- * @return the CMD.
+ * @param cmd current batch command
+ * @param new_ip where to move the IP
*/
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_connect_with_state (const char *label,
- const char *state_reference);
+void
+TALER_TESTING_cmd_batch_set_current (const struct TALER_TESTING_Command *cmd,
+ unsigned int new_ip);
+
/**
* Make the "insert-deposit" CMD.
*
* @param label command label.
- * @param dbc collects plugin and session handles
+ * @param db_cfg configuration to talk to the DB
* @param merchant_name Human-readable name of the merchant.
* @param merchant_account merchant's account name (NOT a payto:// URI)
+ * @param exchange_timestamp when did the exchange receive the deposit
* @param wire_deadline point in time where the aggregator should have
* wired money to the merchant.
* @param amount_with_fee amount to deposit (inclusive of deposit fee)
@@ -1914,14 +1892,15 @@ TALER_TESTING_cmd_connect_with_state (const char *label,
* @return the command.
*/
struct TALER_TESTING_Command
-TALER_TESTING_cmd_insert_deposit (const char *label,
- const struct
- TALER_TESTING_DatabaseConnection *dbc,
- const char *merchant_name,
- const char *merchant_account,
- struct GNUNET_TIME_Relative wire_deadline,
- const char *amount_with_fee,
- const char *deposit_fee);
+TALER_TESTING_cmd_insert_deposit (
+ const char *label,
+ const struct GNUNET_CONFIGURATION_Handle *db_cfg,
+ const char *merchant_name,
+ const char *merchant_account,
+ struct GNUNET_TIME_Timestamp exchange_timestamp,
+ struct GNUNET_TIME_Relative wire_deadline,
+ const char *amount_with_fee,
+ const char *deposit_fee);
/**
@@ -1940,7 +1919,7 @@ struct TALER_TESTING_Timer
struct GNUNET_TIME_Relative total_duration;
/**
- * Total time spend waiting for the *successful* exeuction
+ * Total time spend waiting for the *successful* execution
* in all commands of this type.
*/
struct GNUNET_TIME_Relative success_latency;
@@ -1967,877 +1946,792 @@ struct TALER_TESTING_Command
TALER_TESTING_cmd_stat (struct TALER_TESTING_Timer *timers);
-/* *** Generic trait logic for implementing traits ********* */
-
-/**
- * A trait.
- */
-struct TALER_TESTING_Trait
-{
- /**
- * Index number associated with the trait. This gives the
- * possibility to have _multiple_ traits on offer under the
- * same name.
- */
- unsigned int index;
-
- /**
- * Trait type, for example "reserve-pub" or "coin-priv".
- */
- const char *trait_name;
-
- /**
- * Pointer to the piece of data to offer.
- */
- const void *ptr;
-};
-
-
-/**
- * "end" trait. Because traits are offered into arrays,
- * this type of trait is used to mark the end of such arrays;
- * useful when iterating over those.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_trait_end (void);
-
-
/**
- * Extract a trait.
+ * Add the auditor to the exchange's list of auditors.
+ * The information about the auditor is taken from the
+ * "[auditor]" section in the configuration file.
*
- * @param traits the array of all the traits.
- * @param[out] ret where to store the result.
- * @param trait type of the trait to extract.
- * @param index index number of the trait to extract.
- * @return #GNUNET_OK when the trait is found.
- */
-int
-TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
- const void **ret,
- const char *trait,
- unsigned int index);
-
-
-/* ****** Specific traits supported by this component ******* */
-
-
-/**
- * Obtain a bank transaction row value from @a cmd.
- *
- * @param cmd command to extract the number from.
- * @param[out] row set to the number coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_bank_row (const struct TALER_TESTING_Command *cmd,
- const uint64_t **row);
-
-
-/**
- * Offer bank transaction row trait.
- *
- * @param row number to offer.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_bank_row (const uint64_t *row);
-
-
-/**
- * Offer a reserve private key.
- *
- * @param index reserve priv's index number.
- * @param reserve_priv reserve private key to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_reserve_priv (
- unsigned int index,
- const struct TALER_ReservePrivateKeyP *reserve_priv);
-
-
-/**
- * Obtain a reserve private key from a @a cmd.
- *
- * @param cmd command to extract the reserve priv from.
- * @param index reserve priv's index number.
- * @param[out] reserve_priv set to the reserve priv.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_reserve_priv (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_ReservePrivateKeyP **reserve_priv);
-
-
-/**
- * Offer a reserve public key.
- *
- * @param index reserve pubs's index number.
- * @param reserve_pub reserve public key to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_reserve_pub (
- unsigned int index,
- const struct TALER_ReservePublicKeyP *reserve_pub);
-
-
-/**
- * Obtain a reserve public key from a @a cmd.
- *
- * @param cmd command to extract the reserve pub from.
- * @param index reserve pub's index number.
- * @param[out] reserve_pub set to the reserve pub.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param expected_http_status expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_reserve_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_ReservePublicKeyP **reserve_pub);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_auditor_add (const char *label,
+ unsigned int expected_http_status,
+ bool bad_sig);
/**
- * Offer a reserve history entry.
+ * Remove the auditor from the exchange's list of auditors.
+ * The information about the auditor is taken from the
+ * "[auditor]" section in the configuration file.
*
- * @param index reserve pubs's index number.
- * @param rh reserve history entry to offer.
- * @return the trait.
+ * @param label command label.
+ * @param expected_http_status expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_reserve_history (
- unsigned int index,
- const struct TALER_EXCHANGE_ReserveHistory *rh);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_auditor_del (const char *label,
+ unsigned int expected_http_status,
+ bool bad_sig);
/**
- * Obtain a reserve history entry from a @a cmd.
+ * Add affirmation that the auditor is auditing the given
+ * denomination.
+ * The information about the auditor is taken from the
+ * "[auditor]" section in the configuration file.
*
- * @param cmd command to extract the reserve history from.
- * @param index reserve history's index number.
- * @param[out] rhp set to the reserve history.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param expected_http_status expected HTTP status from exchange
+ * @param denom_ref reference to a command identifying a denomination key
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_reserve_history (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_EXCHANGE_ReserveHistory **rhp);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_auditor_add_denom_sig (const char *label,
+ unsigned int expected_http_status,
+ const char *denom_ref,
+ bool bad_sig);
/**
- * Make a trait for a exchange signature.
- *
- * @param index index number to associate to the offered exchange pub.
- * @param exchange_sig exchange signature to offer with this trait.
+ * Add statement about wire fees of the exchange. This is always
+ * done for a few hours around the current time (for the test).
*
- * @return the trait.
+ * @param label command label.
+ * @param wire_method wire method to set wire fees for
+ * @param wire_fee the wire fee to affirm
+ * @param closing_fee the closing fee to affirm
+ * @param expected_http_status expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_exchange_sig (
- unsigned int index,
- const struct TALER_ExchangeSignatureP *exchange_sig);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_set_wire_fee (const char *label,
+ const char *wire_method,
+ const char *wire_fee,
+ const char *closing_fee,
+ unsigned int expected_http_status,
+ bool bad_sig);
/**
- * Obtain a exchange signature (online sig) from a @a cmd.
+ * Add the given payto-URI bank account to the list of bank
+ * accounts used by the exchange.
*
- * @param cmd command to extract trait from
- * @param index index number of the exchange to obtain.
- * @param[out] exchange_sig set to the offered exchange signature.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param payto_uri URI identifying the bank account
+ * @param expected_http_status expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_exchange_sig (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_ExchangeSignatureP **exchange_sig);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wire_add (const char *label,
+ const char *payto_uri,
+ unsigned int expected_http_status,
+ bool bad_sig);
/**
- * Make a trait for a exchange public key.
+ * Remove the given payto-URI bank account from the list of bank
+ * accounts used by the exchange.
*
- * @param index index number to associate to the offered exchange pub.
- * @param exchange_pub exchange pub to offer with this trait.
- *
- * @return the trait.
+ * @param label command label.
+ * @param payto_uri URI identifying the bank account
+ * @param expected_http_status expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_exchange_pub (
- unsigned int index,
- const struct TALER_ExchangePublicKeyP *exchange_pub);
-
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wire_del (const char *label,
+ const char *payto_uri,
+ unsigned int expected_http_status,
+ bool bad_sig);
/**
- * Obtain a exchange public key from a @a cmd.
+ * Sign all extensions that the exchange has to offer, f. e. the extension for
+ * age restriction. This has to be run before any withdrawal of age restricted
+ * can be performed.
*
- * @param cmd command to extract trait from
- * @param index index number of the exchange to obtain.
- * @param[out] exchange_pub set to the offered exchange pub.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_exchange_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_ExchangePublicKeyP **exchange_pub);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_offline_sign_extensions (const char *label,
+ const char *config_filename);
/**
- * Obtain location where a command stores a pointer to a process.
+ * Sign all exchange denomination and online signing keys
+ * with the "offline" key and provide those signatures to
+ * the exchange. (Downloads the keys, makes the signature
+ * and uploads the result, all in one.)
*
- * @param cmd command to extract trait from.
- * @param index which process to pick if @a cmd
- * has multiple on offer.
- * @param[out] processp set to the address of the pointer to the
- * process.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_process (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- struct GNUNET_OS_Process ***processp);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_offline_sign_keys (const char *label,
+ const char *config_filename);
/**
- * Offer location where a command stores a pointer to a process.
+ * Sign a wire fee structure.
*
- * @param index offered location index number, in case there are
- * multiple on offer.
- * @param processp process location to offer.
- * @return the trait.
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @param wire_fee the wire fee to affirm (for the current year)
+ * @param closing_fee the closing fee to affirm (for the current year)
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_process (unsigned int index,
- struct GNUNET_OS_Process **processp);
-
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_offline_sign_fees (const char *label,
+ const char *config_filename,
+ const char *wire_fee,
+ const char *closing_fee);
-/**
- * Offer coin private key.
- *
- * @param index index number to associate with offered coin priv.
- * @param coin_priv coin private key to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_coin_priv (
- unsigned int index,
- const struct TALER_CoinSpendPrivateKeyP *coin_priv);
/**
- * Obtain a coin private key from a @a cmd.
+ * Sign global fee structure.
*
- * @param cmd command to extract trait from.
- * @param index index of the coin priv to obtain.
- * @param[out] coin_priv set to the private key of the coin.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param config_filename configuration filename.
+ * @param history_fee the history fee to charge (for the current year)
+ * @param account_fee the account fee to charge (for the current year)
+ * @param purse_fee the purse fee to charge (for the current year)
+ * @param purse_timeout when do purses time out
+ * @param history_expiration when does an account history expire
+ * @param num_purses number of (free) active purses per account
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_coin_priv (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_CoinSpendPrivateKeyP **coin_priv);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_exec_offline_sign_global_fees (
+ const char *label,
+ const char *config_filename,
+ const char *history_fee,
+ const char *account_fee,
+ const char *purse_fee,
+ struct GNUNET_TIME_Relative purse_timeout,
+ struct GNUNET_TIME_Relative history_expiration,
+ unsigned int num_purses);
/**
- * Offer blinding key.
+ * Revoke an exchange denomination key.
*
- * @param index index number to associate to the offered key.
- * @param blinding_key blinding key to offer.
- * @return the trait.
+ * @param label command label.
+ * @param expected_response_code expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @param denom_ref reference to a command that identifies
+ * a denomination key (i.e. because it was used to
+ * withdraw a coin).
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_blinding_key (
- unsigned int index,
- const struct TALER_DenominationBlindingKeyP *blinding_key);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_revoke_denom_key (
+ const char *label,
+ unsigned int expected_response_code,
+ bool bad_sig,
+ const char *denom_ref);
/**
- * Obtain a blinding key from a @a cmd.
+ * Revoke an exchange online signing key.
*
- * @param cmd command to extract trait from
- * @param index which coin to pick if @a cmd has multiple on offer.
- * @param[out] blinding_key set to the offered blinding key.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param expected_response_code expected HTTP status from exchange
+ * @param bad_sig should we use a bogus signature?
+ * @param signkey_ref reference to a command that identifies
+ * a signing key (i.e. because it was used to
+ * sign a deposit confirmation).
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_blinding_key (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_DenominationBlindingKeyP **blinding_key);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_revoke_sign_key (
+ const char *label,
+ unsigned int expected_response_code,
+ bool bad_sig,
+ const char *signkey_ref);
/**
- * Make a trait for a denomination public key.
+ * Create a request for a wallet's KYC UUID.
*
- * @param index index number to associate to the offered denom pub.
- * @param denom_pub denom pub to offer with this trait.
- * @return the trait.
+ * @param label command label.
+ * @param reserve_reference command with reserve private key to use (or NULL to create a fresh reserve key).
+ * @param threshold_balance balance amount to pass to the exchange
+ * @param expected_response_code expected HTTP status
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_denom_pub (
- unsigned int index,
- const struct TALER_EXCHANGE_DenomPublicKey *dpk);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_wallet_kyc_get (const char *label,
+ const char *reserve_reference,
+ const char *threshold_balance,
+ unsigned int expected_response_code);
/**
- * Obtain a denomination public key from a @a cmd.
+ * Create a request for an account's KYC status.
*
- * @param cmd command to extract trait from
- * @param index index number of the denom to obtain.
- * @param[out] denom_pub set to the offered denom pub.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param payment_target_reference command with a payment target to query
+ * @param expected_response_code expected HTTP status
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_denom_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_EXCHANGE_DenomPublicKey **dpk);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_kyc_get (const char *label,
+ const char *payment_target_reference,
+ unsigned int expected_response_code);
/**
- * Obtain a denomination signature from a @a cmd.
+ * Create a KYC proof request. Only useful in conjunction with the OAuth2.0
+ * logic, as it generates an OAuth2.0-specific request.
*
- * @param cmd command to extract the denom sig from.
- * @param index index number associated with the denom sig.
- * @param[out] denom_sig set to the offered signature.
- * @return #GNUNET_OK on success.
+ * @param label command label.
+ * @param payment_target_reference command with a payment target to query
+ * @param logic_section name of the KYC provider section
+ * in the exchange configuration for this proof
+ * @param code OAuth 2.0 code to use
+ * @param expected_response_code expected HTTP status
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_denom_sig (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_DenominationSignature **dpk);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_proof_kyc_oauth2 (
+ const char *label,
+ const char *payment_target_reference,
+ const char *logic_section,
+ const char *code,
+ unsigned int expected_response_code);
/**
- * Offer denom sig.
+ * Starts a fake OAuth 2.0 service on @a port for testing
+ * KYC processes which also provides a @a birthdate in a response
*
- * @param index index number to associate to the signature on
- * offer.
- * @param denom_sig the denom sig on offer.
- * @return the trait.
+ * @param label command label
+ * @param birthdate fixed birthdate, such as "2022-03-04", "2022-03-00", "2022-00-00"
+ * @param port the TCP port to listen on
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_denom_sig (
- unsigned int index,
- const struct TALER_DenominationSignature *sig);
-
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_oauth_with_birthdate (const char *label,
+ const char *birthdate,
+ uint16_t port);
/**
- * Offer number trait, 64-bit version.
+ * Starts a fake OAuth 2.0 service on @a port for testing
+ * KYC processes.
*
- * @param index the number's index number.
- * @param n number to offer.
+ * @param label command label
+ * @param port the TCP port to listen on
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_uint64 (unsigned int index,
- const uint64_t *n);
+#define TALER_TESTING_cmd_oauth(label, port) \
+ TALER_TESTING_cmd_oauth_with_birthdate ((label), NULL, (port))
-/**
- * Obtain a "number" value from @a cmd, 64-bit version.
- *
- * @param cmd command to extract the number from.
- * @param index the number's index number.
- * @param[out] n set to the number coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_uint64 (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const uint64_t **n);
+/* ****************** P2P payment commands ****************** */
/**
- * Offer a number.
+ * Creates a purse with deposits.
*
- * @param index the number's index number.
- * @param n the number to offer.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param contract_terms contract, JSON string
+ * @param upload_contract should we upload the contract
+ * @param purse_expiration how long until the purse expires
+ * @param ... NULL-terminated list of references to coins to be deposited
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_uint (unsigned int index,
- const unsigned int *i);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_create_with_deposit (
+ const char *label,
+ unsigned int expected_http_status,
+ const char *contract_terms,
+ bool upload_contract,
+ struct GNUNET_TIME_Relative purse_expiration,
+ ...);
/**
- * Obtain a number from @a cmd.
+ * Deletes a purse.
*
- * @param cmd command to extract the number from.
- * @param index the number's index number.
- * @param[out] n set to the number coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_uint (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const unsigned int **n);
-
-
-/**
- * Opaque handle to fresh coins generated during refresh.
- * Details are internal to the refresh logic.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param purse_cmd command that created the purse
+ * @return the command
*/
-struct TALER_TESTING_FreshCoinData;
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_delete (
+ const char *label,
+ unsigned int expected_http_status,
+ const char *purse_cmd);
/**
- * Offer a _array_ of fresh coins.
+ * Retrieve contract (also checks that the contract matches
+ * the upload command).
*
- * @param index which array of fresh coins to offer,
- * if there are multiple on offer. Typically passed as
- * zero.
- * @param fresh_coins the array of fresh coins to offer
- * @return the trait,
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param for_merge true if for merge, false if for deposit
+ * @param contract_ref reference to a command providing us with the contract private key
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_fresh_coins (
- unsigned int index,
- const struct TALER_TESTING_FreshCoinData *fresh_coins);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_contract_get (
+ const char *label,
+ unsigned int expected_http_status,
+ bool for_merge,
+ const char *contract_ref);
/**
- * Get a array of fresh coins.
+ * Retrieve purse state by merge private key.
*
- * @param cmd command to extract the fresh coin from.
- * @param index which array to pick if @a cmd has multiple
- * on offer.
- * @param[out] fresh_coins will point to the offered array.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param merge_ref reference to a command providing us with the merge private key
+ * @param reserve_ref reference to a command providing us with a reserve private key; if NULL, we create a fresh reserve
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_fresh_coins (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_TESTING_FreshCoinData **fresh_coins);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_merge (
+ const char *label,
+ unsigned int expected_http_status,
+ const char *merge_ref,
+ const char *reserve_ref);
/**
- * Obtain contract terms from @a cmd.
+ * Retrieve purse state.
*
- * @param cmd command to extract the contract terms from.
- * @param index contract terms index number.
- * @param[out] contract_terms where to write the contract
- * terms.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param purse_ref reference to a command providing us with the purse private key
+ * @param expected_balance how much should be in the purse
+ * @param wait_for_merge true to wait for a merge event, otherwise wait for a deposit event
+ * @param timeout how long to wait
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_contract_terms (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const json_t **contract_terms);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_poll (
+ const char *label,
+ unsigned int expected_http_status,
+ const char *purse_ref,
+ const char *expected_balance,
+ bool wait_for_merge,
+ struct GNUNET_TIME_Relative timeout);
/**
- * Offer contract terms.
+ * Wait for the poll command to complete.
*
- * @param index contract terms index number.
- * @param contract_terms contract terms to offer.
- * @return the trait.
+ * @param label command label
+ * @param timeout how long to wait at most
+ * @param poll_reference which poll command to wait for
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_contract_terms (unsigned int index,
- const json_t *contract_terms);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_poll_finish (const char *label,
+ struct GNUNET_TIME_Relative timeout,
+ const char *poll_reference);
/**
- * Obtain wire details from @a cmd.
+ * Creates a purse with reserve.
*
- * @param cmd command to extract the wire details from.
- * @param index index number associate with the wire details
- * on offer; usually zero, as one command sticks to
- * one bank account.
- * @param[out] wire_details where to write the wire details.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param contract_terms contract, JSON string
+ * @param upload_contract should we upload the contract
+ * @param pay_purse_fee should we pay a fee to create the purse
+ * @param expiration when should the purse expire
+ * @param reserve_ref reference to reserve key, or NULL to create a new reserve
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_wire_details (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const json_t **wire_details);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_create_with_reserve (
+ const char *label,
+ unsigned int expected_http_status,
+ const char *contract_terms,
+ bool upload_contract,
+ bool pay_purse_fee,
+ struct GNUNET_TIME_Relative expiration,
+ const char *reserve_ref);
/**
- * Offer wire details in a trait.
+ * Deposit coins into a purse.
*
- * @param index index number associate with the wire details
- * on offer; usually zero, as one command sticks to
- * one bank account.
- * @param wire_details wire details to offer.
- *
- * @return the trait.
+ * @param label command label
+ * @param expected_http_status what HTTP status do we expect to get returned from the exchange
+ * @param min_age age restriction of the purse
+ * @param purse_ref reference to the purse
+ * @param ... NULL-terminated list of references to coins to be deposited
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_wire_details (unsigned int index,
- const json_t *wire_details);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_purse_deposit_coins (
+ const char *label,
+ unsigned int expected_http_status,
+ uint8_t min_age,
+ const char *purse_ref,
+ ...);
/**
- * Obtain serialized exchange keys from @a cmd.
+ * Setup AML officer.
*
- * @param cmd command to extract the keys from.
- * @param index index number associate with the keys on offer.
- * @param[out] keys where to write the serialized keys.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param ref_cmd command that previously created the
+ * officer, NULL to create one this time
+ * @param name full legal name of the officer to use
+ * @param is_active true to set the officer to active
+ * @param read_only true to restrict the officer to read-only
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_exchange_keys (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const json_t **keys);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_set_officer (
+ const char *label,
+ const char *ref_cmd,
+ const char *name,
+ bool is_active,
+ bool read_only);
/**
- * Offer serialized keys in a trait.
+ * Make AML decision.
*
- * @param index index number associate with the serial keys
- * on offer.
- * @param keys serialized keys to offer.
- * @return the trait.
+ * @param label command label
+ * @param ref_officer command that previously created an
+ * officer
+ * @param ref_operation command that previously created an
+ * h_payto which to make an AML decision about
+ * @param new_threshold new threshold to set
+ * @param justification justification given for the decision
+ * @param new_state new AML state for the account
+ * @param kyc_requirement KYC requirement to impose
+ * @param expected_response expected HTTP return status
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_exchange_keys (unsigned int index,
- const json_t *keys);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_take_aml_decision (
+ const char *label,
+ const char *ref_officer,
+ const char *ref_operation,
+ const char *new_threshold,
+ const char *justification,
+ enum TALER_AmlDecisionState new_state,
+ const char *kyc_requirement,
+ unsigned int expected_response);
/**
- * Obtain a private key from a "merchant". Used e.g. to obtain
- * a merchant's priv to sign a /track request.
+ * Fetch AML decision.
*
- * @param cmd command that is offering the key.
- * @param index (typically zero) which key to return if there
- * are multiple on offer.
- * @param[out] priv set to the key coming from @a cmd.
- * @return #GNUNET_OK on success.
+ * @param label command label
+ * @param ref_officer command that previously created an
+ * officer
+ * @param ref_operation command that previously created an
+ * h_payto which to make an AML decision about
+ * @param expected_http_status expected HTTP response status
+ * @return the command
*/
-int
-TALER_TESTING_get_trait_merchant_priv (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_MerchantPrivateKeyP **priv);
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_aml_decision (
+ const char *label,
+ const char *ref_officer,
+ const char *ref_operation,
+ unsigned int expected_http_status);
/**
- * Offer private key of a merchant, typically done when CMD_1 needs it to
- * sign a request.
+ * Fetch AML decisions.
*
- * @param index (typically zero) which key to return if there are
- * multiple on offer.
- * @param priv which object should be offered.
- * @return the trait.
+ * @param label command label
+ * @param ref_officer command that previously created an
+ * officer
+ * @param filter AML state to filter by
+ * @param expected_http_status expected HTTP response status
+ * @return the command
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_merchant_priv (
- unsigned int index,
- const struct TALER_MerchantPrivateKeyP *priv);
-
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_check_aml_decisions (
+ const char *label,
+ const char *ref_officer,
+ enum TALER_AmlDecisionState filter,
+ unsigned int expected_http_status);
-/**
- * Obtain a public key from a "merchant". Used e.g. to obtain
- * a merchant's public key to use backend's API.
- *
- * @param cmd command offering the key.
- * @param index (typically zero) which key to return if there
- * are multiple on offer.
- * @param[out] pub set to the key coming from @a cmd.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_merchant_pub (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_MerchantPublicKeyP **pub);
+/* ****************** convenience functions ************** */
/**
- * Offer public key.
+ * Get exchange URL from interpreter. Convenience function.
*
- * @param index (typically zero) which key to return if there
- * are multiple on offer. NOTE: if one key is offered, it
- * is mandatory to set this as zero.
- * @param pub which object should be returned.
- * @return the trait.
+ * @param is interpreter state.
+ * @return the exchange URL, or NULL on error
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_merchant_pub (
- unsigned int index,
- const struct TALER_MerchantPublicKeyP *pub);
+const char *
+TALER_TESTING_get_exchange_url (
+ struct TALER_TESTING_Interpreter *is);
/**
- * Obtain a string from @a cmd.
+ * Get exchange keys from interpreter. Convenience function.
*
- * @param cmd command to extract the subject from.
- * @param index index number associated with the transfer
- * subject to offer.
- * @param[out] s where to write the offered
- * string.
- * @return #GNUNET_OK on success.
+ * @param is interpreter state.
+ * @return the exchange keys, or NULL on error
*/
-int
-TALER_TESTING_get_trait_string (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const char **s);
+struct TALER_EXCHANGE_Keys *
+TALER_TESTING_get_keys (
+ struct TALER_TESTING_Interpreter *is);
-/**
- * Offer string subject.
- *
- * @param index index number associated with the transfer
- * subject being offered.
- * @param s string to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_string (unsigned int index,
- const char *s);
+/* *** Generic trait logic for implementing traits ********* */
/**
- * Obtain a WTID value from @a cmd.
- *
- * @param cmd command to extract trait from
- * @param index which WTID to pick if @a cmd has multiple on
- * offer
- * @param[out] wtid set to the wanted WTID.
- * @return #GNUNET_OK on success
+ * Opaque handle to fresh coins generated during refresh.
+ * Details are internal to the refresh logic.
*/
-int
-TALER_TESTING_get_trait_wtid (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_WireTransferIdentifierRawP **wtid);
+struct TALER_TESTING_FreshCoinData;
/**
- * Offer a WTID.
- *
- * @param index associate the WTID with this index.
- * @param wtid pointer to the WTID to offer.
- * @return the trait.
+ * A trait.
*/
struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_wtid (
- unsigned int index,
- const struct TALER_WireTransferIdentifierRawP *wtid);
-
-
-/**
- * Different types of URLs that appear in traits.
- */
-enum TALER_TESTING_URL_Type
{
/**
- * Category of last resort. Should not be used.
- */
- TALER_TESTING_UT_UNDEFINED = 0,
-
- /**
- * HTTP base URL of an exchange (API), as for example
- * given in wire transfers subjects made by the aggregator.
+ * Index number associated with the trait. This gives the
+ * possibility to have _multiple_ traits on offer under the
+ * same name.
*/
- TALER_TESTING_UT_EXCHANGE_BASE_URL = 1,
+ unsigned int index;
/**
- * HTTP URL of the exchange's bank account at the bank.
+ * Trait type, for example "reserve-pub" or "coin-priv".
*/
- TALER_TESTING_UT_EXCHANGE_BANK_ACCOUNT_URL = 2
-};
-
-
-/**
- * Offer HTTP url in a trait.
- *
- * @param index which url is to be picked,
- * in case multiple are offered.
- * @param url the url to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_url (enum TALER_TESTING_URL_Type index,
- const char *url);
-
-
-/**
- * Obtain a HTTP url from @a cmd.
- *
- * @param cmd command to extract the url from.
- * @param index which url is to be picked, in case
- * multiple are offered.
- * @param[out] url where to write the url.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_url (const struct TALER_TESTING_Command *cmd,
- enum TALER_TESTING_URL_Type index,
- const char **url);
-
+ const char *trait_name;
-/**
- * Used as the "index" in payto traits, to identify what kind of
- * payto URL we are returning.
- */
-enum TALER_TESTING_PaytoType
-{
- /**
- * We don't know / not credit or debit.
- */
- TALER_TESTING_PT_NEUTRAL,
/**
- * Credit side of a transaction.
- */
- TALER_TESTING_PT_CREDIT,
- /**
- * Debit side of a transaction.
+ * Pointer to the piece of data to offer.
*/
- TALER_TESTING_PT_DEBIT
+ const void *ptr;
};
/**
- * Offer a payto uri in a trait.
- *
- * @param pt which url is to be picked,
- * in case multiple are offered.
- * @param payto_uri the uri to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_payto (enum TALER_TESTING_PaytoType pt,
- const char *payto_uri);
-
-
-/**
- * Obtain a PAYTO url from @a cmd.
- *
- * @param cmd command to extract the url from.
- * @param pt which url is to be picked, in case
- * multiple are offered.
- * @param[out] url where to write the url.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_payto (const struct TALER_TESTING_Command *cmd,
- enum TALER_TESTING_PaytoType pt,
- const char **url);
-
-
-/**
- * Obtain a order id from @a cmd.
- *
- * @param cmd command to extract the order id from.
- * @param index which order id is to be picked, in case
- * multiple are offered.
- * @param[out] order_id where to write the order id.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_order_id (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const char **order_id);
-
-
-/**
- * Offer order id in a trait.
- *
- * @param index which order id is to be offered,
- * in case multiple are offered.
- * @param order_id the order id to offer.
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_order_id (unsigned int index,
- const char *order_id);
-
-
-/**
- * Obtain an amount from a @a cmd.
- *
- * @param cmd command to extract the amount from.
- * @param index which amount to pick if @a cmd has multiple
- * on offer
- * @param[out] amount set to the amount.
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_get_trait_amount_obj (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct TALER_Amount **amount);
-
-
-/**
- * Offer amount.
- *
- * @param index which amount to offer, in case there are
- * multiple available.
- * @param amount the amount to offer.
- *
- * @return the trait.
+ * "end" trait. Because traits are offered into arrays,
+ * this type of trait is used to mark the end of such arrays;
+ * useful when iterating over those.
*/
struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_amount_obj (unsigned int index,
- const struct TALER_Amount *amount);
+TALER_TESTING_trait_end (void);
/**
- * Offer a command in a trait.
- *
- * @param index always zero. Commands offering this
- * kind of traits do not need this index. For
- * example, a "meta" CMD returns always the
- * CMD currently being executed.
- * @param cmd wire details to offer.
+ * Extract a trait.
*
- * @return the trait.
+ * @param traits the array of all the traits.
+ * @param[out] ret where to store the result.
+ * @param trait type of the trait to extract.
+ * @param index index number of the trait to extract.
+ * @return #GNUNET_OK when the trait is found.
*/
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_cmd (unsigned int index,
- const struct TALER_TESTING_Command *cmd);
+enum GNUNET_GenericReturnValue
+TALER_TESTING_get_trait (const struct TALER_TESTING_Trait *traits,
+ const void **ret,
+ const char *trait,
+ unsigned int index);
-/**
- * Obtain a command from @a cmd.
- *
- * @param cmd command to extract the command from.
- * @param index always zero. Commands offering this
- * kind of traits do not need this index. For
- * example, a "meta" CMD returns always the
- * CMD currently being executed.
- * @param[out] _cmd where to write the wire details.
- * @return #GNUNET_OK on success.
- */
-int
-TALER_TESTING_get_trait_cmd (const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- struct TALER_TESTING_Command **_cmd);
+/* ****** Specific traits supported by this component ******* */
/**
- * Obtain a absolute time from @a cmd.
- *
- * @param cmd command to extract trait from
- * @param index which time stamp to pick if
- * @a cmd has multiple on offer.
- * @param[out] time set to the wanted WTID.
- * @return #GNUNET_OK on success
- */
-int
-TALER_TESTING_get_trait_absolute_time (
- const struct TALER_TESTING_Command *cmd,
- unsigned int index,
- const struct GNUNET_TIME_Absolute **time);
+ * Create headers for a trait with name @a name for
+ * statically allocated data of type @a type.
+ */
+#define TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ TALER_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ type **ret); \
+ struct TALER_TESTING_Trait \
+ TALER_TESTING_make_trait_ ## name ( \
+ type * value);
+
+
+/**
+ * Create C implementation for a trait with name @a name for statically
+ * allocated data of type @a type.
+ */
+#define TALER_TESTING_MAKE_IMPL_SIMPLE_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ TALER_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ type **ret) \
+ { \
+ if (NULL == cmd->traits) return GNUNET_SYSERR; \
+ return cmd->traits (cmd->cls, \
+ (const void **) ret, \
+ TALER_S (name), \
+ 0); \
+ } \
+ struct TALER_TESTING_Trait \
+ TALER_TESTING_make_trait_ ## name ( \
+ type * value) \
+ { \
+ struct TALER_TESTING_Trait ret = { \
+ .trait_name = TALER_S (name), \
+ .ptr = (const void *) value \
+ }; \
+ return ret; \
+ }
+
+
+/**
+ * Create headers for a trait with name @a name for
+ * statically allocated data of type @a type.
+ */
+#define TALER_TESTING_MAKE_DECL_INDEXED_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ TALER_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ unsigned int index, \
+ type **ret); \
+ struct TALER_TESTING_Trait \
+ TALER_TESTING_make_trait_ ## name ( \
+ unsigned int index, \
+ type * value);
+
+
+/**
+ * Create C implementation for a trait with name @a name for statically
+ * allocated data of type @a type.
+ */
+#define TALER_TESTING_MAKE_IMPL_INDEXED_TRAIT(name,type) \
+ enum GNUNET_GenericReturnValue \
+ TALER_TESTING_get_trait_ ## name ( \
+ const struct TALER_TESTING_Command *cmd, \
+ unsigned int index, \
+ type **ret) \
+ { \
+ if (NULL == cmd->traits) return GNUNET_SYSERR; \
+ return cmd->traits (cmd->cls, \
+ (const void **) ret, \
+ TALER_S (name), \
+ index); \
+ } \
+ struct TALER_TESTING_Trait \
+ TALER_TESTING_make_trait_ ## name ( \
+ unsigned int index, \
+ type * value) \
+ { \
+ struct TALER_TESTING_Trait ret = { \
+ .index = index, \
+ .trait_name = TALER_S (name), \
+ .ptr = (const void *) value \
+ }; \
+ return ret; \
+ }
+
+
+/**
+ * Call #op on all simple traits.
+ */
+#define TALER_TESTING_SIMPLE_TRAITS(op) \
+ op (bank_row, const uint64_t) \
+ op (officer_pub, const struct TALER_AmlOfficerPublicKeyP) \
+ op (officer_priv, const struct TALER_AmlOfficerPrivateKeyP) \
+ op (officer_name, const char) \
+ op (aml_decision, enum TALER_AmlDecisionState) \
+ op (aml_justification, const char) \
+ op (auditor_priv, const struct TALER_AuditorPrivateKeyP) \
+ op (auditor_pub, const struct TALER_AuditorPublicKeyP) \
+ op (master_priv, const struct TALER_MasterPrivateKeyP) \
+ op (master_pub, const struct TALER_MasterPublicKeyP) \
+ op (purse_priv, const struct TALER_PurseContractPrivateKeyP) \
+ op (purse_pub, const struct TALER_PurseContractPublicKeyP) \
+ op (merge_priv, const struct TALER_PurseMergePrivateKeyP) \
+ op (merge_pub, const struct TALER_PurseMergePublicKeyP) \
+ op (contract_priv, const struct TALER_ContractDiffiePrivateP) \
+ op (reserve_priv, const struct TALER_ReservePrivateKeyP) \
+ op (reserve_sig, const struct TALER_ReserveSignatureP) \
+ op (h_payto, const struct TALER_PaytoHashP) \
+ op (planchet_secret, const struct TALER_PlanchetMasterSecretP) \
+ op (refresh_secret, const struct TALER_RefreshMasterSecretP) \
+ op (reserve_pub, const struct TALER_ReservePublicKeyP) \
+ op (merchant_priv, const struct TALER_MerchantPrivateKeyP) \
+ op (merchant_pub, const struct TALER_MerchantPublicKeyP) \
+ op (merchant_sig, const struct TALER_MerchantSignatureP) \
+ op (wtid, const struct TALER_WireTransferIdentifierRawP) \
+ op (bank_auth_data, const struct TALER_BANK_AuthenticationData) \
+ op (contract_terms, const json_t) \
+ op (wire_details, const json_t) \
+ op (exchange_url, const char) \
+ op (auditor_url, const char) \
+ op (exchange_bank_account_url, const char) \
+ op (taler_uri, const char) \
+ op (payto_uri, const char) \
+ op (kyc_url, const char) \
+ op (web_url, const char) \
+ op (row, const uint64_t) \
+ op (legi_requirement_row, const uint64_t) \
+ op (array_length, const unsigned int) \
+ op (credit_payto_uri, const char) \
+ op (debit_payto_uri, const char) \
+ op (order_id, const char) \
+ op (amount, const struct TALER_Amount) \
+ op (amount_with_fee, const struct TALER_Amount) \
+ op (batch_cmds, struct TALER_TESTING_Command) \
+ op (uuid, const struct GNUNET_Uuid) \
+ op (fresh_coins, const struct TALER_TESTING_FreshCoinData *) \
+ op (claim_token, const struct TALER_ClaimTokenP) \
+ op (relative_time, const struct GNUNET_TIME_Relative) \
+ op (fakebank, struct TALER_FAKEBANK_Handle) \
+ op (keys, struct TALER_EXCHANGE_Keys) \
+ op (process, struct GNUNET_OS_Process *)
+
+
+/**
+ * Call #op on all indexed traits.
+ */
+#define TALER_TESTING_INDEXED_TRAITS(op) \
+ op (denom_pub, const struct TALER_EXCHANGE_DenomPublicKey) \
+ op (denom_sig, const struct TALER_DenominationSignature) \
+ op (amounts, const struct TALER_Amount) \
+ op (deposit_amount, const struct TALER_Amount) \
+ op (deposit_fee_amount, const struct TALER_Amount) \
+ op (age_commitment, const struct TALER_AgeCommitment) \
+ op (age_commitment_proof, const struct TALER_AgeCommitmentProof) \
+ op (h_age_commitment, const struct TALER_AgeCommitmentHash) \
+ op (reserve_history, const struct TALER_EXCHANGE_ReserveHistoryEntry) \
+ op (coin_history, const struct TALER_EXCHANGE_CoinHistoryEntry) \
+ op (planchet_secrets, const struct TALER_PlanchetMasterSecretP) \
+ op (exchange_wd_value, const struct TALER_ExchangeWithdrawValues) \
+ op (coin_priv, const struct TALER_CoinSpendPrivateKeyP) \
+ op (coin_pub, const struct TALER_CoinSpendPublicKeyP) \
+ op (coin_sig, const struct TALER_CoinSpendSignatureP) \
+ op (absolute_time, const struct GNUNET_TIME_Absolute) \
+ op (timestamp, const struct GNUNET_TIME_Timestamp) \
+ op (wire_deadline, const struct GNUNET_TIME_Timestamp) \
+ op (refund_deadline, const struct GNUNET_TIME_Timestamp) \
+ op (exchange_pub, const struct TALER_ExchangePublicKeyP) \
+ op (exchange_sig, const struct TALER_ExchangeSignatureP) \
+ op (blinding_key, const union GNUNET_CRYPTO_BlindingSecretP) \
+ op (h_blinded_coin, const struct TALER_BlindedCoinHashP)
+
+TALER_TESTING_SIMPLE_TRAITS (TALER_TESTING_MAKE_DECL_SIMPLE_TRAIT)
+
+TALER_TESTING_INDEXED_TRAITS (TALER_TESTING_MAKE_DECL_INDEXED_TRAIT)
-/**
- * Offer a absolute time.
- *
- * @param index associate the object with this index
- * @param time which object should be returned
- * @return the trait.
- */
-struct TALER_TESTING_Trait
-TALER_TESTING_make_trait_absolute_time (
- unsigned int index,
- const struct GNUNET_TIME_Absolute *time);
-
#endif
diff --git a/src/include/taler_twister_testing_lib.h b/src/include/taler_twister_testing_lib.h
index fb0c352df..cdafab04b 100644
--- a/src/include/taler_twister_testing_lib.h
+++ b/src/include/taler_twister_testing_lib.h
@@ -26,7 +26,7 @@
#ifndef TALER_TWISTER_TESTING_LIB_H
#define TALER_TWISTER_TESTING_LIB_H
-#include <taler/taler_testing_lib.h>
+#include "taler_testing_lib.h"
#define TWISTER_FAIL() \
do {GNUNET_break (0); return NULL; } while (0)
@@ -100,6 +100,23 @@ TALER_TESTING_cmd_modify_object_ul (const char *label,
/**
+ * Create a "modify header" CMD. This command instructs
+ * the twister to modify a header in the next HTTP response.
+ *
+ * @param label command label
+ * @param config_filename configuration filename.
+ * @param path path identifying where to modify.
+ * @param value value to set the header to.
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_modify_header_dl (const char *label,
+ const char *config_filename,
+ const char *path,
+ const char *value);
+
+
+/**
* Create a "malform response" CMD. This command makes
* the next response randomly malformed (by truncating it).
*
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index c7bf9c02a..8feb8451c 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014-2020 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@@ -16,17 +16,29 @@
/**
* @file include/taler_util.h
* @brief Interface for common utility functions
+ * This library is not thread-safe, all APIs must only be used from a single thread.
+ * This library calls abort() if it runs out of memory. Be aware of these limitations.
* @author Sree Harsha Totakura <sreeharsha@totakura.in>
+ * @author Christian Grothoff
*/
#ifndef TALER_UTIL_H
#define TALER_UTIL_H
+#include <gnunet/gnunet_common.h>
+#define __TALER_UTIL_LIB_H_INSIDE__
+
#include <gnunet/gnunet_util_lib.h>
#include <microhttpd.h>
#include "taler_amount_lib.h"
#include "taler_crypto_lib.h"
/**
+ * Version of the Taler API, in hex.
+ * Thus 0.8.4-1 = 0x00080401.
+ */
+#define TALER_API_VERSION 0x00090401
+
+/**
* Stringify operator.
*
* @param a some expression to stringify. Must NOT be a macro.
@@ -73,6 +85,22 @@
/**
+ * HTTP header with an AML officer signature to approve the inquiry.
+ * Used only in GET Requests.
+ */
+#define TALER_AML_OFFICER_SIGNATURE_HEADER "Taler-AML-Officer-Signature"
+
+/**
+ * Header with signature for reserve history requests.
+ */
+#define TALER_RESERVE_HISTORY_SIGNATURE_HEADER "Taler-Reserve-History-Signature"
+
+/**
+ * Header with signature for coin history requests.
+ */
+#define TALER_COIN_HISTORY_SIGNATURE_HEADER "Taler-Coin-History-Signature"
+
+/**
* Log an error message at log-level 'level' that indicates
* a failure of the command 'cmd' with the message given
* by gcry_strerror(rc).
@@ -119,18 +147,19 @@ TALER_b2s (const void *buf,
* @param obj address of object to convert
* @return string representing the binary obj buffer
*/
-#define TALER_B2S(obj) TALER_b2s (obj, sizeof (*obj))
+#define TALER_B2S(obj) TALER_b2s ((obj), sizeof (*(obj)))
/**
* Obtain denomination amount from configuration file.
*
+ * @param cfg configuration to extract data from
* @param section section of the configuration to access
* @param option option of the configuration to access
* @param[out] denom set to the amount found in configuration
* @return #GNUNET_OK on success, #GNUNET_SYSERR on error
*/
-int
+enum GNUNET_GenericReturnValue
TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *section,
const char *option,
@@ -138,6 +167,39 @@ TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg,
/**
+ * Obtain denomination fee structure of a
+ * denomination from configuration file. All
+ * fee options must start with "fee_" and have
+ * names typical for the respective fees.
+ *
+ * @param cfg configuration to extract data from
+ * @param currency expected currency
+ * @param section section of the configuration to access
+ * @param[out] fees set to the denomination fees
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+enum GNUNET_GenericReturnValue
+TALER_config_get_denom_fees (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char *currency,
+ const char *section,
+ struct TALER_DenomFeeSet *fees);
+
+
+/**
+ * Check that all denominations in @a fees use
+ * @a currency
+ *
+ * @param currency desired currency
+ * @param fees fee set to check
+ * @return #GNUNET_OK on success
+ */
+enum GNUNET_GenericReturnValue
+TALER_denom_fee_check_currency (
+ const char *currency,
+ const struct TALER_DenomFeeSet *fees);
+
+
+/**
* Load our currency from the @a cfg (in section [taler]
* the option "CURRENCY").
*
@@ -145,12 +207,107 @@ TALER_config_get_amount (const struct GNUNET_CONFIGURATION_Handle *cfg,
* @param[out] currency where to write the result
* @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
*/
-int
+enum GNUNET_GenericReturnValue
TALER_config_get_currency (const struct GNUNET_CONFIGURATION_Handle *cfg,
char **currency);
/**
+ * Details about how to render a currency.
+ */
+struct TALER_CurrencySpecification
+{
+ /**
+ * Currency code of the currency.
+ */
+ char currency[TALER_CURRENCY_LEN];
+
+ /**
+ * Human-readable long name of the currency, e.g.
+ * "Japanese Yen".
+ */
+ char *name;
+
+ /**
+ * how many digits the user may enter at most after the @e decimal_separator
+ */
+ unsigned int num_fractional_input_digits;
+
+ /**
+ * how many digits we render in normal scale after the @e decimal_separator
+ */
+ unsigned int num_fractional_normal_digits;
+
+ /**
+ * how many digits we render in after the @e decimal_separator even if all
+ * remaining digits are zero.
+ */
+ unsigned int num_fractional_trailing_zero_digits;
+
+ /**
+ * Mapping of powers of 10 to alternative currency names or symbols.
+ * Keys are the decimal powers, values the currency symbol to use.
+ * Map MUST contain an entry for "0" to the default currency symbol.
+ */
+ json_t *map_alt_unit_names;
+
+};
+
+
+/**
+ * Parse information about supported currencies from
+ * our configuration.
+ *
+ * @param cfg configuration to parse
+ * @param[out] num_currencies set to number of enabled currencies, length of @e cspecs
+ * @param[out] cspecs set to currency specification array
+ * @return #GNUNET_OK on success, #GNUNET_NO if zero
+ * currency specifications were enabled,
+ * #GNUNET_SYSERR if the configuration was malformed
+ */
+enum GNUNET_GenericReturnValue
+TALER_CONFIG_parse_currencies (const struct GNUNET_CONFIGURATION_Handle *cfg,
+ unsigned int *num_currencies,
+ struct TALER_CurrencySpecification **cspecs);
+
+
+/**
+ * Free @a cspecs array.
+ *
+ * @param num_currencies length of @a cspecs array
+ * @param[in] cspecs array to free
+ */
+void
+TALER_CONFIG_free_currencies (
+ unsigned int num_currencies,
+ struct TALER_CurrencySpecification cspecs[static num_currencies]);
+
+
+/**
+ * Convert a currency specification to the
+ * respective JSON object.
+ *
+ * @param cspec currency specification
+ * @return JSON object encoding @a cspec for `/config`.
+ */
+json_t *
+TALER_CONFIG_currency_specs_to_json (
+ const struct TALER_CurrencySpecification *cspec);
+
+
+/**
+ * Check that @a map contains a valid currency scale
+ * map that maps integers from [-12,24] to currency
+ * symbols given as strings.
+ *
+ * @param map map to check
+ * @return #GNUNET_OK if @a map is valid
+ */
+enum GNUNET_GenericReturnValue
+TALER_check_currency_scale_map (const json_t *map);
+
+
+/**
* Allow user to specify an amount on the command line.
*
* @param shortName short name of the option
@@ -175,6 +332,23 @@ TALER_project_data_default (void);
/**
+ * Initialize libtalerutil.
+ */
+void
+TALER_OS_init (void);
+
+
+/**
+ * Re-encode string at @a inp to match RFC 8785 (section 3.2.2.2).
+ *
+ * @param[in,out] inp pointer to string to re-encode
+ * @return number of bytes in resulting @a inp
+ */
+size_t
+TALER_rfc8785encode (char **inp);
+
+
+/**
* URL-encode a string according to rfc3986.
*
* @param s string to encode
@@ -185,6 +359,44 @@ TALER_urlencode (const char *s);
/**
+ * Test if all characters in @a url are valid for
+ * a URL.
+ *
+ * @param url URL to sanity-check
+ * @return true if @a url only contains valid characters
+ */
+bool
+TALER_url_valid_charset (const char *url);
+
+
+/**
+ * Test if the URL is a valid "http" (or "https")
+ * URL (includes test for #TALER_url_valid_charset()).
+ *
+ * @param url a string to test if it could be a valid URL
+ * @return true if @a url is well-formed
+ */
+bool
+TALER_is_web_url (const char *url);
+
+
+/**
+ * Check if @a lang matches the @a language_pattern, and if so with
+ * which preference.
+ * See also: https://tools.ietf.org/html/rfc7231#section-5.3.1
+ *
+ * @param language_pattern a language preferences string
+ * like "fr-CH, fr;q=0.9, en;q=0.8, *;q=0.1"
+ * @param lang the 2-digit language to match
+ * @return q-weight given for @a lang in @a language_pattern, 1.0 if no weights are given;
+ * 0 if @a lang is not in @a language_pattern
+ */
+double
+TALER_language_matches (const char *language_pattern,
+ const char *lang);
+
+
+/**
* Find out if an MHD connection is using HTTPS (either
* directly or via proxy).
*
@@ -193,7 +405,7 @@ TALER_urlencode (const char *s);
* #GNUNET_NO if the MHD connection is using http,
* #GNUNET_SYSERR if the connection type couldn't be determined
*/
-int
+enum GNUNET_GenericReturnValue
TALER_mhd_is_https (struct MHD_Connection *connection);
@@ -204,8 +416,9 @@ TALER_mhd_is_https (struct MHD_Connection *connection);
* that a NULL value does not terminate the list, only a NULL key signals the
* end of the list of arguments.
*
- * @param base_url absolute base URL to use
- * @param path path of the url
+ * @param base_url absolute base URL to use, must either
+ * end with '/' *or* @a path must be the empty string
+ * @param path path of the url to append to the @a base_url
* @param ... NULL-terminated key-value pairs (char *) for query parameters,
* only the value will be url-encoded
* @returns the URL, must be freed with #GNUNET_free
@@ -288,6 +501,20 @@ TALER_payto_get_method (const char *payto_uri);
/**
+ * Normalize payto://-URI to make "strcmp()" sufficient
+ * to check if two payto-URIs refer to the same bank
+ * account. Removes optional arguments (everything after
+ * "?") and applies method-specific normalizations to
+ * the main part of the URI.
+ *
+ * @param input a payto://-URI
+ * @return normalized URI, or NULL if @a input was not well-formed
+ */
+char *
+TALER_payto_normalize (const char *input);
+
+
+/**
* Obtain the account name from a payto URL.
*
* @param payto an x-taler-bank payto URL
@@ -298,4 +525,305 @@ char *
TALER_xtalerbank_account_from_payto (const char *payto);
+/**
+ * Obtain the receiver name from a payto URL.
+ *
+ * @param payto an x-taler-bank payto URL
+ * @return only the receiver name from the @a payto URL, NULL if not an x-taler-bank payto URL
+ */
+char *
+TALER_payto_get_receiver_name (const char *payto);
+
+
+/**
+ * Extract the subject value from the URI parameters.
+ *
+ * @param payto_uri the URL to parse
+ * @return NULL if the subject parameter is not found.
+ * The caller should free the returned value.
+ */
+char *
+TALER_payto_get_subject (const char *payto_uri);
+
+
+/**
+ * Check that a payto:// URI is well-formed.
+ *
+ * @param payto_uri the URL to check
+ * @return NULL on success, otherwise an error
+ * message to be freed by the caller!
+ */
+char *
+TALER_payto_validate (const char *payto_uri);
+
+
+/**
+ * Create payto://-URI for a given exchange base URL
+ * and a @a reserve_pub.
+ *
+ * @param exchange_url the base URL of the exchange
+ * @param reserve_pub the public key of the reserve
+ * @return payto://-URI for the reserve (without receiver-name!)
+ */
+char *
+TALER_reserve_make_payto (const char *exchange_url,
+ const struct TALER_ReservePublicKeyP *reserve_pub);
+
+
+/**
+ * Check that an IBAN number is well-formed.
+ *
+ * Validates given IBAN according to the European Banking Standards. See:
+ * http://www.europeanpaymentscouncil.eu/documents/ECBS%20IBAN%20standard%20EBS204_V3.2.pdf
+ *
+ * @param iban the IBAN to check
+ * @return NULL on success, otherwise an error
+ * message to be freed by the caller!
+ */
+char *
+TALER_iban_validate (const char *iban);
+
+
+/**
+ * Possible values for a binary filter.
+ */
+enum TALER_EXCHANGE_YesNoAll
+{
+ /**
+ * If condition is yes.
+ */
+ TALER_EXCHANGE_YNA_YES = 1,
+
+ /**
+ * If condition is no.
+ */
+ TALER_EXCHANGE_YNA_NO = 2,
+
+ /**
+ * Condition disabled.
+ */
+ TALER_EXCHANGE_YNA_ALL = 3
+};
+
+
+/**
+ * Convert query argument to @a yna value.
+ *
+ * @param connection connection to take query argument from
+ * @param arg argument to try for
+ * @param default_val value to assign if the argument is not present
+ * @param[out] yna value to set
+ * @return true on success, false if the parameter was malformed
+ */
+bool
+TALER_arg_to_yna (struct MHD_Connection *connection,
+ const char *arg,
+ enum TALER_EXCHANGE_YesNoAll default_val,
+ enum TALER_EXCHANGE_YesNoAll *yna);
+
+
+/**
+ * Convert YNA value to a string.
+ *
+ * @param yna value to convert
+ * @return string representation ("yes"/"no"/"all").
+ */
+const char *
+TALER_yna_to_string (enum TALER_EXCHANGE_YesNoAll yna);
+
+
+#ifdef __APPLE__
+/**
+ * Returns the first occurrence of `c` in `s`, or returns the null-byte
+ * terminating the string if it does not occur.
+ *
+ * @param s the string to search in
+ * @param c the character to search for
+ * @return char* the first occurrence of `c` in `s`
+ */
+char *strchrnul (const char *s, int c);
+
+#endif
+
+/**
+ * @brief Parses a date information into days after 1970-01-01 (or 0)
+ *
+ * The input MUST be of the form
+ *
+ * 1) YYYY-MM-DD, representing a valid date
+ * 2) YYYY-MM-00, representing a valid month in a particular year
+ * 3) YYYY-00-00, representing a valid year.
+ *
+ * In the cases 2) and 3) the out parameter is set to the beginning of the
+ * time, f.e. 1950-00-00 == 1950-01-01 and 1888-03-00 == 1888-03-01
+ *
+ * The output will set to the number of days after 1970-01-01 or 0, if the input
+ * represents a date belonging to the largest allowed age group.
+ *
+ * @param in Input string representation of the date
+ * @param mask Age mask
+ * @param[out] out Where to write the result
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
+ */
+enum GNUNET_GenericReturnValue
+TALER_parse_coarse_date (
+ const char *in,
+ const struct TALER_AgeMask *mask,
+ uint32_t *out);
+
+
+/**
+ * @brief Parses a string as a list of age groups.
+ *
+ * The string must consist of a colon-separated list of increasing integers
+ * between 0 and 31. Each entry represents the beginning of a new age group.
+ * F.e. the string
+ *
+ * "8:10:12:14:16:18:21"
+ *
+ * represents the following list of eight age groups:
+ *
+ * | Group | Ages |
+ * | -----:|:------------- |
+ * | 0 | 0, 1, ..., 7 |
+ * | 1 | 8, 9 |
+ * | 2 | 10, 11 |
+ * | 3 | 12, 13 |
+ * | 4 | 14, 15 |
+ * | 5 | 16, 17 |
+ * | 6 | 18, 19, 20 |
+ * | 7 | 21, ... |
+ *
+ * which is then encoded as a bit mask with the corresponding bits set:
+ *
+ * 31 24 16 8 0
+ * | | | | |
+ * oooooooo oo1oo1o1 o1o1o1o1 ooooooo1
+ *
+ * @param groups String representation of age groups
+ * @param[out] mask Mask representation for age restriction.
+ * @return Error, if age groups were invalid, OK otherwise.
+ */
+enum GNUNET_GenericReturnValue
+TALER_parse_age_group_string (
+ const char *groups,
+ struct TALER_AgeMask *mask);
+
+
+/**
+ * @brief Encodes the age mask into a string, like "8:10:12:14:16:18:21"
+ *
+ * NOTE: This function uses a static buffer. It is not safe to call this
+ * function concurrently.
+ *
+ * @param mask Age mask
+ * @return String representation of the age mask.
+ * Can be used as value in the TALER config.
+ */
+const char *
+TALER_age_mask_to_string (
+ const struct TALER_AgeMask *mask);
+
+
+/**
+ * @brief returns the age group of a given age for a given age mask
+ *
+ * @param mask Age mask
+ * @param age The given age
+ * @return age group
+ */
+uint8_t
+TALER_get_age_group (
+ const struct TALER_AgeMask *mask,
+ uint8_t age);
+
+
+/**
+ * @brief Parses a JSON object { "age_groups": "a:b:...y:z" }.
+ *
+ * @param root is the json object
+ * @param[out] mask on success, will contain the age mask
+ * @return #GNUNET_OK on success and #GNUNET_SYSERR on failure.
+ */
+enum GNUNET_GenericReturnValue
+TALER_JSON_parse_age_groups (const json_t *root,
+ struct TALER_AgeMask *mask);
+
+
+/**
+ * @brief Return the lowest age in the corresponding group for a given age
+ * according the given age mask.
+ *
+ * @param mask age mask
+ * @param age age to check
+ * @return lowest age in corresponding age group
+ */
+uint8_t
+TALER_get_lowest_age (
+ const struct TALER_AgeMask *mask,
+ uint8_t age);
+
+
+/**
+ * @brief Get the lowest age for the largest age group
+ *
+ * @param mask the age mask
+ * @return lowest age for the largest age group
+ */
+#define TALER_adult_age(mask) \
+ sizeof((mask)->bits) * 8 - __builtin_clz ((mask)->bits) - 1
+
+/**
+ * Handle to an external process that will assist
+ * with some JSON-to-JSON conversion.
+ */
+struct TALER_JSON_ExternalConversion;
+
+/**
+ * Type of a callback that receives a JSON @a result.
+ *
+ * @param cls closure
+ * @param status_type how did the process die
+ * @param code termination status code from the process
+ * @param result some JSON result, NULL if we failed to get an JSON output
+ */
+typedef void
+(*TALER_JSON_JsonCallback) (void *cls,
+ enum GNUNET_OS_ProcessStatusType status_type,
+ unsigned long code,
+ const json_t *result);
+
+
+/**
+ * Launch some external helper @a binary to convert some @a input
+ * and eventually call @a cb with the result.
+ *
+ * @param input JSON to serialize and pass to the helper process
+ * @param cb function to call on the result
+ * @param cb_cls closure for @a cb
+ * @param binary name of the binary to execute
+ * @param ... NULL-terminated list of arguments for the @a binary,
+ * usually starting with again the name of the binary
+ * @return handle to cancel the operation (and kill the helper)
+ */
+struct TALER_JSON_ExternalConversion *
+TALER_JSON_external_conversion_start (const json_t *input,
+ TALER_JSON_JsonCallback cb,
+ void *cb_cls,
+ const char *binary,
+ ...);
+
+/**
+ * Abort external conversion, killing the process and preventing
+ * the callback from being called. Must not be called after the
+ * callback was invoked.
+ *
+ * @param[in] ec external conversion handle to cancel
+ */
+void
+TALER_JSON_external_conversion_stop (
+ struct TALER_JSON_ExternalConversion *ec);
+
+#undef __TALER_UTIL_LIB_H_INSIDE__
+
#endif