1.2. Conventions for Taler RESTful APIs

1.2.1. HTTP Request and Response

Certain response formats are common for all requests. They are documented here instead of with each individual request. Furthermore, we note that clients may theoretically fail to receive any response. In this case, the client should verify that the Internet connection is working properly, and then proceed to handle the error as if an internal error (500) had been returned.

ANY /*

Request:

Unless specified otherwise, HTTP requests that carry a message body must have the content type application/json.

Request Headers:

Response:

Response Headers:
200 Ok:

The request was successful.

301 Moved permanently:

The server responsible for the reserve changed, the client MUST follow the link to the new location. If possible, the client SHOULD remember the new URL for the reserve for future requests. Only applicable if the request method is GET.

302 Found:

The server responsible for the reserve changed, the client MUST follow the link to the new location, but MUST NOT retain the new URL for future requests. Only applicable if the request method is GET.

307 Temporary redirect:

The server responsible for the reserve changed, the client MUST follow the link to the new location, but MUST NOT retain the new URL for future requests.

308 Permanent redirect:

The server responsible for the reserve changed, the client MUST follow the link to the new location. If possible, the client SHOULD remember the new URL for the reserve for future requests.

400 Bad request:

One of the arguments to the request is missing or malformed.

415 Unsupported Media Type:

The Content-Type header was not set, or it was set to an unsupported MIME type.

500 Internal server error:

This always indicates some serious internal operational error of the exchange, such as a program bug, database problems, etc., and must not be used for client-side problems. When facing an internal server error, clients should retry their request after some delay. We recommended initially trying after 1s, twice more at randomized times within 1 minute, then the user should be informed and another three retries should be scheduled within the next 24h. If the error persists, a report should ultimately be made to the auditor, although the auditor API for this is not yet specified. However, as internal server errors are always reported to the exchange operator, a good operator should naturally be able to address them in a timely fashion, especially within 24h.

Unless specified otherwise, all error status codes (4xx and 5xx) have a message body with an ErrorDetail JSON object.

Details:

interface ErrorDetail {

  // Numeric error code unique to the condition.
  // The other arguments are specific to the error value reported here.
  code: number;

  // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ...
  // Should give a human-readable hint about the error's nature. Optional, may change without notice!
  hint?: string;

  // Optional detail about the specific input value that failed. May change without notice!
  detail?: string;

  // Name of the parameter that was bogus (if applicable).
  parameter?: string;

  // Path to the argument that was bogus (if applicable).
  path?: string;

  // Offset of the argument that was bogus (if applicable).
  offset?: string;

  // Index of the argument that was bogus (if applicable).
  index?: string;

  // Name of the object that was bogus (if applicable).
  object?: string;

  // Name of the currency that was problematic (if applicable).
  currency?: string;

  // Expected type (if applicable).
  type_expected?: string;

  // Type that was provided instead (if applicable).
  type_actual?: string;

  // Extra information that doesn't fit into the above (if applicable).
  extra?: Object;
}

1.2.2. Protocol Version Ranges

Some of the Taler services (e.g. exchange, merchant, bank integration API) expose the range of API versions they support. Clients in turn have an API version range they support. These version ranges are written down in the libtool version format.

A protocol version is a positive, non-zero integer. A protocol version range consists of three components:

  1. The current version. This is the latest version of the protocol supported by the client or service.

  2. The revision number. This value should usually not be interpreted by the client/server, but serves purely as a comment. Each time a service/client for a protocol is updated while supporting the same set of protocol versions, the revision should be increased. In rare cases, the revision number can be used to work around unintended breakage in deployed versions of a service. This is discouraged and should only be used in exceptional situations.

  3. The age number. This non-zero integer identifies with how many previous protocol versions this implementation is compatible. An age of 0 implies that the implementation only supports the current protocol version. The age must be less or equal than the current protocol version.

To avoid confusion with semantic versions, the protocol version range is written down in the following format:

current[:revision[:age]]

The angle brackets mark optional components. If either revision or age are omitted, they default to 0.

Examples:

  • “1” and “1” are compatible

  • “1” and “2” are incompatible

  • “2:0:1” and “1:0:0” are compatible

  • “2:5:1” and “1:10:0” are compatible

  • “4:0:1” and “2:0:0” are incompatible

  • “4:0:1” and “3:0:0” are compatible

Note

Semantic versions are not a good tool for this job, as we concisely want to express that the client/server supports the last n versions of the protocol. Semantic versions don’t support this, and semantic version ranges are too complex for this.

Warning

A client doesn’t have one single protocol version range. Instead, it has a protocol version range for each type of service it talks to.

Warning

For privacy reasons, the protocol version range of a client should not be sent to the service. Instead, the client should just use the two version ranges to decide whether it will talk to the service.

1.2.3. Error Codes

All error codes used in GNU Taler are defined in GANA.

This centralized registry also contains generators that create enumerations and mappings from error codes to HTTP status codes and human-readable error messages for various programming languages.

All error codes have numeric values below 100 or above 1000, so as to never be confused with HTTP status codes. A value of 0 is reserved for “no error” or “success”.

In C, the respective enumeration is the enum TALER_ErrorCode.

Developers may have to re-run bootstrap and/or update their Git submodules to ensure that they have the lastest GANA registry.

1.2.4. Common query patterns

1.2.4.1. Row ID pagination

Some endpoints paginate elements identified by an opaque numeric identifier, referred to here as row ID. The semantics of the row ID (including its sorting order) are determined by the server and are completely opaque to the client.

The list of returned elements is determined by a row ID offset and a non-zero signed integer limit:

  • If limit is positive, return a list of up to limit elements (all matching the filter criteria) strictly after the offset. The elements are sorted in ascending order of the row ID.

  • If limit is negative, return a list of up to -limit elements (all matching the filter criteria) strictly before the offset. The elements are sorted in descending order of the row ID.

If offset is not explicitly given, it defaults to:

  • A value smaller than all other row IDs if limit is positive.

  • A value larger than all other row IDs if limit is negative.

query limit:

Optional. At most return the given number of results. Negative for descending by row ID, positive for ascending by row ID.

query offset:

Optional. Starting row ID for an iteration.

1.2.4.2. Long polling

Endpoints can result in an empty response (pagination) or a negative response (uncompleted operation, etc). Some endpoints allow clients to perform a form of long polling by asking the server to wait until timeout_ms for a non-empty or positive result.

In the case of pagination, the response is sent as soon as a matching element is found and, therefore, the response MAY contain fewer than limit elements.

A client MUST never rely on this behavior, as a response can be sent immediately or after waiting only a fraction of timeout_ms.

query timeout_ms:

Optional. Timeout in milliseconds to wait for the response to be non-empty or positive.

1.2.5. Common encodings

This section describes how certain types of values are represented throughout the API.

1.2.5.1. Binary Data

type Base32 = string;

Binary data is generally encoded using Crockford’s variant of Base32 (http://www.crockford.com/wrmg/base32.html), except that “U” is not excluded but also decodes to “V” to make OCR easy. We will still simply use the JSON type “base32” and the term “Crockford Base32” in the text to refer to the resulting encoding.

1.2.5.2. Hash codes

Hash codes are strings representing base32 encoding of the respective hashed data. See base32.

// 64-byte hash code.
type HashCode = string;
// 32-byte hash code.
type ShortHashCode = string;
// 32-byte nonce.
type AccountAccessToken = string;
// 16-byte salt.
type WireSalt = string;
type SHA256HashCode = ShortHashCode;
type SHA512HashCode = HashCode;
// 32-byte nonce value, must only be used once.
type CSNonce = string;
// 32-byte nonce value, must only be used once.
type RefreshMasterSeed = string;
// 32-byte value representing a point on Curve25519.
type Cs25519Point = string;
// 32-byte value representing a scalar multiplier
// for scalar operations on points on Curve25519.
type Cs25519Scalar = string;

1.2.5.3. Safe Integers

For easier browser-side processing, we restrict some integers to the range that is safely representable in JavaScript.

// Subset of numbers:  Integers in the
// inclusive range 0 .. (2^53 - 1).
type SafeUint64 = number;

1.2.5.4. Large numbers

Large numbers such as RSA blinding factors and 256 bit keys, are transmitted as other binary data in Crockford Base32 encoding.

1.2.5.5. Decimal numbers

// Number with at most 8 fractional digits.
type DecimalNumber = string;

1.2.5.6. Timestamps

Timestamps are represented by the following structure:

interface Timestamp {
  // Seconds since epoch, or the special
  // value "never" to represent an event that will
  // never happen.
  t_s: number | "never";
}
interface RelativeTime {
  // Duration in microseconds or "forever"
  // to represent an infinite duration. Numeric
  // values are capped at 2^53 - 1 inclusive.
  d_us: number | "forever";
}

1.2.5.7. Integers

// JavaScript numbers restricted to integers.
type Integer = number;

1.2.5.8. Floats

// JavaScript numbers.
type Float = number;

1.2.5.9. Ages

// An age is an integer between 0 and 255 measured in years.
type Age = number;

1.2.5.10. Versions

We use the type LibtoolVersion in the design documents to refer to a string that represents a version with the semantic as defined by libtool.

// Version information in libtool version format and semantics
// current[:revision[:age]], f.e. "1", "2:0" or "3:1:2".
// see https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html.
type LibtoolVersion = string;

We use the type SemVer to refer to a string that represents a version with the semantic as defined by semantic versioning.

// Version information in semantic versioning format and semantics,
// like "X.Z.Y", see https://semver.org/.
type SemVer = string;

1.2.5.11. Objects

// JavaScript objects, no further restrictions.
type Object = object;

1.2.5.12. Contact details

type EmailAddress = string;
type PhoneNumber = string;

Phone numbers should start with the + symbol and the country code.

1.2.5.13. Permissions

This type epresses which permissions for a subject apply on a resource.

interface LibeufinPermission {
  subjectType: string;
  subjectId: string;
  resourceType: string;
  resourceId: string;
  permissionName: string
}

1.2.5.14. Fetch params

interface FetchParams {

  // Because transactions are delivered by banks in "batches",
  // then every batch can have different qualities.  This value
  // lets the request specify which type of batch ought to be
  // returned.  Currently, the following two type are supported:
  //
  // 'report': typically includes only non booked transactions.
  // 'statement': typically includes only booked transactions.
  level: "report" | "statement" | "all";

  // This type indicates the time range of the query.
  // It allows the following values:
  //
  // 'latest': retrieves the last transactions from the bank.
  //           If there are older unread transactions, those will *not*
  //           be downloaded.
  //
  // 'all': retrieves all the transactions from the bank,
  //        until the oldest.
  //
  // 'previous-days': currently *not* implemented, it will allow
  //                  the request to download transactions from
  //                  today until N days before.
  //
  // 'since-last': retrieves all the transactions since the last
  //               time one was downloaded.
  //
  rangeType: "latest" | "all" | "previous-days" | "since-last";
};

1.2.5.15. Keys

// 16-byte access token used to authorize access.
type ClaimToken = string;
// EdDSA and ECDHE public keys always point on Curve25519
// and represented  using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type EddsaPublicKey = string;
// EdDSA and ECDHE public keys always point on Curve25519
// and represented  using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type EddsaPrivateKey = string;
// Edx25519 public keys are points on Curve25519 and represented using the
// standard 256 bits Ed25519 compact format converted to Crockford
// Base32.
type Edx25519PublicKey = string;
// Edx25519 private keys are always points on Curve25519
// and represented using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type Edx25519PrivateKey = string;
// EdDSA and ECDHE public keys always point on Curve25519
// and represented  using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type EcdhePublicKey = string;
// Point on Curve25519 represented using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type CsRPublic = string;
// EdDSA and ECDHE public keys always point on Curve25519
// and represented  using the standard 256 bits Ed25519 compact format,
// converted to Crockford Base32.
type EcdhePrivateKey = string;
type CoinPublicKey = EddsaPublicKey;
// RSA public key converted to Crockford Base32.
type RsaPublicKey = string;

1.2.5.16. Blinded coin

// The type of a coin's blinded envelope depends on the cipher that is used
// for signing with a denomination key.
type CoinEnvelope = RSACoinEnvelope | CSCoinEnvelope ;
// For denomination signatures based on RSA, the planchet is just a blinded
// coin's public EdDSA key.
interface RSACoinEnvelope {
  cipher: "RSA" | "RSA+age_restricted";
  rsa_blinded_planchet: BlindedRsaSignature;
}
// For denomination signatures based on Blind Clause-Schnorr, the planchet
// consists of the public nonce and two Curve25519 scalars which are two
// blinded challenges in the Blinded Clause-Schnorr signature scheme.
// See https://taler.net/papers/cs-thesis.pdf for details.
interface CSCoinEnvelope {
  cipher: "CS" | "CS+age_restricted";
  cs_nonce: string;      // Crockford Base32 encoded
  cs_blinded_c0: string; // Crockford Base32 encoded
  cs_blinded_c1: string; // Crockford Base32 encoded
}
// Secret for blinding/unblinding.
// An RSA blinding secret, which is basically
// a 256-bit nonce, converted to Crockford Base32.
type DenominationBlindingKeyP = string;

. _unblinded-coin:

1.2.5.17. Unblinded coin

// The type of a coin's unblinded signature depends on the cipher that was used
// for signing with a denomination key.
// Note that for now, only RSA is supported.
type UnblindedSignature = RsaUnblindedSignature | CsUnblindedSignature;
interface RsaUnblindedSignature {
  cipher: "RSA";
  rsa_signature: RsaSignature;
}
// Note, this is here for the sake of completeness, but not yet supported
interface CsUnblindedSignature {
  cipher: "CS";

  cs_signature_r: Cs25519Point;
  cs_signature_s: Cs25519Scalar;
}

1.2.5.18. Signatures

// EdDSA signatures are transmitted as 64-bytes base32
// binary-encoded objects with just the R and S values (base32_ binary-only).
type EddsaSignature = string;
// Edx25519 signatures are transmitted as 64-bytes base32
// binary-encoded objects with just the R and S values (base32_ binary-only).
type Edx25519Signature = string;
// base32 encoded RSA signature.
type RsaSignature = string;
// base32 encoded RSA blinded signature.
type BlindedRsaSignature = string;
// base32 encoded RSA blinding secret.
type RsaBlindingKeySecret = string;
// Union, not (!) discriminated!
// (Note: CS Blinding Key secret is yet to be defined&added here).
type DenominationBlindingKeySecret =
  | RsaBlindingKeySecret;

1.2.5.19. Amounts

type Amount = string;

Amounts of currency are serialized as a string of the format <Currency>:<DecimalAmount>. Taler treats monetary amounts as fixed-precision numbers, with 8 decimal places. Unlike floating point numbers, this allows accurate representation of monetary amounts.

The following constrains apply for a valid amount:

  1. The <Currency> part must be at most 11 characters long and may only consist of ASCII letters (a-zA-Z).

  2. The integer part of <DecimalAmount> may be at most 2^52.

  3. The fractional part of <DecimalAmount> may contain at most 8 decimal digits.

Note

“EUR:1.50” and “EUR:10” are valid amounts. These are all invalid amounts: “A:B:1.5”, “EUR:4503599627370501.0”, “EUR:1.”, “EUR:.1”.

An amount that is prefixed with a + or - character is also used in certain contexts. When no sign is present, the amount is assumed to be positive.

Note

In some setups, when Libeufin-Bank offers cashouts towards traditional currencies like EUR for example, the fractional part gets restricted to at most 2 digits.

type SignedAmount = string;

1.2.5.20. Images

// The string must be a data URL according to RFC 2397
// with explicit mediatype and base64 parameters.
//
//     data:<mediatype>;base64,<data>
//
// Supported mediatypes are image/jpeg and image/png.
// Invalid strings will be rejected by the wallet.
type ImageDataUrl = string;

1.2.6. Binary Formats

Note

Due to the way of handling “big” numbers by some platforms (such as JavaScript, for example), wherever the following specification mentions a 64-bit value, the actual implementations are strongly advised to rely on arithmetic up to 53 bits.

Note

Taler uses libgnunetutil for interfacing itself with the operating system, doing crypto work, and other “low level” actions, therefore it is strongly connected with the GNUnet project.

This section specifies the binary representation of messages used in Taler’s protocols. The message formats are given in a C-style pseudocode notation. Padding is always specified explicitly, and numeric values are in network byte order (big endian).

1.2.6.1. Amounts

Amounts of currency are always expressed in terms of a base value, a fractional value and the denomination of the currency:

struct TALER_AmountNBO {
  // Non-negative integer value in the currency (in network byte order),
  // can be at most 2^52.
  // Note that "1" here would correspond to 1 EUR or 1 USD,
  // depending on `currency`, not 1 cent.
  uint64_t value;

  // Unsigned 32 bit fractional value (in network byte order)
  // to be added to ``value`` representing
  // an additional currency fraction, in units of one hundred millionth (1e-8)
  // of the base currency value.  For example, a fraction
  // of 50,000,000 would correspond to 50 cents.
  uint32_t fraction;

  // Name of the currency, using either a three-character ISO 4217 currency
  // code, or a regional currency identifier between 4 and 11 characters,
  // consisting of ASCII alphabetic characters ("a-zA-Z").
  // Should be padded to 12 bytes with 0-characters.
  // Currency codes are compared case-insensitively.
  uint8_t currency_code[12];
};

1.2.6.2. Time

In signed messages, time is represented using 64-bit big-endian values, denoting microseconds since the UNIX Epoch. UINT64_MAX represents “never”.

struct GNUNET_TIME_Absolute {
  uint64_t timestamp_us;
};
struct GNUNET_TIME_AbsoluteNBO {
  uint64_t abs_value_us__;       // in network byte order
};

1.2.6.3. 451 Responses

When KYC operations are required, various endpoints may respond with a 451 Unavailable for Legal Reasons status code and a LegitimizationNeededResponse body.

// Implemented in this style since exchange
// protocol **v20**.
interface LegitimizationNeededResponse {

  // Numeric error code unique to the condition.
  // Should always be TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED.
  code: number;

  // Human-readable description of the error, i.e. "missing parameter",
  // "commitment violation", ...  Should give a human-readable hint
  // about the error's nature. Optional, may change without notice!
  hint?: string;

  // Hash of the payto:// account URI for which KYC
  // is required.
  // The account holder can uses the /kyc-check/$H_PAYTO
  // endpoint to check the KYC status or initiate the KYC process.
  h_payto: PaytoHash;

  // Public key associated with the account. The client must sign
  // the initial request for the KYC status using the corresponding
  // private key.  Will be either a reserve public key or a merchant
  // (instance) public key.
  //
  // Absent if no public key is currently associated
  // with the account and the client MUST thus first
  // credit the exchange via an inbound wire transfer
  // to associate a public key with the debited account.
  account_pub?: EddsaPublicKey;

  // Identifies a set of measures that were triggered and that are
  // now preventing this operation from proceeding.  Gives developers
  // a starting point for understanding why the transaction was
  // blocked and how to lift it.
  // Can be zero (which means there is no requirement row),
  // especially if bad_kyc_auth is set.
  requirement_row: Integer;

  // True if the operation was denied because the
  // KYC auth key does not match the merchant public
  // key.  In this case, a KYC auth wire transfer
  // with the merchant public key must be performed
  // first.
  // Since exchange protocol **v21**.
  bad_kyc_auth?: boolean;

}

1.2.6.4. Cryptographic primitives

All elliptic curve operations are on Curve25519. Public and private keys are thus 32 bytes, and signatures 64 bytes. For hashing, including HKDFs, Taler uses 512-bit hash codes (64 bytes).

struct GNUNET_HashCode {
  uint8_t hash[64];      // usually SHA-512
};

struct TALER_DenominationHash {
  struct GNUNET_HashCode hash;
};

struct TALER_PrivateContractHash {
  struct GNUNET_HashCode hash;
};

struct TALER_ExtensionsPolicyHash {
  struct GNUNET_HashCode hash;
};

struct TALER_MerchantWireHash {
  struct GNUNET_HashCode hash;
};

struct TALER_PaytoHash {
  struct GNUNET_ShortHashCode hash;
};

struct TALER_BlindedCoinHash {
  struct GNUNET_HashCode hash;
};

struct TALER_CoinPubHash {
  struct GNUNET_HashCode hash;
};

struct TALER_OutputCommitmentHash {
  struct GNUNET_HashCode hash;
};

struct TALER_EcdhEphemeralPublicKeyP {
  uint8_t ecdh_pub[32];
};

struct TALER_ReservePublicKeyP {
  uint8_t eddsa_pub[32];
};

struct TALER_ReservePrivateKeyP {
  uint8_t eddsa_priv[32];
};

struct TALER_ReserveSignatureP {
  uint8_t eddsa_signature[64];
};

struct TALER_MerchantPublicKeyP {
  uint8_t eddsa_pub[32];
};

struct TALER_MerchantPrivateKeyP {
  uint8_t eddsa_priv[32];
};

struct TALER_TransferPublicKeyP {
  uint8_t ecdhe_pub[32];
};

struct TALER_TransferPrivateKeyP {
  uint8_t ecdhe_priv[32];
};

enum TALER_AmlDecisionState {
  NORMAL, PENDING, FROZEN
};

struct TALER_AmlOfficerPublicKeyP {
  uint8_t eddsa_pub[32];
};

struct TALER_AmlOfficerPrivateKeyP {
  uint8_t eddsa_priv[32];
};

struct TALER_ExchangePublicKeyP {
  uint8_t eddsa_pub[32];
};

struct TALER_ExchangePrivateKeyP {
  uint8_t eddsa_priv[32];
};

struct TALER_ExchangeSignatureP {
  uint8_t eddsa_signature[64];
};

struct TALER_MasterPublicKeyP {
  uint8_t eddsa_pub[32];
};

struct TALER_MasterPrivateKeyP {
  uint8_t eddsa_priv[32];
};

 struct TALER_MasterSignatureP {
  uint8_t eddsa_signature[64];
};

struct WireTransferIdentifierRawP {
  uint8_t raw[32];
};

struct UUID {
  uint32_t value[4];
};

struct TALER_WadId wad_id {
  uint32_t value[6];
};

union TALER_CoinSpendPublicKeyP {
  uint8_t eddsa_pub[32];
  uint8_t ecdhe_pub[32];
};

union TALER_CoinSpendPrivateKeyP {
  uint8_t eddsa_priv[32];
  uint8_t ecdhe_priv[32];
};

struct TALER_CoinSpendSignatureP {
  uint8_t eddsa_signature[64];
};

struct TALER_TransferSecretP {
  uint8_t key[sizeof (struct GNUNET_HashCode)];
};
  uint8_t key[sizeof (struct GNUNET_HashCode)];
};

struct TALER_EncryptedLinkSecretP {
  uint8_t enc[sizeof (struct TALER_LinkSecretP)];
};

union TALER_TokenPublicKeyP {
  uint8_t eddsa_pub[32];
  uint8_t ecdhe_pub[32];
};

1.2.6.5. Signatures

Any piece of signed data, complies to the abstract data structure given below.

struct Data {
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  type1_t payload1;
  type2_t payload2;
  ...
};

/*From gnunet_crypto_lib.h*/
struct GNUNET_CRYPTO_EccSignaturePurpose {
  /**
   * This field equals the number of bytes being signed,
   * namely 'sizeof (struct Data)'.
   */
  uint32_t size;
  /**
   * This field is used to express the context in
   * which the signature is made, ensuring that a
   * signature cannot be lifted from one part of the protocol
   * to another. See `src/include/taler_signatures.h` within the
   * exchange's codebase (git://taler.net/exchange).
   */
  uint32_t purpose;
};

The following list contains all the data structures that can be signed in Taler. Their definition is typically found in src/include/taler_signatures.h, within the exchange’s codebase.

struct TALER_WithdrawRequestPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ReservePublicKeyP reserve_pub;
  struct TALER_AmountNBO amount_with_fee;
  struct TALER_AmountNBO withdraw_fee;
  struct TALER_DenominationHash h_denomination_pub;
  struct TALER_BlindedCoinHash h_coin_envelope;
};

struct TALER_AgeWithdrawRequestPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ReservePublicKeyP reserve_pub;
  /**
   * This is the running SHA512-hash over n*kappa
   * `struct TALER_BlindedCoinHash` values
   */
  struct GNUNET_HashCode h_commitment;
  struct TALER_AgeMask mask;
  uint8_t max_age_group;
};

struct TALER_AgeWithdrawConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_AGE_WITHDRAW
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_HashCode h_commitment;
  uint32_t noreveal_index;
};

struct TALER_DepositRequestPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_DEPOSIT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  struct TALER_AgeCommitmentHash h_age_commitment;
  struct TALER_ExtensionsPolicyHash h_policy;
  struct TALER_MerchantWireHash h_wire;
  struct TALER_DenominationHash h_denom_pub;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct GNUNET_TIME_AbsoluteNBO refund_deadline;
  struct TALER_AmountNBO amount_with_fee;
  struct TALER_AmountNBO deposit_fee;
  struct TALER_MerchantPublicKeyP merchant;
  struct GNUNET_HashCode wallet_data_hash;
};

struct TALER_DepositConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  struct TALER_MerchantWireHash h_wire;
  struct TALER_ExtensionsPolicyHash h_policy;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct GNUNET_TIME_AbsoluteNBO refund_deadline;
  struct TALER_AmountNBO amount_without_fee;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct TALER_MerchantPublicKeyP merchant;
};

struct TALER_RefreshMeltCoinAffirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_MELT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_RefreshCommitmentP session_hash;
  struct TALER_DenominationHash h_denom_pub;
  struct TALER_AgeCommitmentHash h_age_commitment;
  struct TALER_AmountNBO amount_with_fee;
  struct TALER_AmountNBO melt_fee;
};

struct TALER_RefreshMeltConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_RefreshCommitmentP session_hash;
  uint16_t noreveal_index;
};

struct TALER_ExchangeSigningKeyValidityPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO start;
  struct GNUNET_TIME_AbsoluteNBO expire;
  struct GNUNET_TIME_AbsoluteNBO end;
  struct TALER_ExchangePublicKeyP signkey_pub;
};

struct TALER_ExchangeKeySetPS {
    /**
     * purpose.purpose = TALER_SIGNATURE_EXCHANGE_KEY_SET
     */
    struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    struct GNUNET_TIME_AbsoluteNBO list_issue_date;
    struct GNUNET_HashCode hc;
};

struct TALER_DenominationKeyValidityPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_MasterPublicKeyP master;
  struct GNUNET_TIME_AbsoluteNBO start;
  struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
  struct GNUNET_TIME_AbsoluteNBO expire_spend;
  struct GNUNET_TIME_AbsoluteNBO expire_legal;
  struct TALER_AmountNBO value;
  struct TALER_AmountNBO fee_withdraw;
  struct TALER_AmountNBO fee_deposit;
  struct TALER_AmountNBO fee_refresh;
  struct TALER_DenominationHash denom_hash;
};

struct TALER_MasterWireDetailsPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_DETAILS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PaytoHash h_wire_details;
  struct GNUNET_HashCode h_conversion_url;
  struct GNUNET_HashCode h_credit_restrictions;
  struct GNUNET_HashCode h_debit_restrictions;
};

struct TALER_MasterWireFeePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_FEES
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_HashCode h_wire_method;
  struct GNUNET_TIME_AbsoluteNBO start_date;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct TALER_AmountNBO wire_fee;
  struct TALER_AmountNBO closing_fee;
};

struct TALER_GlobalFeesPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_GLOBAL_FEES
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO start_date;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct GNUNET_TIME_RelativeNBO purse_timeout;
  struct GNUNET_TIME_RelativeNBO kyc_timeout;
  struct GNUNET_TIME_RelativeNBO history_expiration;
  struct TALER_AmountNBO history_fee;
  struct TALER_AmountNBO kyc_fee;
  struct TALER_AmountNBO account_fee;
  struct TALER_AmountNBO purse_fee;
  uint32_t purse_account_limit;
};

struct TALER_MasterDrainProfitPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_DRAIN_PROFITS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_WireTransferIdentifierRawP wtid;
  struct GNUNET_TIME_AbsoluteNBO date;
  struct TALER_AmountNBO amount;
  struct GNUNET_HashCode h_section;
  struct TALER_PaytoHashP h_payto;
};

struct TALER_DepositTrackPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  struct TALER_MerchantWireHash h_wire;
  union TALER_CoinSpendPublicKeyP coin_pub;
};

struct TALER_WireDepositDetailP {
  struct TALER_PrivateContractHash h_contract_terms;
  struct GNUNET_TIME_AbsoluteNBO execution_time;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct TALER_AmountNBO deposit_value;
  struct TALER_AmountNBO deposit_fee;
};

struct TALER_WireDepositDataPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO total;
  struct TALER_AmountNBO wire_fee;
  struct TALER_MerchantPublicKeyP merchant_pub;
  struct TALER_MerchantWireHash h_wire;
  struct GNUNET_HashCode h_details;
};

struct TALER_ExchangeKeyValidityPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_HashCode auditor_url_hash;
  struct TALER_MasterPublicKeyP master;
  struct GNUNET_TIME_AbsoluteNBO start;
  struct GNUNET_TIME_AbsoluteNBO expire_withdraw;
  struct GNUNET_TIME_AbsoluteNBO expire_spend;
  struct GNUNET_TIME_AbsoluteNBO expire_legal;
  struct TALER_AmountNBO value;
  struct TALER_AmountNBO fee_withdraw;
  struct TALER_AmountNBO fee_deposit;
  struct TALER_AmountNBO fee_refresh;
  struct TALER_DenominationHash denom_hash;
};

struct PaymentResponsePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MERCHANT_PAYMENT_OK
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
};

struct TALER_ContractPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MERCHANT_CONTRACT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
};

struct TALER_ConfirmWirePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_MerchantWireHash h_wire;
  struct TALER_PrivateContractHash h_contract_terms;
  struct TALER_WireTransferIdentifierRawP wtid;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct GNUNET_TIME_AbsoluteNBO execution_time;
  struct TALER_AmountNBO coin_contribution;
};

struct TALER_RefundConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct TALER_MerchantPublicKeyP merchant;
  uint64_t rtransaction_id;
  struct TALER_AmountNBO refund_amount;
};

struct TALER_DepositTrackPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  struct TALER_MerchantWireHash h_wire;
  struct TALER_MerchantPublicKeyP merchant;
  union TALER_CoinSpendPublicKeyP coin_pub;
};

struct TALER_RefundRequestPS {
  /**
   *  purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PrivateContractHash h_contract_terms;
  union TALER_CoinSpendPublicKeyP coin_pub;
  uint64_t rtransaction_id;
  struct TALER_AmountNBO refund_amount;
  struct TALER_AmountNBO refund_fee;
};

struct TALER_MerchantRefundConfirmationPS {
  /**
   *  purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND_OK
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  /**
   * Hash of the order ID (a string), hashed without the 0-termination.
   */
  struct GNUNET_HashCode h_order_id;
};

struct TALER_RecoupRequestPS {
  /**
   *  purpose.purpose = TALER_SIGNATURE_WALLET_COIN_RECOUP
   * or TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_DenominationHash h_denom_pub;
  struct TALER_DenominationBlindingKeyP coin_blind;
};

struct TALER_RecoupRefreshConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct TALER_AmountNBO recoup_amount;
  union TALER_CoinSpendPublicKeyP coin_pub;
  union TALER_CoinSpendPublicKeyP old_coin_pub;
};

struct TALER_RecoupConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct TALER_AmountNBO recoup_amount;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct TALER_ReservePublicKeyP reserve_pub;
};

struct TALER_DenominationUnknownAffirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct TALER_DenominationHash h_denom_pub;
};

struct TALER_DenominationExpiredAffirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_GENERIC_DENOMINATIN_EXPIRED
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  char operation[8];
  struct TALER_DenominationHash h_denom_pub;
};

struct TALER_ReserveCloseConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
  struct TALER_AmountNBO closing_amount;
  struct TALER_ReservePublicKeyP reserve_pub;
  struct TALER_PaytoHash h_wire;
};

struct TALER_CoinLinkSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_COIN_LINK
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_DenominationHash h_denom_pub;
  union TALER_CoinSpendPublicKeyP old_coin_pub;
  struct TALER_TransferPublicKeyP transfer_pub;
  struct TALER_BlindedCoinHash coin_envelope_hash;
};

struct TALER_ReserveStatusRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_RESERVE_STATUS_REQUEST
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO request_timestamp;
};

struct TALER_ReserveHistoryRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_RESERVE_HISTORY_REQUEST
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO history_fee;
  struct GNUNET_TIME_AbsoluteNBO request_timestamp;
};

struct TALER_PurseStatusRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_PURSE_STATUS_REQUEST
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
};

struct TALER_PurseStatusResponseSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_PURSE_STATUS_RESPONSE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO total_purse_amount;
  struct TALER_AmountNBO total_deposit_amount;
  struct TALER_AmountNBO max_deposit_fees;
  struct GNUNET_TIME_AbsoluteNBO purse_expiration;
  struct GNUNET_TIME_AbsoluteNBO status_timestamp;
  struct TALER_PrivateContractHash h_contract_terms;
};

struct TALER_ReserveCloseRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_CLOSE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
};

struct TALER_RefreshCommitmentP {
  struct GNUNET_HashCode session_hash;
};

struct TALER_PurseRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_PURSE_CREATE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO purse_expiration;
  struct TALER_AmountNBO merge_value_after_fees;
  struct TALER_PrivateContractHashP h_contract_terms;
  uint32_t min_age;
};

struct TALER_PurseDepositSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_PURSE_DEPOSIT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO coin_contribution;
  struct TALER_DenominationHash h_denom_pub;
  struct TALER_AgeCommitmentHash h_age_commitment;
  struct TALER_PursePublicKeyP purse_pub;
  struct GNUNET_HashCode h_exchange_base_url;
};

struct TALER_PurseDepositSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ReserveSignatureP reserve_sig;
  struct TALER_AmountNBO coin_contribution;
};

struct TALER_PurseDepositConfirmedSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_PURSE_DEPOSIT_CONFIRMED
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO total_purse_amount;
  struct TALER_AmountNBO total_deposit_fees;
  struct TALER_PursePublicKeyP purse_pub;
  struct GNUNET_TIME_AbsoluteNBO purse_expiration;
  struct TALER_PrivateContractHashP h_contract_terms;
};

struct TALER_PurseMergeSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_PURSE_MERGE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO merge_timestamp;
  struct TALER_PaytoHashP h_wire;
};

struct TALER_AccountMergeSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ReservePublicKeyP reserve_pub;
  struct TALER_PursePublicKeyP purse_pub;
  struct TALER_AmountNBO merge_amount_after_fees;
  struct GNUNET_TIME_AbsoluteNBO merge_timestamp;
  struct GNUNET_TIME_AbsoluteNBO purse_expiration;
  struct TALER_PrivateContractHashP h_contract_terms;
  uint32_t min_age;
};

struct TALER_AccountSetupRequestSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_ACCOUNT_SETUP
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO threshold;
};

struct TALER_AccountSetupSuccessSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_ACCOUNT_SETUP_SUCCESS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PaytoHash h_payto;
  struct GNUNET_HashCode h_kyc;
  struct GNUNET_TIME_AbsoluteNBO timestamp;
};

struct TALER_PurseMergeSuccessSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_PURSE_MERGE_SUCCESS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ReservePublicKeyP reserve_pub;
  struct TALER_PursePublicKeyP purse_pub;
  struct TALER_AmountNBO merge_amount_after_fees;
  struct GNUNET_TIME_AbsoluteNBO contract_time;
  struct TALER_PrivateContractHashP h_contract_terms;
  struct TALER_PaytoHashP h_wire;
  uint32_t min_age;
};

struct TALER_WadDataSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WAD_DATA
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO wad_execution_time;
  struct TALER_AmountNBO total_amount;
  struct GNUNET_HashCode h_items;
  struct TALER_WadId wad_id;
};

struct TALER_WadPartnerSignaturePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_PARTNER_DETAILS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_HashCode h_partner_base_url;
  struct TALER_MasterPublicKeyP master_public_key;
  struct GNUNET_TIME_AbsoluteNBO start_date;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct TALER_AmountNBO wad_fee;
  struct GNUNET_TIME_RelativeNBO wad_frequency;
};

struct TALER_P2PFeesPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_P2P_FEES
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO start_date;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct TALER_AmountNBO kyc_fee;
  struct TALER_AmountNBO purse_fee;
  struct TALER_AmountNBO account_history_fee;
  struct TALER_AmountNBO account_annual_fee;
  struct GNUNET_TIME_RelativeNBO account_kyc_timeout;
  struct GNUNET_TIME_RelativeNBO purse_timeout;
  uint32_t purse_account_limit;
};

struct TALER_CoinPurseRefundConfirmationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_PursePublicKey purse_pub;
  union TALER_CoinSpendPublicKeyP coin_pub;
  struct TALER_AmountNBO refunded_amount;
  struct TALER_AmountNBO refund_fee;
};

struct TALER_DenominationKeyAnnouncementPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_SM_DENOMINATION_KEY
   */
   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
   struct TALER_DenominationHash h_denom_pub;
   struct GNUNET_HashCode h_section_name;
   struct GNUNET_TIME_AbsoluteNBO anchor_time;
   struct GNUNET_TIME_RelativeNBO duration_withdraw;
 };

struct TALER_SigningKeyAnnouncementPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_SM_SIGNING_KEY .
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ExchangePublicKeyP exchange_pub;
  struct GNUNET_TIME_AbsoluteNBO anchor_time;
  struct GNUNET_TIME_RelativeNBO duration;
};

struct TALER_MasterDenominationKeyRevocationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_DenominationHash h_denom_pub;
};

struct TALER_MasterSigningKeyRevocationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_ExchangePublicKeyP exchange_pub;
};

struct TALER_MasterAddAuditorPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_ADD_AUDITOR
   */
   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
   struct GNUNET_TIME_AbsoluteNBO start_date;
   struct TALER_AuditorPublicKeyP auditor_pub;
   struct GNUNET_HashCode h_auditor_url;
 };

struct TALER_MasterDelAuditorPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_DEL_AUDITOR
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct TALER_AuditorPublicKeyP auditor_pub;
};

struct TALER_MasterAddWirePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_ADD_WIRE.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO start_date;
  struct TALER_PaytoHash h_wire;
  struct GNUNET_HashCode h_conversion_url;
  struct GNUNET_HashCode h_credit_restrictions;
  struct GNUNET_HashCode h_debit_restrictions;
};

struct TALER_MasterDelWirePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_DEL_WIRE.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_AbsoluteNBO end_date;
  struct TALER_PaytoHash h_wire;
};

struct TALER_MasterAmlOfficerStatusPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_AML_KEY
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_TimestampNBO change_date;
  struct TALER_AmlOfficerPublicKeyP officer_pub;
  struct GNUNET_HashCode h_officer_name GNUNET_PACKED;
  uint32_t is_active GNUNET_PACKED;
};

struct TALER_AmlDecisionPS {
  /**
   * purpose.purpose =TALER_SIGNATURE_AML_DECISION.
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_HashCode h_justification GNUNET_PACKED;
  struct GNUNET_TIME_TimestampNBO decision_time;
  struct TALER_AmountNBO new_threshold;
  struct TALER_PaytoHashP h_payto GNUNET_PACKED;
  struct GNUNET_HashCode h_kyc_requirements;
  uint32_t new_state GNUNET_PACKED;
};

struct TALER_PartnerConfigurationPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_MASTER_PARNTER_DETAILS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_MasterPublicKeyP partner_pub;
  struct GNUNET_TIME_TimestampNBO start_date;
  struct GNUNET_TIME_TimestampNBO end_date;
  struct GNUNET_TIME_RelativeNBO wad_frequency;
  struct TALER_AmountNBO wad_fee;
  struct GNUNET_HashCode h_url;
};

struct TALER_ReserveOpenPS {
  /**
   * Purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_OPEN
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct TALER_AmountNBO reserve_payment;
  struct GNUNET_TIME_TimestampNBO request_timestamp;
  struct GNUNET_TIME_TimestampNBO reserve_expiration;
  uint32_t purse_limit;
};

struct TALER_ReserveClosePS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_CLOSE
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_TimestampNBO request_timestamp;
  struct TALER_PaytoHashP target_account_h_payto;
};

struct TALER_ReserveAttestRequestPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_WALLET_ATTEST_REQUEST
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_TimestampNBO request_timestamp;
  struct GNUNET_HashCode h_details;
};

struct TALER_ExchangeAttestPS {
  /**
   * purpose.purpose = TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
   */
  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
  struct GNUNET_TIME_TimestampNBO attest_timestamp;
  struct GNUNET_TIME_TimestampNBO expiration_time;
  struct TALER_ReservePublicKeyP reserve_pub;
  struct GNUNET_HashCode h_attributes;
};