gnunet-svn
[Top][All Lists]
Advanced

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

[taler-docs] branch master updated: update exchange REST API: remove pai


From: gnunet
Subject: [taler-docs] branch master updated: update exchange REST API: remove paid history API, authenticate GET coin history API, add start offset and ETag specs for both histories
Date: Mon, 18 Sep 2023 14:46:38 +0200

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

grothoff pushed a commit to branch master
in repository docs.

The following commit(s) were added to refs/heads/master by this push:
     new 90448a05 update exchange REST API: remove paid history API, 
authenticate GET coin history API, add start offset and ETag specs for both 
histories
90448a05 is described below

commit 90448a05fae6b27db2825d3d77902a821b61a512
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon Sep 18 14:46:35 2023 +0200

    update exchange REST API: remove paid history API, authenticate GET coin 
history API, add start offset and ETag specs for both histories
---
 core/api-exchange.rst | 1493 +++++++++++++++++++++++++------------------------
 1 file changed, 775 insertions(+), 718 deletions(-)

diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 71a15454..e7934bff 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -1636,7 +1636,7 @@ exchange.
 
 .. http:get:: /reserves/$RESERVE_PUB
 
-  Request information about a reserve.
+  Request summary information about a reserve.
 
   **Request:**
 
@@ -1667,970 +1667,906 @@ exchange.
     }
 
 
-.. http:post:: /reserves/$RESERVE_PUB/status
+Withdraw
+~~~~~~~~
 
-  Request information about a reserve or an account.
+.. http:post:: /csr-withdraw
 
-  **Request:**
+  Obtain exchange-side input values in preparation for a
+  withdraw step for certain denomination cipher types,
+  specifically at this point for Clause-Schnorr blind
+  signatures.
 
-  The request body must be a `ReserveStatusRequest` object.
+  **Request:** The request body must be a `WithdrawPrepareRequest` object.
 
   **Response:**
 
   :http:statuscode:`200 OK`:
-    The exchange responds with a `ReserveStatus` object; the reserve was known 
to the exchange.
-  :http:statuscode:`403 Forbidden`:
-    The *TALER_SIGNATURE_RESERVE_STATUS_REQUEST* signature is invalid.
-    This response comes with a standard `ErrorDetail` response. Alternatively, 
the provided timestamp is not close to the current time.
+    The request was successful, and the response is a 
`WithdrawPrepareResponse`.  Note that repeating exactly the same request
+    will again yield the same response (assuming none of the denomination is 
expired).
   :http:statuscode:`404 Not found`:
-    The reserve key does not belong to a reserve known to the exchange.
+    The denomination key is not known to the exchange.
+  :http:statuscode:`410 Gone`:
+    The requested denomination key is not yet or no longer valid.
+    It either before the validity start, past the expiration or was revoked. 
The response is a
+    `DenominationExpiredMessage`. Clients must evaluate
+    the error code provided to understand which of the
+    cases this is and handle it accordingly.
 
   **Details:**
 
-  .. ts:def:: ReserveStatusRequest
-
-    interface ReserveStatusRequest {
-      // Signature of purpose
-      // ``TALER_SIGNATURE_RESERVE_STATUS_REQUEST`` over
-      // a `TALER_ReserveStatusRequestSignaturePS`.
-      reserve_sig: EddsaSignature;
-
-      // Time when the client made the request.
-      // Timestamp must be reasonably close to the time of
-      // the exchange, otherwise the exchange may reject
-      // the request.
-      request_timestamp: Timestamp;
-    }
+  .. ts:def:: WithdrawPrepareRequest
 
-  .. ts:def:: ReserveStatus
+    interface WithdrawPrepareRequest {
 
-    interface ReserveStatus {
-      // Balance left in the reserve.
-      balance: Amount;
+      // Nonce to be used by the exchange to derive
+      // its private inputs from. Must not have ever
+      // been used before.
+      nonce: CSNonce;
 
-      // If set, gives the maximum age group that the client is required to set
-      // during withdrawal.
-      maximum_age_group: number;
+      // Hash of the public key of the denomination the
+      // request relates to.
+      denom_pub_hash: HashCode;
 
-      // Transaction history for this reserve.
-      // May be partial (!).
-      history: TransactionHistoryItem[];
     }
 
-  Objects in the transaction history have the following format:
+  .. ts:def:: WithdrawPrepareResponse
 
-  .. ts:def:: TransactionHistoryItem
+    type WithdrawPrepareResponse =
+      | ExchangeWithdrawValue;
 
-    // Union discriminated by the "type" field.
-    type TransactionHistoryItem =
-      | AccountSetupTransaction
-      | ReserveHistoryTransaction
-      | ReserveWithdrawTransaction
-      | ReserveAgeWithdrawTransaction
-      | ReserveCreditTransaction
-      | ReserveClosingTransaction
-      | ReserveOpenRequestTransaction
-      | ReserveCloseRequestTransaction
-      | PurseMergeTransaction;
+  .. ts:def:: ExchangeWithdrawValue
 
-  .. ts:def:: AccountSetupTransaction
+    type ExchangeWithdrawValue =
+      | ExchangeRsaWithdrawValue
+      | ExchangeCsWithdrawValue;
 
-    interface AccountSetupTransaction {
-      type: "SETUP";
+  .. ts:def:: ExchangeRsaWithdrawValue
 
-      // KYC fee agreed to by the reserve owner.
-      kyc_fee: Amount;
+    interface ExchangeRsaWithdrawValue {
+      cipher: "RSA";
+    }
 
-      // Time when the KYC was triggered.
-      kyc_timestamp: Timestamp;
+  .. ts:def:: ExchangeCsWithdrawValue
 
-      // Hash of the wire details of the account.
-      // Note that this hash is unsalted and potentially
-      // private (as it could be inverted), hence access
-      // to this endpoint must be authorized using the
-      // private key of the reserve.
-      h_wire: HashCode;
+    interface ExchangeCsWithdrawValue {
+      cipher: "CS";
 
-      // Signature created with the reserve's private key.
-      // Must be of purpose ``TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST`` over
-      // a ``TALER_AccountSetupRequestSignaturePS``.
-      reserve_sig: EddsaSignature;
+      // CSR R0 value
+      r_pub_0: CsRPublic;
 
+      // CSR R1 value
+      r_pub_1: CsRPublic;
     }
 
-  .. ts:def:: ReserveHistoryTransaction
-
-    interface ReserveHistoryTransaction {
-      type: "HISTORY";
 
-      // Fee agreed to by the reserve owner.
-      amount: Amount;
+.. http:post:: /reserves/$RESERVE_PUB/withdraw
 
-      // Time when the request was made.
-      request_timestamp: Timestamp;
+  Withdraw a coin of the specified denomination.  Note that the client should
+  commit all of the request details, including the private key of the coin and
+  the blinding factor, to disk *before* issuing this request, so that it can
+  recover the information if necessary in case of transient failures, like
+  power outage, network outage, etc.
 
-      // Signature created with the reserve's private key.
-      // Must be of purpose ``TALER_SIGNATURE_RESERVE_HISTORY_REQUEST`` over
-      // a `TALER_ReserveHistoryRequestSignaturePS`.
-      reserve_sig: EddsaSignature;
+  **Request:** The request body must be a `WithdrawRequest` object.
 
-    }
+  **Response:**
 
-  .. ts:def:: ReserveWithdrawTransaction
+  :http:statuscode:`200 OK`:
+    The request was successful, and the response is a `WithdrawResponse`.  
Note that repeating exactly the same request
+    will again yield the same response, so if the network goes down during the
+    transaction or before the client can commit the coin signature to disk, the
+    coin is not lost.
+  :http:statuscode:`403 Forbidden`:
+    The signature is invalid.
+    This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`404 Not found`:
+    The denomination key or the reserve are not known to the exchange.  If the
+    denomination key is unknown, this suggests a bug in the wallet as the
+    wallet should have used current denomination keys from ``/keys``.
+    In this case, the response will be a `DenominationUnknownMessage`.
+    If the reserve is unknown, the wallet should not report a hard error yet, 
but
+    instead simply wait for up to a day, as the wire transaction might simply
+    not yet have completed and might be known to the exchange in the near 
future.
+    In this case, the wallet should repeat the exact same request later again
+    using exactly the same blinded coin.
+  :http:statuscode:`409 Conflict`:
+    One of the following reasons occured:
 
-    interface ReserveWithdrawTransaction {
-      type: "WITHDRAW";
+    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
+    indicated denominations.  The response is `WithdrawError` object.
 
-      // Amount withdrawn.
-      amount: Amount;
+    2. The reserve has a birthday set and requires a request to 
``/age-withdraw`` instead.
+    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED`` and an additional field 
``maximum_allowed_age`` for the maximum age (in years) that the client can 
commit to in the call to ``/age-withdraw``
+  :http:statuscode:`410 Gone`:
+    The requested denomination key is not yet or no longer valid.
+    It either before the validity start, past the expiration or was revoked. 
The response is a
+    `DenominationExpiredMessage`. Clients must evaluate
+    the error code provided to understand which of the
+    cases this is and handle it accordingly.
+  :http:statuscode:`451 Unavailable for Legal Reasons`:
+    This reserve has received funds from a purse or the amount withdrawn
+    exceeds another legal threshold and thus the reserve must
+    be upgraded to an account (with KYC) before the withdraw can
+    complete.  Note that this response does NOT affirm that the
+    withdraw will ultimately complete with the requested amount.
+    The user should be redirected to the provided location to perform
+    the required KYC checks to open the account before withdrawing.
+    Afterwards, the request should be repeated.
+    The response will be an `KycNeededRedirect` object.
 
-      // Hash of the denomination public key of the coin.
-      h_denom_pub: HashCode;
+    Implementation note: internally, we need to
+    distinguish between upgrading the reserve to an
+    account (due to P2P payment) and identifying the
+    owner of the origin bank account (due to exceeding
+    the withdraw amount threshold), as we need to create
+    a different payto://-URI for the KYC check depending
+    on the case.
 
-      // Hash of the blinded coin to be signed.
-      h_coin_envelope: HashCode;
 
-      // Signature over a `TALER_WithdrawRequestPS`
-      // with purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``
-      // created with the reserve's private key.
-      reserve_sig: EddsaSignature;
+  **Details:**
 
-      // Fee that is charged for withdraw.
-      withdraw_fee: Amount;
-     }
+  .. ts:def:: DenominationExpiredMessage
 
-  .. ts:def:: ReserveAgeWithdrawTransaction
+    interface DenominationExpiredMessage {
 
-    interface ReserveAgeWithdrawTransaction {
-      type: "AGEWITHDRAW";
+      // Taler error code.  Note that beyond
+      // expiration this message format is also
+      // used if the key is not yet valid, or
+      // has been revoked.
+      code: number;
 
-      // Total Amount withdrawn.
-      amount: Amount;
+      // Signature by the exchange over a
+      // `TALER_DenominationExpiredAffirmationPS`.
+      // Must have purpose ``TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED``.
+      exchange_sig: EddsaSignature;
 
-      // Commitment of all ``n*kappa`` blinded coins.
-      h_commitment: HashCode;
+      // Public key of the exchange used to create
+      // the 'exchange_sig.
+      exchange_pub: EddsaPublicKey;
 
-      // Signature over a `TALER_AgeWithdrawRequestPS`
-      // with purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``
-      // created with the reserve's private key.
-      reserve_sig: EddsaSignature;
+      // Hash of the denomination public key that is unknown.
+      h_denom_pub: HashCode;
 
-      // Fee that is charged for withdraw.
-      withdraw_fee: Amount;
-     }
+      // When was the signature created.
+      timestamp: Timestamp;
 
+      // What kind of operation was requested that now
+      // failed?
+      oper: string;
+    }
 
-  .. ts:def:: ReserveCreditTransaction
 
-    interface ReserveCreditTransaction {
-      type: "CREDIT";
+  .. ts:def:: WithdrawRequest
 
-      // Amount deposited.
-      amount: Amount;
+    interface WithdrawRequest {
+      // Hash of a denomination public key (RSA), specifying the type of coin 
the client
+      // would like the exchange to create.
+      denom_pub_hash: HashCode;
 
-      // Sender account ``payto://`` URL.
-      sender_account_url: string;
+      // Coin's blinded public key, should be (blindly) signed by the 
exchange's
+      // denomination private key.
+      coin_ev: CoinEnvelope;
 
-      // Opaque identifier internal to the exchange that
-      // uniquely identifies the wire transfer that credited the reserve.
-      wire_reference: Integer;
+      // Signature of `TALER_WithdrawRequestPS` created with
+      // the `reserves's private key <reserve-priv>`
+      // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``.
+      reserve_sig: EddsaSignature;
 
-      // Timestamp of the incoming wire transfer.
-      timestamp: Timestamp;
     }
 
+  .. ts:def:: WithdrawResponse
 
-  .. ts:def:: ReserveClosingTransaction
+    interface WithdrawResponse {
+      // The blinded signature over the 'coin_ev', affirms the coin's
+      // validity after unblinding.
+      ev_sig: BlindedDenominationSignature;
 
-    interface ReserveClosingTransaction {
-      type: "CLOSING";
+    }
 
-      // Closing balance.
-      amount: Amount;
+  .. ts:def:: BlindedDenominationSignature
 
-      // Closing fee charged by the exchange.
-      closing_fee: Amount;
+    type BlindedDenominationSignature =
+      | RsaBlindedDenominationSignature
+      | CSBlindedDenominationSignature;
 
-      // Wire transfer subject.
-      wtid: Base32;
+  .. ts:def:: RsaBlindedDenominationSignature
 
-      // ``payto://`` URI of the wire account into which the funds were 
returned to.
-      receiver_account_details: string;
+    interface RsaBlindedDenominationSignature {
+      cipher: "RSA";
 
-      // This is a signature over a
-      // struct `TALER_ReserveCloseConfirmationPS` with purpose
-      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED``.
-      exchange_sig: EddsaSignature;
-
-      // Public key used to create 'exchange_sig'.
-      exchange_pub: EddsaPublicKey;
-
-      // Time when the reserve was closed.
-      timestamp: Timestamp;
+      // (blinded) RSA signature
+      blinded_rsa_signature: BlindedRsaSignature;
     }
 
+  .. ts:def:: CSBlindedDenominationSignature
 
-  .. ts:def:: ReserveOpenRequestTransaction
-
-    interface ReserveOpenRequestTransaction {
-      type: "OPEN";
-
-      // Open fee paid from the reserve.
-      open_fee: Amount;
+    interface CSBlindedDenominationSignature {
+      type: "CS";
 
-      // This is a signature over
-      // a struct `TALER_ReserveOpenPS` with purpose
-      // ``TALER_SIGNATURE_WALLET_RESERVE_OPEN``.
-      reserve_sig: EddsaSignature;
+      // Signer chosen bit value, 0 or 1, used
+      // in Clause Blind Schnorr to make the
+      // ROS problem harder.
+      b: Integer;
 
-      // Timestamp of the open request.
-      request_timestamp: Timestamp;
+      // Blinded scalar calculated from c_b.
+      s: Cs25519Scalar;
 
-      // Requested expiration.
-      requested_expiration: Timestamp;
+    }
 
-      // Requested number of free open purses.
-      requested_min_purses: Integer;
+  .. ts:def:: KycNeededRedirect
 
-    }
+    interface KycNeededRedirect {
 
-  .. ts:def:: ReserveCloseRequestTransaction
+      // Numeric `error code <error-codes>` unique to the condition.
+      // Should always be ``TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED``.
+      code: number;
 
-    interface ReserveCloseRequestTransaction {
-      type: "CLOSE";
+      // 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;
 
-      // This is a signature over
-      // a struct `TALER_ReserveClosePS` with purpose
-      // ``TALER_SIGNATURE_WALLET_RESERVE_CLOSE``.
-      reserve_sig: EddsaSignature;
+      // Hash of the payto:// account URI that identifies
+      // the account which is being KYCed.
+      h_payto:  PaytoHash;
 
-      // Target account ``payto://``, optional.
-      h_payto?: PaytoHash;
+      // Legitimization target that the merchant should
+      // use to check for its KYC status using
+      // the ``/kyc-check/$REQUIREMENT_ROW/...`` endpoint.
+      requirement_row: Integer;
 
-      // Timestamp of the close request.
-      request_timestamp: Timestamp;
     }
 
-  .. ts:def:: ReserveCreditTransaction
-
-    interface ReserveCreditTransaction {
-      type: "CREDIT";
+  .. ts:def:: WithdrawError
 
-      // Amount deposited.
-      amount: Amount;
+    interface WithdrawError {
+      // Text describing the error.
+      hint: string;
 
-      // Sender account ``payto://`` URL.
-      sender_account_url: string;
+      // Detailed error code.
+      code: Integer;
 
-      // Opaque identifier internal to the exchange that
-      // uniquely identifies the wire transfer that credited the reserve.
-      wire_reference: Integer;
+      // Amount left in the reserve.
+      balance: Amount;
 
-      // Timestamp of the incoming wire transfer.
-      timestamp: Timestamp;
+      // History of the reserve's activity, in the same format
+      // as returned by ``/reserve/$RID/history``.
+      history: TransactionHistoryItem[]
     }
 
-  .. ts:def:: PurseMergeTransaction
-
-    interface PurseMergeTransaction {
-      type: "MERGE";
-
-      // SHA-512 hash of the contact of the purse.
-      h_contract_terms: HashCode;
 
-      // EdDSA public key used to approve merges of this purse.
-      merge_pub: EddsaPublicKey;
 
-      // Minimum age required for all coins deposited into the purse.
-      min_age: Integer;
 
-      // Number that identifies who created the purse
-      // and how it was paid for.
-      flags: Integer;
+Batch Withdraw
+~~~~~~~~~~~~~~
 
-      // Purse public key.
-      purse_pub: EddsaPublicKey;
 
-      // EdDSA signature of the account/reserve affirming the merge
-      // over a `TALER_AccountMergeSignaturePS`.
-      // Must be of purpose ``TALER_SIGNATURE_ACCOUNT_MERGE``
-      reserve_sig: EddsaSignature;
+.. http:post:: /reserves/$RESERVE_PUB/batch-withdraw
 
-      // Client-side timestamp of when the merge request was made.
-      merge_timestamp: Timestamp;
+  Withdraw multiple coins from the same reserve.  Note that the client should
+  commit all of the request details, including the private key of the coins and
+  the blinding factors, to disk *before* issuing this request, so that it can
+  recover the information if necessary in case of transient failures, like
+  power outage, network outage, etc.
 
-      // Indicative time by which the purse should expire
-      // if it has not been merged into an account. At this
-      // point, all of the deposits made should be
-      // auto-refunded.
-      purse_expiration: Timestamp;
+  **Request:** The request body must be a `BatchWithdrawRequest` object.
 
-      // Purse fee the reserve owner paid for the purse creation.
-      purse_fee: Amount;
+  **Response:**
 
-      // Total amount merged into the reserve.
-      // (excludes fees).
-      amount: Amount;
+  :http:statuscode:`200 OK`:
+    The request was successful, and the response is a `BatchWithdrawResponse`.
+    Note that repeating exactly the same request will again yield the same
+    response, so if the network goes down during the transaction or before the
+    client can commit the coin signature to disk, the coin is not lost.
+  :http:statuscode:`403 Forbidden`:
+    A signature is invalid.
+    This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`404 Not found`:
+    A denomination key or the reserve are not known to the exchange.  If the
+    denomination key is unknown, this suggests a bug in the wallet as the
+    wallet should have used current denomination keys from ``/keys``.
+    In this case, the response will be a `DenominationUnknownMessage`.
+    If the reserve is unknown, the wallet should not report a hard error yet, 
but
+    instead simply wait for up to a day, as the wire transaction might simply
+    not yet have completed and might be known to the exchange in the near 
future.
+    In this case, the wallet should repeat the exact same request later again
+    using exactly the same blinded coin.
+  :http:statuscode:`409 Conflict`:
+    One of the following reasons occured:
 
-      // True if the purse was actually merged.
-      // If false, only the purse_fee has an impact
-      // on the reserve balance!
-      merged: boolean;
-    }
+    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
+    indicated denominations.  The response is `WithdrawError` object.
 
+    2. The reserve has a birthday set and requires a request to 
``/age-withdraw`` instead.
+    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED`` and an additional field 
``maximum_allowed_age`` for the maximum age (in years) that the client can 
commit to in the call to ``/age-withdraw``
+  :http:statuscode:`410 Gone`:
+    A requested denomination key is not yet or no longer valid.
+    It either before the validity start, past the expiration or was revoked.
+    The response is a `DenominationExpiredMessage`. Clients must evaluate the
+    error code provided to understand which of the cases this is and handle it
+    accordingly.
+  :http:statuscode:`451 Unavailable for Legal Reasons`:
+    This reserve has received funds from a purse or the amount withdrawn
+    exceeds another legal threshold and thus the reserve must
+    be upgraded to an account (with KYC) before the withdraw can
+    complete.  Note that this response does NOT affirm that the
+    withdraw will ultimately complete with the requested amount.
+    The user should be redirected to the provided location to perform
+    the required KYC checks to open the account before withdrawing.
+    Afterwards, the request should be repeated.
+    The response will be an `KycNeededRedirect` object.
 
-.. http:post:: /reserves/$RESERVE_PUB/history
+    Implementation note: internally, we need to
+    distinguish between upgrading the reserve to an
+    account (due to P2P payment) and identifying the
+    owner of the origin bank account (due to exceeding
+    the withdraw amount threshold), as we need to create
+    a different payto://-URI for the KYC check depending
+    on the case.
 
-  Request information about the full history of
-  a reserve or an account.
 
-  **Request:**
+  **Details:**
 
-  The request body must be a `ReserveHistoryRequest` object.
+  .. ts:def:: BatchWithdrawRequest
 
-  **Response:**
+    interface BatchWithdrawRequest {
+      // Array of requests for the individual coins to withdraw.
+      planchets: WithdrawRequest[];
 
-  :http:statuscode:`200 OK`:
-    The exchange responds with a `ReserveStatus` object; the reserve was known 
to the exchange.
-  :http:statuscode:`403 Forbidden`:
-    The *TALER_SIGNATURE_RESERVE_HISTORY_REQUEST* is invalid.
-    This response comes with a standard `ErrorDetail` response.  
Alternatively, the provided timestamp is not close to the current time.
-  :http:statuscode:`404 Not found`:
-    The reserve key does not belong to a reserve known to the exchange.
-  :http:statuscode:`412 Precondition failed`:
-    The balance in the reserve is insufficient to pay for the history request.
-    This response comes with a standard `ErrorDetail` response.
+    }
 
-  **Details:**
 
-  .. ts:def:: ReserveHistoryRequest
+  .. ts:def:: BatchWithdrawResponse
 
-    interface ReserveHistoryRequest {
-      // Signature of type
-      // ``TALER_SIGNATURE_RESERVE_HISTORY_REQUEST``
-      // over a `TALER_ReserveHistoryRequestSignaturePS`.
-      reserve_sig: EddsaSignature;
+    interface BatchWithdrawResponse {
+      // Array of blinded signatures, in the same order as was
+      // given in the request.
+      ev_sigs: WithdrawResponse[];
 
-      // Time when the client made the request.
-      // Timestamp must be reasonably close to the time of
-      // the exchange, otherwise the exchange may reject
-      // the request.
-      request_timestamp: Timestamp;
     }
 
+Withdraw with Age Restriction
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. _delete-reserve:
-
-.. http:DELETE:: /reserves/$RESERVE_PUB
+If the reserve was marked with a maximum age group, the client has to perform a
+cut&choose protocol with the exchange.  It first calls
+``/reserves/$RESERVE_PUB/age-withdraw`` and commits to ``n*kappa`` coins.  On
+success, the exchange answers this request with an noreveal-index.  The client
+then has to call ``/age-withdraw/$ACH/reveal`` to reveal all ``n*(kappa - 1)``
+coins along with their age commitments to proof that they were appropriate.
+If so, the exchange will blindly sign ``n`` undisclosed coins from the request.
 
-  Forcefully closes a reserve.
-  The request header must contain an *Account-Request-Signature*.
-  Note: this endpoint is not currently implemented!
 
-  **Request:**
+.. http:POST:: /reserves/$RESERVE_PUB/age-withdraw
 
-  *Account-Request-Signature*: The client must provide Base-32 encoded EdDSA 
signature made with ``$ACCOUNT_PRIV``, affirming its authorization to delete 
the account.  The purpose used MUST be ``TALER_SIGNATURE_RESERVE_CLOSE``.
+  Withdraw multiple coins *with age restriction* from the same reserve.
+  Note that the client should commit all of the request details, including the
+  private key of the coins and the blinding factors, to disk *before* issuing
+  this request, so that it can recover the information if necessary in case of
+  transient failures, like power outage, network outage, etc.
 
-  :query force=BOOLEAN: *Optional.*  If set to 'true' specified, the exchange
-    will delete the account even if there is a balance remaining.
+  **Request:** The request body must be a `AgeWithdrawRequest` object.
 
   **Response:**
 
   :http:statuscode:`200 OK`:
-    The operation succeeded, the exchange provides details
-    about the account deletion.
-    The response will include a `ReserveClosedResponse` object.
+    The request was successful, and the response is a `AgeWithdrawResponse`.
+    Note that repeating exactly the same request will again yield the same
+    response, so if the network goes down during the transaction or before the
+    client can commit the coin signature to disk, the coin is not lost.
   :http:statuscode:`403 Forbidden`:
-    The *Account-Request-Signature* is invalid.
+    A signature is invalid.
     This response comes with a standard `ErrorDetail` response.
-  :http:statuscode:`404 Not found`:
-    The account is unknown to the exchange.
   :http:statuscode:`409 Conflict`:
-    The account is still has digital cash in it, the associated
-    wire method is ``void`` and the *force* option was not provided.
-    This response comes with a standard `ErrorDetail` response.
-
-  **Details:**
-
-  .. ts:def:: ReserveClosedResponse
+    One of two reasons occured:
 
-     interface ReserveClosedResponse {
+    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
+    given amount.  The response is a `WithdrawError` object.
 
-      // Final balance of the account.
-      closing_amount: Amount;
-
-      // Current time of the exchange, used as part of
-      // what the exchange signs over.
-      close_time: Timestamp;
-
-      // Hash of the wire account into which the remaining
-      // balance will be transferred. Note: may be the
-      // hash over ``payto://void/`, in which case the
-      // balance is forfeit to the profit of the exchange.
-      h_wire: HashCode;
-
-      // This is a signature over a
-      // struct ``TALER_AccountDeleteConfirmationPS`` with purpose
-      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED``.
-      exchange_sig: EddsaSignature;
-
-    }
-
-
-
-Withdraw
-~~~~~~~~
-
-.. http:post:: /csr-withdraw
-
-  Obtain exchange-side input values in preparation for a
-  withdraw step for certain denomination cipher types,
-  specifically at this point for Clause-Schnorr blind
-  signatures.
-
-  **Request:** The request body must be a `WithdrawPrepareRequest` object.
-
-  **Response:**
-
-  :http:statuscode:`200 OK`:
-    The request was successful, and the response is a 
`WithdrawPrepareResponse`.  Note that repeating exactly the same request
-    will again yield the same response (assuming none of the denomination is 
expired).
-  :http:statuscode:`404 Not found`:
-    The denomination key is not known to the exchange.
+    2. The provided value for ``max_age`` is higher than the allowed value 
according to the reserve's birthday.
+    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_AGE_WITHDRAW_MAXIMUM_AGE_TOO_LARGE`` and an additional 
field ``maximum_allowed_age`` for the maximum age (in years) that the client 
can commit to in a call to ``/age-withdraw``
   :http:statuscode:`410 Gone`:
-    The requested denomination key is not yet or no longer valid.
-    It either before the validity start, past the expiration or was revoked. 
The response is a
-    `DenominationExpiredMessage`. Clients must evaluate
-    the error code provided to understand which of the
-    cases this is and handle it accordingly.
-
-  **Details:**
+    A requested denomination key is not yet or no longer valid.
+    It either before the validity start, past the expiration or was revoked.
+    The response is a `DenominationExpiredMessage`. Clients must evaluate the
+    error code provided to understand which of the cases this is and handle it
+    accordingly.
+  :http:statuscode:`451 Unavailable for Legal Reasons`:
+    This reserve has received funds from a purse or the amount withdrawn
+    exceeds another legal threshold and thus the reserve must
+    be upgraded to an account (with KYC) before the withdraw can
+    complete.  Note that this response does NOT affirm that the
+    withdraw will ultimately complete with the requested amount.
+    The user should be redirected to the provided location to perform
+    the required KYC checks to open the account before withdrawing.
+    Afterwards, the request should be repeated.
+    The response will be an `KycNeededRedirect` object.
 
-  .. ts:def:: WithdrawPrepareRequest
+  .. ts:def:: AgeWithdrawRequest
 
-    interface WithdrawPrepareRequest {
+    interface AgeWithdrawRequest {
+      // Array of ``n`` hash codes of denomination public keys to order.
+      // These denominations MUST support age restriction as defined in the
+      // output to /keys.
+      // The sum of all denomination's values and fees MUST be at most the
+      // balance of the reserve.  The balance of the reserve will be
+      // immediatley reduced by that amount.
+      denoms_h: HashCode[];
 
-      // Nonce to be used by the exchange to derive
-      // its private inputs from. Must not have ever
-      // been used before.
-      nonce: CSNonce;
+      // ``n`` arrays of ``kappa`` entries with blinded coin envelopes.  Each
+      // (toplevel)  entry represents ``kappa`` canditates for a particular
+      // coin.  The exchange  will respond with an index ``gamma``, which is
+      // the index that shall remain undisclosed during the reveal phase.
+      // The SHA512 hash $ACH over the blinded coin envelopes is the commitment
+      // that is later used as the key to the reveal-URL.
+      blinded_coins_evs:  CoinEnvelope[][];
 
-      // Hash of the public key of the denomination the
-      // request relates to.
-      denom_pub_hash: HashCode;
+      // The maximum age to commit to.  MUST be the same as the maximum
+      // age in the reserve.
+      max_age: number;
 
+      // Signature of `TALER_AgeWithdrawRequestPS` created with
+      // the `reserves's private key <reserve-priv>`
+      // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``.
+      reserve_sig: EddsaSignature;
     }
 
-  .. ts:def:: WithdrawPrepareResponse
-
-    type WithdrawPrepareResponse =
-      | ExchangeWithdrawValue;
-
-  .. ts:def:: ExchangeWithdrawValue
+  .. ts:def:: AgeWithdrawResponse
 
-    type ExchangeWithdrawValue =
-      | ExchangeRsaWithdrawValue
-      | ExchangeCsWithdrawValue;
+    interface AgeWithdrawResponse {
+      // index of the commitments that the client doesn't
+      // have to disclose
+      noreveal_index: Integer;
 
-  .. ts:def:: ExchangeRsaWithdrawValue
+      // Signature of `TALER_AgeWithdrawConfirmationPS` whereby
+      // the exchange confirms the ``noreveal_index``.
+      exchange_sig: EddsaSignature;
 
-    interface ExchangeRsaWithdrawValue {
-      cipher: "RSA";
+      // `Public EdDSA key <sign-key-pub>` of the exchange that was used to
+      // generate the signature.  Should match one of the exchange's signing
+      // keys from ``/keys``.  Again given explicitly as the client might
+      // otherwise be confused by clock skew as to which signing key was used.
+      exchange_pub: EddsaPublicKey;
     }
 
-  .. ts:def:: ExchangeCsWithdrawValue
-
-    interface ExchangeCsWithdrawValue {
-      cipher: "CS";
-
-      // CSR R0 value
-      r_pub_0: CsRPublic;
 
-      // CSR R1 value
-      r_pub_1: CsRPublic;
-    }
 
+.. http:POST:: /age-withdraw/$ACH/reveal
 
-.. http:post:: /reserves/$RESERVE_PUB/withdraw
+  The client has previously committed to multiple coins with age restriction
+  in a call to ``/reserve/$RESERVE_PUB/age-withdraw`` and got a
+  `AgeWithdrawResponse` from the exchange.  By calling this
+  endpoint, the client has to reveal each coin and their ``kappa - 1``
+  age commitments, except for the age commitments with index
+  ``noreveal_index``.  The hash of all commitments from the former withdraw
+  request is given as the ``$ACH`` value in the URL to this endpoint.
 
-  Withdraw a coin of the specified denomination.  Note that the client should
-  commit all of the request details, including the private key of the coin and
-  the blinding factor, to disk *before* issuing this request, so that it can
-  recover the information if necessary in case of transient failures, like
-  power outage, network outage, etc.
 
-  **Request:** The request body must be a `WithdrawRequest` object.
+  **Request:** The request body must be a `AgeWithdrawRevealRequest` object.
 
   **Response:**
 
   :http:statuscode:`200 OK`:
-    The request was successful, and the response is a `WithdrawResponse`.  
Note that repeating exactly the same request
-    will again yield the same response, so if the network goes down during the
-    transaction or before the client can commit the coin signature to disk, the
-    coin is not lost.
-  :http:statuscode:`403 Forbidden`:
-    The signature is invalid.
-    This response comes with a standard `ErrorDetail` response.
+    The request was successful, and the response is a 
`AgeWithdrawRevealResponse`.
+    Note that repeating exactly the same request will again yield the same
+    response, so if the network goes down during the transaction or before the
+    client can commit the coin signature to disk, the coin is not lost.
   :http:statuscode:`404 Not found`:
-    The denomination key or the reserve are not known to the exchange.  If the
-    denomination key is unknown, this suggests a bug in the wallet as the
-    wallet should have used current denomination keys from ``/keys``.
-    In this case, the response will be a `DenominationUnknownMessage`.
-    If the reserve is unknown, the wallet should not report a hard error yet, 
but
-    instead simply wait for up to a day, as the wire transaction might simply
-    not yet have completed and might be known to the exchange in the near 
future.
-    In this case, the wallet should repeat the exact same request later again
-    using exactly the same blinded coin.
+    The provided commitment $ACH is unknown.
   :http:statuscode:`409 Conflict`:
-    One of the following reasons occured:
+    The reveal operation failed and the response is an `WithdrawError` object.
+    The error codes indicate one of two cases:
 
-    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
-    indicated denominations.  The response is `WithdrawError` object.
+    1. An age commitment for at least one of the coins did not fulfill the
+       required maximum age requirement of the corresponding reserve.
+       Error code:
+       ``TALER_EC_EXCHANGE_GENERIC_COIN_AGE_REQUIREMENT_FAILURE``.
+    2. The computation of the hash of the commitment with provided input does
+       result in the value $ACH.
+       Error code:
+       ``TALER_EC_EXCHANGE_AGE_WITHDRAW_REVEAL_INVALID_HASH``
 
-    2. The reserve has a birthday set and requires a request to 
``/age-withdraw`` instead.
-    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED`` and an additional field 
``maximum_allowed_age`` for the maximum age (in years) that the client can 
commit to in the call to ``/age-withdraw``
-  :http:statuscode:`410 Gone`:
-    The requested denomination key is not yet or no longer valid.
-    It either before the validity start, past the expiration or was revoked. 
The response is a
-    `DenominationExpiredMessage`. Clients must evaluate
-    the error code provided to understand which of the
-    cases this is and handle it accordingly.
-  :http:statuscode:`451 Unavailable for Legal Reasons`:
-    This reserve has received funds from a purse or the amount withdrawn
-    exceeds another legal threshold and thus the reserve must
-    be upgraded to an account (with KYC) before the withdraw can
-    complete.  Note that this response does NOT affirm that the
-    withdraw will ultimately complete with the requested amount.
-    The user should be redirected to the provided location to perform
-    the required KYC checks to open the account before withdrawing.
-    Afterwards, the request should be repeated.
-    The response will be an `KycNeededRedirect` object.
 
-    Implementation note: internally, we need to
-    distinguish between upgrading the reserve to an
-    account (due to P2P payment) and identifying the
-    owner of the origin bank account (due to exceeding
-    the withdraw amount threshold), as we need to create
-    a different payto://-URI for the KYC check depending
-    on the case.
+  .. ts:def:: AgeWithdrawRevealRequest
 
+    interface AgeWithdrawRevealRequest {
+      // Array of ``n`` of ``(kappa - 1)`` disclosed coin master secrets, from
+      // which the coins' private key, blinding, nonce (for Clause-Schnorr) and
+      // age-restriction  is calculated.
+      //
+      // Given each coin's private key and age commitment, the exchange will
+      // calculate each coin's blinded hash value und use all those (disclosed)
+      // blinded hashes together with the non-disclosed envelopes ``coin_evs``
+      // during the verification of the original age-withdraw-commitment.
+      disclosed_coin_secrets: AgeRestrictedCoinSecret[][];
+    }
 
-  **Details:**
+  .. ts:def:: AgeRestrictedCoinSecret
 
-  .. ts:def:: DenominationExpiredMessage
+    // The Master key material from which the coins' private key ``coin_priv``,
+    // blinding ``beta`` and nonce ``nonce`` (for Clause-Schnorr) itself are
+    // derived as usually in wallet-core.  Given a coin's master key material,
+    // the age commitment for the coin MUST be derived from this private key as
+    // follows:
+    //
+    // Let m ∈  {1,...,M} be the maximum age group as defined in the reserve
+    // that the wallet can commit to.
+    //
+    // For age group $AG ∈  {1,...m}, set
+    //     seed = HDKF(coin_secret, "age-commitment", $AG)
+    //   p[$AG] = Edx25519_generate_private(seed)
+    // and calculate the corresponding Edx25519PublicKey as
+    //   q[$AG] = Edx25519_public_from_private(p[$AG])
+    //
+    // For age groups $AG ∈  {m,...,M}, set
+    //   f[$AG] = HDKF(coin_secret, "age-factor", $AG)
+    // and calculate the corresponding Edx25519PublicKey as
+    //   q[$AG] = Edx25519_derive_public(`PublishedAgeRestrictionBaseKey`, 
f[$AG])
+    //
+    type AgeRestrictedCoinSecret = string;
 
-    interface DenominationExpiredMessage {
+  .. ts:def:: PublishedAgeRestrictionBaseKey
 
-      // Taler error code.  Note that beyond
-      // expiration this message format is also
-      // used if the key is not yet valid, or
-      // has been revoked.
-      code: number;
+    // The value for ``PublishedAgeRestrictionBaseKey`` is a randomly chosen
+    // `Edx25519PublicKey` for which the private key is not known to the 
clients.  It is
+    // used during the age-withdraw protocol so that clients can proof that 
they
+    // derived all public keys to age groups higher than their allowed maximum
+    // from this particular value.
+    const PublishedAgeRestrictionBaseKey =
+        new 
Edx25519PublicKey("CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG");
 
-      // Signature by the exchange over a
-      // `TALER_DenominationExpiredAffirmationPS`.
-      // Must have purpose ``TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED``.
-      exchange_sig: EddsaSignature;
+  .. ts:def:: AgeWithdrawRevealResponse
 
-      // Public key of the exchange used to create
-      // the 'exchange_sig.
-      exchange_pub: EddsaPublicKey;
+    interface AgeWithdrawRevealResponse {
+      // List of the exchange's blinded RSA signatures on the new coins.
+      ev_sigs : BlindedDenominationSignature[];
+    }
 
-      // Hash of the denomination public key that is unknown.
-      h_denom_pub: HashCode;
 
-      // When was the signature created.
-      timestamp: Timestamp;
+.. _reserve-history:
 
-      // What kind of operation was requested that now
-      // failed?
-      oper: string;
-    }
+---------------
+Reserve History
+---------------
 
+.. http:get:: /reserves/$RESERVE_PUB/history
 
-  .. ts:def:: WithdrawRequest
+  Request information about the full history of
+  a reserve or an account.
 
-    interface WithdrawRequest {
-      // Hash of a denomination public key (RSA), specifying the type of coin 
the client
-      // would like the exchange to create.
-      denom_pub_hash: HashCode;
+  **Request:**
 
-      // Coin's blinded public key, should be (blindly) signed by the 
exchange's
-      // denomination private key.
-      coin_ev: CoinEnvelope;
+  The GET request should come with the following HTTP headers:
 
-      // Signature of `TALER_WithdrawRequestPS` created with
-      // the `reserves's private key <reserve-priv>`
-      // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``.
-      reserve_sig: EddsaSignature;
+  *If-None-Match*: The client MAY provide an ``If-None-Match`` header with an
+  Etag.  In that case, the server MUST additionally respond with an ``304``
+  status code in case the reserve history matches the provided Etag.
 
-    }
+  *Taler-Reserve-History-Signature*: The client MUST provide Base-32 encoded
+   EdDSA signature over a TALER_SIGNATURE_RESERVE_HISTORY_REQUEST made with
+   the respective ``$RESERVE_PRIV``, affirming desire to download the current
+   reserve transaction history.
 
-  .. ts:def:: WithdrawResponse
+  :query start=OFFSET: *Optional.* Only return reserve history entries with
+                       offsets above the given OFFSET. Allows clients to not
+                       retrieve history entries they already have.
 
-    interface WithdrawResponse {
-      // The blinded signature over the 'coin_ev', affirms the coin's
-      // validity after unblinding.
-      ev_sig: BlindedDenominationSignature;
+  **Response:**
 
-    }
+  :http:statuscode:`200 OK`:
+    The exchange responds with a `ReserveHistory` object; the reserve was 
known to the exchange.
+  :http:statuscode:`204 No content`:
+    The reserve history is known, but at this point from the given starting 
point it is empty. Can only happen if OFFSET was positive.
+  :http:statuscode:`304 Not modified`:
+    The reserve history matches the one identified by the "If-none-match" HTTP 
header of the request.
+  :http:statuscode:`403 Forbidden`:
+    The *TALER_SIGNATURE_RESERVE_HISTORY_REQUEST* is invalid.
+    This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`404 Not found`:
+    The reserve key does not belong to a reserve known to the exchange.
 
-  .. ts:def:: BlindedDenominationSignature
+  **Details:**
 
-    type BlindedDenominationSignature =
-      | RsaBlindedDenominationSignature
-      | CSBlindedDenominationSignature;
+  .. ts:def:: ReserveHistory
 
-  .. ts:def:: RsaBlindedDenominationSignature
+    interface ReserveHistory {
+      // Balance left in the reserve.
+      balance: Amount;
 
-    interface RsaBlindedDenominationSignature {
-      cipher: "RSA";
+      // If set, gives the maximum age group that the client is required to set
+      // during withdrawal.
+      maximum_age_group: number;
 
-      // (blinded) RSA signature
-      blinded_rsa_signature: BlindedRsaSignature;
+      // Transaction history for this reserve.
+      // May be partial (!).
+      history: TransactionHistoryItem[];
     }
 
-  .. ts:def:: CSBlindedDenominationSignature
-
-    interface CSBlindedDenominationSignature {
-      type: "CS";
+  Objects in the transaction history have the following format:
 
-      // Signer chosen bit value, 0 or 1, used
-      // in Clause Blind Schnorr to make the
-      // ROS problem harder.
-      b: Integer;
+  .. ts:def:: TransactionHistoryItem
 
-      // Blinded scalar calculated from c_b.
-      s: Cs25519Scalar;
+    // Union discriminated by the "type" field.
+    type TransactionHistoryItem =
+      | AccountSetupTransaction
+      | ReserveWithdrawTransaction
+      | ReserveAgeWithdrawTransaction
+      | ReserveCreditTransaction
+      | ReserveClosingTransaction
+      | ReserveOpenRequestTransaction
+      | ReserveCloseRequestTransaction
+      | PurseMergeTransaction;
 
-    }
+  .. ts:def:: AccountSetupTransaction
 
-  .. ts:def:: KycNeededRedirect
+    interface AccountSetupTransaction {
+      type: "SETUP";
 
-    interface KycNeededRedirect {
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-      // Numeric `error code <error-codes>` unique to the condition.
-      // Should always be ``TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED``.
-      code: number;
+      // KYC fee agreed to by the reserve owner.
+      kyc_fee: Amount;
 
-      // 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;
+      // Time when the KYC was triggered.
+      kyc_timestamp: Timestamp;
 
-      // Hash of the payto:// account URI that identifies
-      // the account which is being KYCed.
-      h_payto:  PaytoHash;
+      // Hash of the wire details of the account.
+      // Note that this hash is unsalted and potentially
+      // private (as it could be inverted), hence access
+      // to this endpoint must be authorized using the
+      // private key of the reserve.
+      h_wire: HashCode;
 
-      // Legitimization target that the merchant should
-      // use to check for its KYC status using
-      // the ``/kyc-check/$REQUIREMENT_ROW/...`` endpoint.
-      requirement_row: Integer;
+      // Signature created with the reserve's private key.
+      // Must be of purpose ``TALER_SIGNATURE_ACCOUNT_SETUP_REQUEST`` over
+      // a ``TALER_AccountSetupRequestSignaturePS``.
+      reserve_sig: EddsaSignature;
 
     }
 
-  .. ts:def:: WithdrawError
+  .. ts:def:: ReserveWithdrawTransaction
 
-    interface WithdrawError {
-      // Text describing the error.
-      hint: string;
+    interface ReserveWithdrawTransaction {
+      type: "WITHDRAW";
 
-      // Detailed error code.
-      code: Integer;
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-      // Amount left in the reserve.
-      balance: Amount;
+      // Amount withdrawn.
+      amount: Amount;
 
-      // History of the reserve's activity, in the same format
-      // as returned by ``/reserve/$RID/history``.
-      history: TransactionHistoryItem[]
-    }
+      // Hash of the denomination public key of the coin.
+      h_denom_pub: HashCode;
 
+      // Hash of the blinded coin to be signed.
+      h_coin_envelope: HashCode;
 
+      // Signature over a `TALER_WithdrawRequestPS`
+      // with purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``
+      // created with the reserve's private key.
+      reserve_sig: EddsaSignature;
 
+      // Fee that is charged for withdraw.
+      withdraw_fee: Amount;
+     }
 
-Batch Withdraw
-~~~~~~~~~~~~~~
+  .. ts:def:: ReserveAgeWithdrawTransaction
 
+    interface ReserveAgeWithdrawTransaction {
+      type: "AGEWITHDRAW";
 
-.. http:post:: /reserves/$RESERVE_PUB/batch-withdraw
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-  Withdraw multiple coins from the same reserve.  Note that the client should
-  commit all of the request details, including the private key of the coins and
-  the blinding factors, to disk *before* issuing this request, so that it can
-  recover the information if necessary in case of transient failures, like
-  power outage, network outage, etc.
+      // Total Amount withdrawn.
+      amount: Amount;
 
-  **Request:** The request body must be a `BatchWithdrawRequest` object.
+      // Commitment of all ``n*kappa`` blinded coins.
+      h_commitment: HashCode;
 
-  **Response:**
+      // Signature over a `TALER_AgeWithdrawRequestPS`
+      // with purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``
+      // created with the reserve's private key.
+      reserve_sig: EddsaSignature;
 
-  :http:statuscode:`200 OK`:
-    The request was successful, and the response is a `BatchWithdrawResponse`.
-    Note that repeating exactly the same request will again yield the same
-    response, so if the network goes down during the transaction or before the
-    client can commit the coin signature to disk, the coin is not lost.
-  :http:statuscode:`403 Forbidden`:
-    A signature is invalid.
-    This response comes with a standard `ErrorDetail` response.
-  :http:statuscode:`404 Not found`:
-    A denomination key or the reserve are not known to the exchange.  If the
-    denomination key is unknown, this suggests a bug in the wallet as the
-    wallet should have used current denomination keys from ``/keys``.
-    In this case, the response will be a `DenominationUnknownMessage`.
-    If the reserve is unknown, the wallet should not report a hard error yet, 
but
-    instead simply wait for up to a day, as the wire transaction might simply
-    not yet have completed and might be known to the exchange in the near 
future.
-    In this case, the wallet should repeat the exact same request later again
-    using exactly the same blinded coin.
-  :http:statuscode:`409 Conflict`:
-    One of the following reasons occured:
+      // Fee that is charged for withdraw.
+      withdraw_fee: Amount;
+     }
 
-    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
-    indicated denominations.  The response is `WithdrawError` object.
 
-    2. The reserve has a birthday set and requires a request to 
``/age-withdraw`` instead.
-    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_RESERVES_AGE_RESTRICTION_REQUIRED`` and an additional field 
``maximum_allowed_age`` for the maximum age (in years) that the client can 
commit to in the call to ``/age-withdraw``
-  :http:statuscode:`410 Gone`:
-    A requested denomination key is not yet or no longer valid.
-    It either before the validity start, past the expiration or was revoked.
-    The response is a `DenominationExpiredMessage`. Clients must evaluate the
-    error code provided to understand which of the cases this is and handle it
-    accordingly.
-  :http:statuscode:`451 Unavailable for Legal Reasons`:
-    This reserve has received funds from a purse or the amount withdrawn
-    exceeds another legal threshold and thus the reserve must
-    be upgraded to an account (with KYC) before the withdraw can
-    complete.  Note that this response does NOT affirm that the
-    withdraw will ultimately complete with the requested amount.
-    The user should be redirected to the provided location to perform
-    the required KYC checks to open the account before withdrawing.
-    Afterwards, the request should be repeated.
-    The response will be an `KycNeededRedirect` object.
+  .. ts:def:: ReserveCreditTransaction
 
-    Implementation note: internally, we need to
-    distinguish between upgrading the reserve to an
-    account (due to P2P payment) and identifying the
-    owner of the origin bank account (due to exceeding
-    the withdraw amount threshold), as we need to create
-    a different payto://-URI for the KYC check depending
-    on the case.
+    interface ReserveCreditTransaction {
+      type: "CREDIT";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-  **Details:**
+      // Amount deposited.
+      amount: Amount;
 
-  .. ts:def:: BatchWithdrawRequest
+      // Sender account ``payto://`` URL.
+      sender_account_url: string;
 
-    interface BatchWithdrawRequest {
-      // Array of requests for the individual coins to withdraw.
-      planchets: WithdrawRequest[];
+      // Opaque identifier internal to the exchange that
+      // uniquely identifies the wire transfer that credited the reserve.
+      wire_reference: Integer;
 
+      // Timestamp of the incoming wire transfer.
+      timestamp: Timestamp;
     }
 
 
-  .. ts:def:: BatchWithdrawResponse
+  .. ts:def:: ReserveClosingTransaction
 
-    interface BatchWithdrawResponse {
-      // Array of blinded signatures, in the same order as was
-      // given in the request.
-      ev_sigs: WithdrawResponse[];
+    interface ReserveClosingTransaction {
+      type: "CLOSING";
 
-    }
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-Withdraw with Age Restriction
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+      // Closing balance.
+      amount: Amount;
 
-If the reserve was marked with a maximum age group, the client has to perform a
-cut&choose protocol with the exchange.  It first calls
-``/reserves/$RESERVE_PUB/age-withdraw`` and commits to ``n*kappa`` coins.  On
-success, the exchange answers this request with an noreveal-index.  The client
-then has to call ``/age-withdraw/$ACH/reveal`` to reveal all ``n*(kappa - 1)``
-coins along with their age commitments to proof that they were appropriate.
-If so, the exchange will blindly sign ``n`` undisclosed coins from the request.
+      // Closing fee charged by the exchange.
+      closing_fee: Amount;
 
+      // Wire transfer subject.
+      wtid: Base32;
 
-.. http:POST:: /reserves/$RESERVE_PUB/age-withdraw
+      // ``payto://`` URI of the wire account into which the funds were 
returned to.
+      receiver_account_details: string;
 
-  Withdraw multiple coins *with age restriction* from the same reserve.
-  Note that the client should commit all of the request details, including the
-  private key of the coins and the blinding factors, to disk *before* issuing
-  this request, so that it can recover the information if necessary in case of
-  transient failures, like power outage, network outage, etc.
+      // This is a signature over a
+      // struct `TALER_ReserveCloseConfirmationPS` with purpose
+      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED``.
+      exchange_sig: EddsaSignature;
 
-  **Request:** The request body must be a `AgeWithdrawRequest` object.
+      // Public key used to create 'exchange_sig'.
+      exchange_pub: EddsaPublicKey;
 
-  **Response:**
+      // Time when the reserve was closed.
+      timestamp: Timestamp;
+    }
 
-  :http:statuscode:`200 OK`:
-    The request was successful, and the response is a `AgeWithdrawResponse`.
-    Note that repeating exactly the same request will again yield the same
-    response, so if the network goes down during the transaction or before the
-    client can commit the coin signature to disk, the coin is not lost.
-  :http:statuscode:`403 Forbidden`:
-    A signature is invalid.
-    This response comes with a standard `ErrorDetail` response.
-  :http:statuscode:`409 Conflict`:
-    One of two reasons occured:
 
-    1. The balance of the reserve is not sufficient to withdraw the coins of 
the
-    given amount.  The response is a `WithdrawError` object.
+  .. ts:def:: ReserveOpenRequestTransaction
 
-    2. The provided value for ``max_age`` is higher than the allowed value 
according to the reserve's birthday.
-    The response comes with a standard `ErrorDetail` response with error-code 
``TALER_EC_EXCHANGE_AGE_WITHDRAW_MAXIMUM_AGE_TOO_LARGE`` and an additional 
field ``maximum_allowed_age`` for the maximum age (in years) that the client 
can commit to in a call to ``/age-withdraw``
-  :http:statuscode:`410 Gone`:
-    A requested denomination key is not yet or no longer valid.
-    It either before the validity start, past the expiration or was revoked.
-    The response is a `DenominationExpiredMessage`. Clients must evaluate the
-    error code provided to understand which of the cases this is and handle it
-    accordingly.
-  :http:statuscode:`451 Unavailable for Legal Reasons`:
-    This reserve has received funds from a purse or the amount withdrawn
-    exceeds another legal threshold and thus the reserve must
-    be upgraded to an account (with KYC) before the withdraw can
-    complete.  Note that this response does NOT affirm that the
-    withdraw will ultimately complete with the requested amount.
-    The user should be redirected to the provided location to perform
-    the required KYC checks to open the account before withdrawing.
-    Afterwards, the request should be repeated.
-    The response will be an `KycNeededRedirect` object.
+    interface ReserveOpenRequestTransaction {
+      type: "OPEN";
+
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-  .. ts:def:: AgeWithdrawRequest
+      // Open fee paid from the reserve.
+      open_fee: Amount;
 
-    interface AgeWithdrawRequest {
-      // Array of ``n`` hash codes of denomination public keys to order.
-      // These denominations MUST support age restriction as defined in the
-      // output to /keys.
-      // The sum of all denomination's values and fees MUST be at most the
-      // balance of the reserve.  The balance of the reserve will be
-      // immediatley reduced by that amount.
-      denoms_h: HashCode[];
+      // This is a signature over
+      // a struct `TALER_ReserveOpenPS` with purpose
+      // ``TALER_SIGNATURE_WALLET_RESERVE_OPEN``.
+      reserve_sig: EddsaSignature;
 
-      // ``n`` arrays of ``kappa`` entries with blinded coin envelopes.  Each
-      // (toplevel)  entry represents ``kappa`` canditates for a particular
-      // coin.  The exchange  will respond with an index ``gamma``, which is
-      // the index that shall remain undisclosed during the reveal phase.
-      // The SHA512 hash $ACH over the blinded coin envelopes is the commitment
-      // that is later used as the key to the reveal-URL.
-      blinded_coins_evs:  CoinEnvelope[][];
+      // Timestamp of the open request.
+      request_timestamp: Timestamp;
 
-      // The maximum age to commit to.  MUST be the same as the maximum
-      // age in the reserve.
-      max_age: number;
+      // Requested expiration.
+      requested_expiration: Timestamp;
+
+      // Requested number of free open purses.
+      requested_min_purses: Integer;
 
-      // Signature of `TALER_AgeWithdrawRequestPS` created with
-      // the `reserves's private key <reserve-priv>`
-      // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_AGE_WITHDRAW``.
-      reserve_sig: EddsaSignature;
     }
 
-  .. ts:def:: AgeWithdrawResponse
+  .. ts:def:: ReserveCloseRequestTransaction
 
-    interface AgeWithdrawResponse {
-      // index of the commitments that the client doesn't
-      // have to disclose
-      noreveal_index: Integer;
+    interface ReserveCloseRequestTransaction {
+      type: "CLOSE";
 
-      // Signature of `TALER_AgeWithdrawConfirmationPS` whereby
-      // the exchange confirms the ``noreveal_index``.
-      exchange_sig: EddsaSignature;
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-      // `Public EdDSA key <sign-key-pub>` of the exchange that was used to
-      // generate the signature.  Should match one of the exchange's signing
-      // keys from ``/keys``.  Again given explicitly as the client might
-      // otherwise be confused by clock skew as to which signing key was used.
-      exchange_pub: EddsaPublicKey;
+      // This is a signature over
+      // a struct `TALER_ReserveClosePS` with purpose
+      // ``TALER_SIGNATURE_WALLET_RESERVE_CLOSE``.
+      reserve_sig: EddsaSignature;
+
+      // Target account ``payto://``, optional.
+      h_payto?: PaytoHash;
+
+      // Timestamp of the close request.
+      request_timestamp: Timestamp;
     }
 
+  .. ts:def:: ReserveCreditTransaction
 
+    interface ReserveCreditTransaction {
+      type: "CREDIT";
 
-.. http:POST:: /age-withdraw/$ACH/reveal
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-  The client has previously committed to multiple coins with age restriction
-  in a call to ``/reserve/$RESERVE_PUB/age-withdraw`` and got a
-  `AgeWithdrawResponse` from the exchange.  By calling this
-  endpoint, the client has to reveal each coin and their ``kappa - 1``
-  age commitments, except for the age commitments with index
-  ``noreveal_index``.  The hash of all commitments from the former withdraw
-  request is given as the ``$ACH`` value in the URL to this endpoint.
+      // Amount deposited.
+      amount: Amount;
 
+      // Sender account ``payto://`` URL.
+      sender_account_url: string;
 
-  **Request:** The request body must be a `AgeWithdrawRevealRequest` object.
+      // Opaque identifier internal to the exchange that
+      // uniquely identifies the wire transfer that credited the reserve.
+      wire_reference: Integer;
 
-  **Response:**
+      // Timestamp of the incoming wire transfer.
+      timestamp: Timestamp;
+    }
 
-  :http:statuscode:`200 OK`:
-    The request was successful, and the response is a 
`AgeWithdrawRevealResponse`.
-    Note that repeating exactly the same request will again yield the same
-    response, so if the network goes down during the transaction or before the
-    client can commit the coin signature to disk, the coin is not lost.
-  :http:statuscode:`404 Not found`:
-    The provided commitment $ACH is unknown.
-  :http:statuscode:`409 Conflict`:
-    The reveal operation failed and the response is an `WithdrawError` object.
-    The error codes indicate one of two cases:
+  .. ts:def:: PurseMergeTransaction
 
-    1. An age commitment for at least one of the coins did not fulfill the
-       required maximum age requirement of the corresponding reserve.
-       Error code:
-       ``TALER_EC_EXCHANGE_GENERIC_COIN_AGE_REQUIREMENT_FAILURE``.
-    2. The computation of the hash of the commitment with provided input does
-       result in the value $ACH.
-       Error code:
-       ``TALER_EC_EXCHANGE_AGE_WITHDRAW_REVEAL_INVALID_HASH``
+    interface PurseMergeTransaction {
+      type: "MERGE";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
 
-  .. ts:def:: AgeWithdrawRevealRequest
+      // SHA-512 hash of the contact of the purse.
+      h_contract_terms: HashCode;
 
-    interface AgeWithdrawRevealRequest {
-      // Array of ``n`` of ``(kappa - 1)`` disclosed coin master secrets, from
-      // which the coins' private key, blinding, nonce (for Clause-Schnorr) and
-      // age-restriction  is calculated.
-      //
-      // Given each coin's private key and age commitment, the exchange will
-      // calculate each coin's blinded hash value und use all those (disclosed)
-      // blinded hashes together with the non-disclosed envelopes ``coin_evs``
-      // during the verification of the original age-withdraw-commitment.
-      disclosed_coin_secrets: AgeRestrictedCoinSecret[][];
-    }
+      // EdDSA public key used to approve merges of this purse.
+      merge_pub: EddsaPublicKey;
 
-  .. ts:def:: AgeRestrictedCoinSecret
+      // Minimum age required for all coins deposited into the purse.
+      min_age: Integer;
 
-    // The Master key material from which the coins' private key ``coin_priv``,
-    // blinding ``beta`` and nonce ``nonce`` (for Clause-Schnorr) itself are
-    // derived as usually in wallet-core.  Given a coin's master key material,
-    // the age commitment for the coin MUST be derived from this private key as
-    // follows:
-    //
-    // Let m ∈  {1,...,M} be the maximum age group as defined in the reserve
-    // that the wallet can commit to.
-    //
-    // For age group $AG ∈  {1,...m}, set
-    //     seed = HDKF(coin_secret, "age-commitment", $AG)
-    //   p[$AG] = Edx25519_generate_private(seed)
-    // and calculate the corresponding Edx25519PublicKey as
-    //   q[$AG] = Edx25519_public_from_private(p[$AG])
-    //
-    // For age groups $AG ∈  {m,...,M}, set
-    //   f[$AG] = HDKF(coin_secret, "age-factor", $AG)
-    // and calculate the corresponding Edx25519PublicKey as
-    //   q[$AG] = Edx25519_derive_public(`PublishedAgeRestrictionBaseKey`, 
f[$AG])
-    //
-    type AgeRestrictedCoinSecret = string;
+      // Number that identifies who created the purse
+      // and how it was paid for.
+      flags: Integer;
 
-  .. ts:def:: PublishedAgeRestrictionBaseKey
+      // Purse public key.
+      purse_pub: EddsaPublicKey;
 
-    // The value for ``PublishedAgeRestrictionBaseKey`` is a randomly chosen
-    // `Edx25519PublicKey` for which the private key is not known to the 
clients.  It is
-    // used during the age-withdraw protocol so that clients can proof that 
they
-    // derived all public keys to age groups higher than their allowed maximum
-    // from this particular value.
-    const PublishedAgeRestrictionBaseKey =
-        new 
Edx25519PublicKey("CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG");
+      // EdDSA signature of the account/reserve affirming the merge
+      // over a `TALER_AccountMergeSignaturePS`.
+      // Must be of purpose ``TALER_SIGNATURE_ACCOUNT_MERGE``
+      reserve_sig: EddsaSignature;
 
-  .. ts:def:: AgeWithdrawRevealResponse
+      // Client-side timestamp of when the merge request was made.
+      merge_timestamp: Timestamp;
 
-    interface AgeWithdrawRevealResponse {
-      // List of the exchange's blinded RSA signatures on the new coins.
-      ev_sigs : BlindedDenominationSignature[];
+      // Indicative time by which the purse should expire
+      // if it has not been merged into an account. At this
+      // point, all of the deposits made should be
+      // auto-refunded.
+      purse_expiration: Timestamp;
+
+      // Purse fee the reserve owner paid for the purse creation.
+      purse_fee: Amount;
+
+      // Total amount merged into the reserve.
+      // (excludes fees).
+      amount: Amount;
+
+      // True if the purse was actually merged.
+      // If false, only the purse_fee has an impact
+      // on the reserve balance!
+      merged: boolean;
     }
 
 
@@ -2640,7 +2576,7 @@ If so, the exchange will blindly sign ``n`` undisclosed 
coins from the request.
 Coin History
 ------------
 
-.. http:GET:: /coins/$COIN_PUB
+.. http:GET:: /coins/$COIN_PUB/history
 
   Obtain the transaction history of a coin.  Used only in special cases, like
   when the exchange claims a double-spending error and the wallet does not
@@ -2649,17 +2585,35 @@ Coin History
 
   **Request:**
 
-  If possible, clients should set an "If-none-match" HTTP header based on a
-  previous "Etag" returned by the exchange.
+  The GET request should come with the following HTTP headers:
+
+  *If-None-Match*: The client MAY provide an ``If-None-Match`` header with an
+  Etag.  In that case, the server MUST additionally respond with an ``304``
+  status code in case the coin history matches the provided Etag.
+
+  *Taler-Coin-History-Signature*: The client MUST provide Base-32 encoded
+   EdDSA signature over a TALER_SIGNATURE_COIN_HISTORY_REQUEST made with
+   the respective ``$RESERVE_PRIV``, affirming desire to download the current
+   coin transaction history.
+
+   :query start=OFFSET: *Optional.* Only return coin history entries with
+                       offsets above the given OFFSET. Allows clients to not
+                       retrieve history entries they already have.
+
 
   **Response:**
 
   :http:statuscode:`200 OK`:
     The operation succeeded, the exchange confirms that no double-spending took
     place.  The response will include a `CoinHistoryResponse` object.
+  :http:statuscode:`204 No content`:
+    The reserve history is known, but at this point from the given starting 
point it is empty. Can only happen if OFFSET was positive.
   :http:statuscode:`304 Not modified`:
     The coin history has not changed since the previous query (detected via 
Etag
     in "If-none-match" header).
+  :http:statuscode:`403 Forbidden`:
+    The *TALER_SIGNATURE_COIN_HISTORY_REQUEST* is invalid.
+    This response comes with a standard `ErrorDetail` response.
   :http:statuscode:`404 Not found`:
     The coin public key is not (yet) known to the exchange.
 
@@ -2689,6 +2643,11 @@ Coin History
     interface CoinDepositTransaction {
       type: "DEPOSIT";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed (or restored in the
       // case of a refund) by this transaction.
       // The amount given includes
@@ -2732,6 +2691,11 @@ Coin History
     interface CoinMeltTransaction {
       type: "MELT";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed by this transaction.
       // Note that for melt this means the amount given includes
       // the melt fee. The current coin value can thus be computed by
@@ -2761,6 +2725,11 @@ Coin History
     interface CoinRefundTransaction {
       type: "REFUND";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value restored
       // by this transaction.
       // The amount given excludes the transaction fee.
@@ -2791,6 +2760,11 @@ Coin History
     interface CoinRecoupTransaction {
       type: "RECOUP";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed
       // by this transaction.
       // The current coin value can thus be computed by
@@ -2832,6 +2806,11 @@ Coin History
     interface CoinOldCoinRecoupTransaction {
       type: "OLD-COIN-RECOUP";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value restored
       // by this transaction.
       // The current coin value can thus be computed by
@@ -2856,6 +2835,11 @@ Coin History
     interface CoinRecoupRefreshTransaction {
       type: "RECOUP-REFRESH";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed
       // by this transaction.
       // The current coin value can thus be computed by
@@ -2898,6 +2882,11 @@ Coin History
     interface CoinPurseDepositTransaction {
       type: "PURSE-DEPOSIT";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed
       // by this transaction.
       // Note that this means the amount given includes
@@ -2932,6 +2921,11 @@ Coin History
     interface CoinPurseRefundTransaction {
       type: "PURSE-REFUND";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value restored
       // by this transaction.
       // The amount given excludes the refund fee.
@@ -2961,6 +2955,11 @@ Coin History
     interface CoinReserveOpenDepositTransaction {
       type: "RESERVE-OPEN-DEPOSIT";
 
+      // Offset of this entry in the reserve history.
+      // Useful to request incremental histories via
+      // the "start" query parameter.
+      history_offset: Integer;
+
       // The total amount of the coin's value absorbed
       // by this transaction.
       // Note that this means the amount given includes
@@ -5490,3 +5489,61 @@ naturally expire and possibly (5) wire the funds to a 
designated account.
       wire_amount: Amount;
 
     }
+
+
+.. _delete-reserve:
+
+.. http:DELETE:: /reserves/$RESERVE_PUB
+
+  Forcefully closes a reserve.
+  The request header must contain an *Account-Request-Signature*.
+  Note: this endpoint is not currently implemented!
+
+  **Request:**
+
+  *Account-Request-Signature*: The client must provide Base-32 encoded EdDSA 
signature made with ``$ACCOUNT_PRIV``, affirming its authorization to delete 
the account.  The purpose used MUST be ``TALER_SIGNATURE_RESERVE_CLOSE``.
+
+  :query force=BOOLEAN: *Optional.*  If set to 'true' specified, the exchange
+    will delete the account even if there is a balance remaining.
+
+  **Response:**
+
+  :http:statuscode:`200 OK`:
+    The operation succeeded, the exchange provides details
+    about the account deletion.
+    The response will include a `ReserveDeletedResponse` object.
+  :http:statuscode:`403 Forbidden`:
+    The *Account-Request-Signature* is invalid.
+    This response comes with a standard `ErrorDetail` response.
+  :http:statuscode:`404 Not found`:
+    The account is unknown to the exchange.
+  :http:statuscode:`409 Conflict`:
+    The account is still has digital cash in it, the associated
+    wire method is ``void`` and the *force* option was not provided.
+    This response comes with a standard `ErrorDetail` response.
+
+  **Details:**
+
+  .. ts:def:: ReserveDeletedResponse
+
+     interface ReserveDeletedResponse {
+
+      // Final balance of the account.
+      closing_amount: Amount;
+
+      // Current time of the exchange, used as part of
+      // what the exchange signs over.
+      close_time: Timestamp;
+
+      // Hash of the wire account into which the remaining
+      // balance will be transferred. Note: may be the
+      // hash over ``payto://void/`, in which case the
+      // balance is forfeit to the profit of the exchange.
+      h_wire: HashCode;
+
+      // This is a signature over a
+      // struct ``TALER_AccountDeleteConfirmationPS`` with purpose
+      // ``TALER_SIGNATURE_EXCHANGE_RESERVE_DELETED``.
+      exchange_sig: EddsaSignature;
+
+    }

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



reply via email to

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