commit 7ca305587f4d887b6e08eb7d5b81037997152416
parent f80f3f91561e668d2580bf154bec7adfbc78fe60
Author: Özgür Kesim <oec-taler@kesim.org>
Date: Fri, 11 Jul 2025 13:00:24 +0200
[exchange] added first changes to recoup
Diffstat:
| M | core/api-exchange.rst | | | 146 | +++++++++++++++++++++++++++++++++++++------------------------------------------ |
1 file changed, 68 insertions(+), 78 deletions(-)
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
@@ -293,7 +293,7 @@ possibly by using HTTPS.
exchange_pub: EddsaPublicKey;
// Denominations for which the exchange currently offers/requests recoup.
- recoup: Recoup[];
+ recoup: RecoupDenoms[];
// Array of globally applicable fees by time range.
global_fees: GlobalFees[];
@@ -604,9 +604,9 @@ possibly by using HTTPS.
different currency, but this is not currently supported by the
implementation.
- .. ts:def:: Recoup
+ .. ts:def:: RecoupDenoms
- interface Recoup {
+ interface RecoupDenoms {
// Hash of the public key of the denomination that is being revoked under
// emergency protocol (see ``/recoup``).
h_denom_pub: HashCode;
@@ -3426,6 +3426,8 @@ by anyone except the wallet itself.
Recoup
------
+The purpose of this API is to allow coins to be cashed back in,
+in certain exceptional situations.
This API is only used if the exchange is either about to go out of
business or has had its private signing keys compromised (so in
either case, the protocol is only used in **abnormal**
@@ -3436,24 +3438,36 @@ part of the ``/keys`` response. If and only if this has happened,
coins that were signed with those denomination keys can be cashed
in using this API.
-.. http:post:: /coins/$COIN_PUB/recoup
+For a recoup, a coin has to provide the necessary information to
+identify the original transaction (either a withdraw or a refresh) it
+became minted, and proof ownership of the coin itself.
- Demand that a coin be refunded via wire transfer to the original owner.
- The base URL for ``/coins/``-requests may differ from the main base URL of the
+.. http:post:: /recoup/withdraw
+
+ Demand that a batch of coins be refunded via wire transfer to the original owner.
+ The coins must have been originated from the same call to withdraw, and be
+ a subset of that original batch.
+
+ The base URL for ``/recoup/``-requests may differ from the main base URL of the
exchange. The exchange MUST return a 307 or 308 redirection to the correct
base URL if this is the case.
The remaining amount on the coin will be credited to the reserve
- that ``$COIN_PUB`` was withdrawn from.
+ that the coins were withdrawn from, in the same withdraw request.
Note that the original withdrawal fees will **not** be recouped.
- .. note:: This endpoint is currently not implemented and the API going to change after **v27**. It is documented here as a placeholder for the documentation of the future endpoint.
+ .. note:: This endpoint will become active with version **vRECOUP**, sometime after v27.
**Request:**
- The request body must be a `RecoupRequest` object.
+ The request body must be a `RecoupWithdrawRequest` object.
+
+ It provides sufficient information to
+ a) identify the originating withdraw request
+ b) proof that the coins to be recouped were part of that withdraw request
+ c) proof ownership of all coins requested to be recouped.
**Response:**
@@ -3464,95 +3478,71 @@ in using this API.
transaction or before the client can commit the coin signature to disk, the
coin is not lost.
:http:statuscode:`403 Forbidden`:
- The coin's signature is invalid.
+ A coin's signature is invalid.
This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
- The denomination key is unknown, the withdraw commitment is unknown
- or the blinded coin is not known to have been withdrawn.
- If the denomination key is unknown, the response will be
+ A denomination key is unknown,
+ the withdraw commitment is unknown
+ or a blinded coin is not known to have been withdrawn.
+ If a denomination key is unknown, the response will be
a `DenominationUnknownMessage`.
:http:statuscode:`409 Conflict`:
- The operation is not allowed as the coin has insufficient
- residual value, or because the same public key of the coin has been
- previously used with a different denomination. Which case it is
- can be decided by looking at the error code
+ The operation is not allowed
+ as a coin has insufficient residual value,
+ or because the same public key of a coin
+ has been previously used with a different denomination.
+ Which case it is can be decided by looking at the error code
(usually ``TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS``).
The response is a `DepositDoubleSpendError`.
: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 not yet revoked. The response is a
- `DenominationGoneMessage`. Clients must evaluate
- the error code provided to understand which of the
- cases this is and handle it accordingly.
+ A requested denomination key is not yet or no longer valid.
+ It either before the validity start, past the expiration or was not yet revoked.
+ The response is a `DenominationGoneMessage`.
+ Clients must evaluate the error code provided
+ to understand which of the cases this is and handle it accordingly.
**Details:**
- .. ts:def:: RecoupRequest
-
- interface RecoupRequest {
- // Hash of denomination public key, specifying the type of coin the client
- // would like the exchange to pay back.
- denom_pub_hash: HashCode;
-
- // Signature over the `coin public key <eddsa-coin-pub>` by the denomination.
- denom_sig: DenominationSignature;
-
- // The hash of the original withdraw commitment that this coin was part of.
- h_planchets: HashCode;
-
- // The hash of the age-commitment for the coin. Only present
- // if the denomination has support for age restriction.
- h_age_commitment?: AgeCommitmentHash;
-
- // Exchange-contributed values during the refresh
- // operation (see /blinding-prepare).
- ewv: ExchangeWithdrawValue;
+ .. ts:def:: RecoupWithdrawRequest
- // Signature of `TALER_RecoupRequestPS` created with
- // the `coin's private key <coin-priv>`.
- coin_sig: EddsaSignature;
-
- // Coin's blinding factor.
- coin_blind_key_secret: DenominationBlindingKeySecret;
-
- // Nonce that was used by the exchange to derive
- // its private inputs from during withdraw. Only
- // present if the cipher of the revoked denomination
- // is of type Clause-Schnorr (CS).
- nonce?: CSNonce;
+ interface RecoupWithdrawRequest {
+ // The details about the coins:
+ // An array of either
+ // a) the hash code of a blinded coin envelope (not to be recouped)
+ // b) the disclosed coin details, in order to recoup it.
+ // From these, the hash of all coin envelopes
+ // from the original withdraw can be reconstructed.
+ coin_data: RecoupCoinData[];
}
+ .. ts:def:: RecoupCoinData
+ type RecoupCoinData =
+ | HashCode
+ | RecoupDisclosedCoinDetails
- .. ts:def:: ExchangeWithdrawValue
-
- type ExchangeWithdrawValue = DenomCipher & (
- | ExchangeRsaWithdrawValue
- | ExchangeCsWithdrawValue
- );
-
- .. ts:def:: DenomCipher
-
- interface DenomCipher {
- cipher: "RSA" | "CS";
- }
+ .. ts:def:: RecoupDisclosedCoinDetails
- .. ts:def:: ExchangeRsaWithdrawValue
+ interface RecoupDisclosedCoinDetails {
+ // The coin's public key
+ coin_pub: CoinPublicKey;
- interface ExchangeRsaWithdrawValue extends DenomCipher {
- cipher: "RSA";
- }
+ // The blinding secret for this coin
+ // that was used during withdraw
+ coin_blinding_key_secret: DenominationBlindingKeySecret;
- .. ts:def:: ExchangeCsWithdrawValue
+ // Unblinded signature of the coins' public key,
+ // signed by the denomination key.
+ denom_pub_sig: DenominationSignature;
- interface ExchangeCsWithdrawValue extends DenomCipher {
- cipher: "CS";
-
- // CSR R0 value
- r_pub_0: CSRPublic;
+ // The denomination public key.
+ // This denomination MUST be eligible for recoup,
+ // i.e. being listed in the "recoup" section of /config.
+ denom_pub_h: HashCode;
- // CSR R1 value
- r_pub_1: CSRPublic;
+ // Signature of `TALER_RecoupRequestPS`,
+ // created by this coin's private key.
+ coin_sig: EddsaSignature;
}
.. ts:def:: RecoupWithdrawalConfirmation