[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-docs] 02/04: [api] WIP: new withdraw and reveal endpoints introdu
From: |
gnunet |
Subject: |
[taler-docs] 02/04: [api] WIP: new withdraw and reveal endpoints introduced |
Date: |
Thu, 02 Jan 2025 22:31:53 +0100 |
This is an automated email from the git hooks/post-receive script.
oec pushed a commit to branch master
in repository docs.
commit 039627fee4219e9a502fcc841d4995bb29c5af66
Author: Özgür Kesim <oec-taler@kesim.org>
AuthorDate: Sun Dec 29 14:43:01 2024 +0100
[api] WIP: new withdraw and reveal endpoints introduced
As part of the convergence of /batch-withdraw and /age-withdraw,
a new /withdraw endpoint has been introduced.
Also, a new /melt endpoint requires now the full list of coin-envelopes
and the denominations sent, allowing this and the subsequent
reveal step to become idempotent.
A new toplevel /reveal is now prefix for new ./withdraw and ./refresh
endpoints.
Note:
This is work-in-progress, paramters might be missing or wrong, return
values not fully captured and details missing or incorrect.
---
core/api-common.rst | 34 ++-
core/api-exchange.rst | 615 ++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 534 insertions(+), 115 deletions(-)
diff --git a/core/api-common.rst b/core/api-common.rst
index f1bd96ed..aec267bd 100644
--- a/core/api-common.rst
+++ b/core/api-common.rst
@@ -662,7 +662,7 @@ Blinded coin
type DenominationBlindingKeyP = string;
-. _unblinded-coin:
+.. _unblinded-coin:
Unblinded coin
^^^^^^^^^^^^^^
@@ -973,6 +973,10 @@ uses 512-bit hash codes (64 bytes).
.. sourcecode:: c
struct TALER_BlindedCoinHash {
+ // Hash over a) the hash of the denomination's public key
+ // and b) the hash of the blinded planchet.
+ // See implementation of `TALER_coin_ev_hash`
+ // in libtalerexchange for details.
struct GNUNET_HashCode hash;
};
@@ -1187,9 +1191,37 @@ within the
`exchange's codebase
<https://docs.taler.net/global-licensing.html#exchange-repo>`_.
.. _TALER_WithdrawRequestPS:
+
+.. note::
+ struct ``TALER_WithdrawRequestPS`` is first introduced with protocol
version v24.
+
.. sourcecode:: c
struct TALER_WithdrawRequestPS {
+ /**
+ * purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ struct TALER_ReservePublicKeyP reserve_pub;
+ /**
+ * This is the running SHA512-hash over all
+ * `struct TALER_BlindedCoinHash` values.
+ * If max_age_group is > 0, there will be N*κ many such values.
+ * The iteration MUST be then depth's first, i.e.
+ * …,h[i][0],…,h[i][κ],h[i+1][0],…,h[i+1][κ],…
+ */
+ struct GNUNET_HashCode h_planchets;
+ /**
+ * If max_age_group is > 0, the mask MUST be non-zero, too
+ */
+ uint8_t max_age_group;
+ struct TALER_AgeMask mask;
+ };
+
+.. _TALER_SingleWithdrawRequestPS:
+.. sourcecode:: c
+
+ struct TALER_SingleWithdrawRequestPS {
/**
* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW
*/
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 3f73475c..24b591f2 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -841,7 +841,7 @@ Management operations authorized by master key
}
- .. ts:def:: DenominationKey
+ .. ts:def:: DenominationKey
type DenominationKey =
| RsaDenominationKey
@@ -1547,8 +1547,8 @@ exchange.
}
-Withdraw
-~~~~~~~~
+CSR-Withdraw
+~~~~~~~~~~~~
.. http:post:: /csr-withdraw
@@ -1620,10 +1620,15 @@ Withdraw
}
-Batch Withdraw
-~~~~~~~~~~~~~~
+Withdraw
+~~~~~~~~
-.. http:post:: /reserves/$RESERVE_PUB/batch-withdraw
+.. http:post:: /reserves/$RESERVE_PUB/withdraw
+
+ .. note::
+ This endpoint is available starting with API version v24.
+ It combines and replaces the endpoints
``/reserves/$RESERVE_PUB/batch-withdraw``
+ and ``/reserves/$RESERVE_PUB/age-withdraw``.
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
@@ -1631,12 +1636,20 @@ Batch Withdraw
recover the information if necessary in case of transient failures, like
power outage, network outage, etc.
- **Request:** The request body must be a `BatchWithdrawRequest` object.
+ **Request:** The request body must be a `WithdrawRequest` object.
**Response:**
:http:statuscode:`200 OK`:
- The request was successful, and the response is a `BatchWithdrawResponse`.
+ The request was successful, and ``max_age`` was not set.
+ 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:`201 Created`:
+ The request was successful, and ``max_age`` was set.
+ The response is a `AgeWithdrawResponse`. The client is expected
+ to call ``/reveal/$ACH`` next.
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.
@@ -1659,8 +1672,21 @@ Batch Withdraw
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``
+ 2. The reserve has a birthday set and requires the request to provide a
``max_age``
+ value.
+ 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 a call to ``/withdraw``, this time
+ with ``max_age`` set accordingly and ``blinded_coin_evs`` being an array
+ of elements of type `AgeCoinEnvelope`.
+
+ 3. 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 ``/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.
@@ -1686,51 +1712,67 @@ Batch Withdraw
a different payto://-URI for the KYC check depending
on the case.
-
**Details:**
- .. ts:def:: BatchWithdrawRequest
-
- interface BatchWithdrawRequest {
- // Array of requests for the individual coins to withdraw.
- planchets: WithdrawRequest[];
-
- }
.. ts:def:: WithdrawRequest
interface WithdrawRequest {
- // Hash of a denomination public key, specifying the type of coin the
client
- // would like the exchange to create.
- denom_pub_hash: HashCode;
+ // Array of ``n`` hash codes of denomination public keys to order.
+ // 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.
+ // If ``max_age`` is set, these denominations MUST support
+ // age restriction as defined in the output to /keys.
+ denoms_h: HashCode[];
- // Coin's blinded public key, should be (blindly) signed by the
exchange's
- // denomination private key.
- coin_ev: CoinEnvelope;
+ // If set, the maximum age to commit to. This implies:
+ // 1.) MUST be the same value as the maximum age in the reserve.
+ // 2.) ``blinded_planchets`` MUST be an array of type `AgeCoinEnvelope`.
+ // 3.) the denominations in ``denoms_h`` MUST support age restriction.
+ max_age?: number;
+
+ // ``n`` arrays of blinded coin envelopes.
+ // If ``max_age`` is not set, each entry MUST be of type `CoinEnvelope`.
+ // If ``max_age`` is set, the following rules apply:
+ // Each entry MUST be of type `AgeCoinEnvelope` to represent ``kappa``
+ // canditates for one particular age-restricted coin.
+ // The exchange will respond with an index ``gamma``, which is the
+ // index that shall remain undisclosed during the subsequent
+ // 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_coin_evs: BlindedCoinEnvelope[];
// Signature of `TALER_WithdrawRequestPS` created with
// the `reserves's private key <reserve-priv>`
// using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``.
reserve_sig: EddsaSignature;
-
}
+ .. ts:def:: BlindedCoinEnvelope
- .. ts:def:: BatchWithdrawResponse
+ type BlindedCoinEnvelope =
+ | CoinEnvelope
+ | AgeCoinEnvelope
- interface BatchWithdrawResponse {
- // Array of blinded signatures, in the same order as was
- // given in the request.
- ev_sigs: WithdrawResponse[];
- }
+ .. ts:def:: AgeCoinEnvelope
+
+ // Represents ``kappa`` candidates of one age restricted coin.
+ // The age-restriction MUST have been calculated according
+ // to the description of `AgeRestrictedCoinSecret`.
+ type AgeCoinEnvelope = CoinEnvelope[kappa];
+
.. ts:def:: WithdrawResponse
interface WithdrawResponse {
- // The blinded signature over the 'coin_ev', affirms the coin's
- // validity after unblinding.
- ev_sig: BlindedDenominationSignature;
+ // Array of blinded signatures over each ``blinded_coin_ev``,
+ // in the same order as was given in the request.
+ // The blinded signatures affirm the coin's validity
+ // after unblinding.
+ ev_sigs: BlindedDenominationSignature[];
}
@@ -1764,21 +1806,24 @@ Batch Withdraw
}
- .. ts:def:: WithdrawError
+ .. ts:def:: AgeWithdrawResponse
- interface WithdrawError {
- // Text describing the error.
- hint: string;
+ interface AgeWithdrawResponse {
+ // index of the commitments that the client doesn't
+ // have to disclose in the subsequent call to
+ // ``/withdraw/$ACH/reveal``.
+ noreveal_index: Integer;
- // Detailed error code.
- code: Integer;
+ // Signature of `TALER_AgeWithdrawConfirmationPS` whereby
+ // the exchange confirms the ``noreveal_index``.
+ exchange_sig: EddsaSignature;
- // Amount left in the reserve.
- balance: Amount;
+ // `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;
- // History of the reserve's activity, in the same format
- // as returned by ``/reserve/$RID/history``.
- history: TransactionHistoryItem[]
}
.. ts:def:: DenominationExpiredMessage
@@ -1809,9 +1854,131 @@ Batch Withdraw
// What kind of operation was requested that now
// failed?
oper: string;
+
+ }
+
+
+ .. ts:def:: WithdrawError
+
+ interface SingleWithdrawError {
+ // Text describing the error.
+ hint: string;
+
+ // Detailed error code.
+ code: Integer;
+
+ // Amount left in the reserve.
+ balance: Amount;
+
+ // History of the reserve's activity, in the same format
+ // as returned by ``/reserve/$RID/history``.
+ history: TransactionHistoryItem[]
+ }
+
+
+
+Batch Withdraw
+~~~~~~~~~~~~~~
+
+.. http:post:: /reserves/$RESERVE_PUB/batch-withdraw
+
+ .. note::
+ This endpoint becomes deprecated starting with API version v24.
+ Use the ``/reserves/$RESERVE_PUB/withdraw`` endpoint instead,
+ see `Withdraw`_.
+
+ 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.
+
+ **Request:** The request body must be a `BatchWithdrawRequest` 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`:
+ 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:
+
+ 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 `LegitimizationNeededResponse` 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.
+
+
+ **Details:**
+
+ .. ts:def:: BatchWithdrawRequest
+
+ interface BatchWithdrawRequest {
+ // Array of requests for the individual coins to withdraw.
+ planchets: SingleWithdrawRequest[];
+
}
+ .. ts:def:: SingleWithdrawRequest
+ interface SingleWithdrawRequest {
+ // Hash of a denomination public key, specifying the type of coin the
client
+ // would like the exchange to create.
+ denom_pub_hash: HashCode;
+
+ // Coin's blinded public key, should be (blindly) signed by the
exchange's
+ // denomination private key.
+ coin_ev: CoinEnvelope;
+
+ // Signature of `TALER_SingleWithdrawRequestPS` created with
+ // the `reserves's private key <reserve-priv>`
+ // using purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``.
+ reserve_sig: EddsaSignature;
+
+ }
@@ -1829,6 +1996,11 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
.. http:post:: /reserves/$RESERVE_PUB/age-withdraw
+ .. note::
+ This endpoint becomes deprecated starting with API version v24.
+ Use the ``/reserves/$RESERVE_PUB/withdraw`` endpoint instead,
+ see `Withdraw`_.
+
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
@@ -1853,8 +2025,12 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
1. The balance of the reserve is not sufficient to withdraw the coins of
the
given amount. The response is a `WithdrawError` object.
- 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``
+ 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.
@@ -1889,7 +2065,7 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
// 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[][];
+ blinded_planchets: CoinEnvelope[][];
// The maximum age to commit to. MUST be the same as the maximum
// age in the reserve.
@@ -1901,30 +2077,40 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
reserve_sig: EddsaSignature;
}
- .. ts:def:: AgeWithdrawResponse
- interface AgeWithdrawResponse {
- // index of the commitments that the client doesn't
- // have to disclose
- noreveal_index: Integer;
+.. http:post:: /age-withdraw/$ACH/reveal
- // Signature of `TALER_AgeWithdrawConfirmationPS` whereby
- // the exchange confirms the ``noreveal_index``.
- exchange_sig: EddsaSignature;
+ .. note::
+ This endpoint is deprecated starting with API version v24.
+ It is renamed to ``/reveal/withdraw/$ACH``, see `Reveal`_.
+ The request and response objects are identical.
- // `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;
- }
+------
+Reveal
+------
+
+These endpoins are called whenever a client made a commitment prior this this
+call at another endpoint, such as a call to `Withdraw`_ with ``max_age`` set
+or the melting request in`Refresh`_, and has to reveal now all but one secret
+as part of a cut-and-choose protocol.
+
+After Withdraw
+~~~~~~~~~~~~~~
+.. note::
+ This endpoint is available starting with API version v24.
-.. http:post:: /age-withdraw/$ACH/reveal
+This endpoint is called by the client after a call to `Withdraw`_, *only if*
the original request
+had ``max_age`` set and the response was of type ``AgeWithdrawResponse``.
+Now the client has to disclose for each coin all but one of the κ secrets that
went into
+creating the blinded coin's planchets, including the commitent to age
restriction, and prove
+that the age restriction was set correctly.
+
+.. http:post:: /reveal/withdraw/$ACH
The client has previously committed to multiple coins with age restriction
- in a call to ``/reserve/$RESERVE_PUB/age-withdraw`` and got a
+ in a call to ``/reserve/$RESERVE_PUB/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
@@ -1932,12 +2118,12 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
request is given as the ``$ACH`` value in the URL to this endpoint.
- **Request:** The request body must be a `AgeWithdrawRevealRequest` object.
+ **Request:** The request body must be a `WithdrawRevealRequest` object.
**Response:**
:http:statuscode:`200 OK`:
- The request was successful, and the response is a
`AgeWithdrawRevealResponse`.
+ The request was successful, and the response is a `WithdrawRevealResponse`.
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.
@@ -1957,9 +2143,9 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
``TALER_EC_EXCHANGE_AGE_WITHDRAW_REVEAL_INVALID_HASH``
- .. ts:def:: AgeWithdrawRevealRequest
+ .. ts:def:: WithdrawRevealRequest
- interface AgeWithdrawRevealRequest {
+ interface WithdrawRevealRequest {
// 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.
@@ -2005,14 +2191,93 @@ If so, the exchange will blindly sign ``n`` undisclosed
coins from the request.
const PublishedAgeRestrictionBaseKey =
new
Edx25519PublicKey("CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG");
- .. ts:def:: AgeWithdrawRevealResponse
+ .. ts:def:: WithdrawRevealResponse
- interface AgeWithdrawRevealResponse {
+ interface WithdrawRevealResponse {
// List of the exchange's blinded RSA signatures on the new coins.
ev_sigs : BlindedDenominationSignature[];
}
+After Melt
+~~~~~~~~~~
+
+.. note::
+ This endpoint is available starting with API version v24.
+
+This endpoint is called by the client after a call to `melt`_.
+Now the client has to disclose for each coin all but one of the κ secrets that
went into
+creating the blinded coin's planchets, the transfer public keys
+(linking the ownership of the old and new coin),
+and the commitent to age restriction, prove that the age restriction was set
correctly
+(if applicable).
+
+.. http:post:: /reveal/refresh/$RCH
+
+ Reveal previously committed values to the exchange, except for the values
+ corresponding to the ``noreveal_index`` returned by the ``/melt/`` step.
+
+ The $RCH is the hash over the refresh commitment from the ``/melt/``-melt
step
+ (note that the value is calculated independently by both sides and has never
+ appeared *explicitly* in the protocol before).
+
+ The base URL for ``/reveal/refresh``-requests may differ from the main base
URL of
+ the exchange. Clients SHOULD respect the ``refresh_base_url`` returned for
the
+ coin during melt operations. The exchange MUST return a
+ 307 or 308 redirection to the correct base URL if the client failed to
+ respect the ``refresh_base_url`` or if the allocation has changed.
+
+ :http:statuscode:`200 OK`:
+ The transfer private keys matched the commitment and the original request
was well-formed.
+ The response body is a `RevealResponse`.
+ :http:statuscode:`409 Conflict`:
+ There is a problem between the original commitment and the revealed private
+ keys. The returned information is proof of the mismatch, and therefore
+ rather verbose, as it includes most of the original /melt request,
+ but of course expected to be primarily used for diagnostics.
+ The response body is a `RevealConflictResponse`.
+ :http:statuscode:`410 Gone`:
+ The requested denomination key (for the fresh coins) 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:**
+
+ Request body contains a JSON object with the following fields:
+
+ .. ts:def:: RevealRequest
+
+ interface RevealRequest {
+
+ // ``kappa - 1`` transfer private keys (ephemeral ECDHE keys).
+ transfer_privs: EddsaPrivateKey[];
+
+ }
+
+
+ .. ts:def:: RevealResponse
+
+ type RevealResponse = WithdrawResponse;
+
+
+ .. ts:def:: RevealConflictResponse
+
+ interface RevealConflictResponse {
+ // Text describing the error.
+ hint: string;
+
+ // Detailed error code.
+ code: Integer;
+
+ // Commitment as calculated by the exchange from the revealed data.
+ rc_expected: HashCode;
+
+ }
+
+
+
.. _reserve-history:
---------------
@@ -2136,7 +2401,7 @@ Reserve History
// Hash of the blinded coin to be signed.
h_coin_envelope: HashCode;
- // Signature over a `TALER_WithdrawRequestPS`
+ // Signature over a `TALER_SingleWithdrawRequestPS`
// with purpose ``TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW``
// created with the reserve's private key.
reserve_sig: EddsaSignature;
@@ -3194,9 +3459,13 @@ the API during normal operation.
ewvs: ExchangeWithdrawValue[];
}
+.. _melt:
+.. http:post:: /melt/$COIN_PUB
-.. _refresh:
-.. http:post:: /coins/$COIN_PUB/melt
+ .. note::
+ This endpoint will become available starting with version v24 of the API.
+
+ .. warning:: This endpoint is still work-in-progress!
"Melts" a coin. Invalidates the coins and prepares for exchanging of fresh
coins. Taler uses a global parameter ``kappa`` for the cut-and-choose
@@ -3204,7 +3473,7 @@ the API during normal operation.
various arguments are given ``kappa``-times in this step. At present
``kappa``
is always 3.
- The base URL for ``/coins/``-requests may differ from the main base URL of
the
+ The base URL for ``/melt/``-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.
@@ -3234,10 +3503,159 @@ the API during normal operation.
**Details:**
-
.. ts:def:: MeltRequest
interface MeltRequest {
+ old: {
+ // Hash of the denomination public key, to determine total coin
value.
+ denom_pub_hash: HashCode;
+
+ // Signature over the `coin public key <eddsa-coin-pub>` by the
denomination.
+ denom_sig: DenominationSignature;
+
+ // Signature by the `coin <coin-priv>` over the melt commitment.
+ confirm_sig: EddsaSignature;
+
+ // Amount of the value of the coin that should be melted as part of
+ // this refresh operation, including melting fee.
+ value_with_fee: Amount;
+
+ // Master seed for the Clause-schnorr R-value
+ // creation. Must match the /csr-melt request.
+ // Must not have been used in any prior melt request.
+ // Must be present if one of the fresh coin's
+ // denominations is of type Clause-Schnorr.
+ rms?: RefreshMasterSeed;
+
+ // IFF the corresponding denomination has support for age
restriction,
+ // the client MUST provide the original age commitment, i. e. the
+ // vector of public keys, or omitted otherwise.
+ // The size of the vector MUST be the number of age groups as
defined by the
+ // Exchange in the field ``.age_groups`` of the extension
``age_restriction``.
+ age_commitment?: Edx25519PublicKey[];
+ }
+
+ fresh: {
+ // Array of ``n`` new hash codes of denomination public keys to
order.
+ denoms_h: HashCode[];
+
+ // Array of ``n`` entries with blinded coins,
+ // matching the respective entries in ``denoms_h``.
+ coin_evs: CoinEnvelope[];
+
+ // Array of ``n`` entries with the transfer public keys
+ // (ephemeral ECDHE keys).
+ transfer_pubs: EddsaPublicKey[];
+
+ // Array of ``n`` signatures made by the wallet using the old coin's
private key,
+ // used later to verify the /refresh/link response from the exchange.
+ // Signs over a `TALER_CoinLinkSignaturePS`.
+ link_sigs: EddsaSignature[];
+ }
+ }
+
+ For details about the HKDF used to derive the new coin private keys and
+ the blinding factors from ECDHE between the transfer public keys and
+ the private key of the melted coin, please refer to the
+ implementation in ``libtalerutil``.
+
+ .. ts:def:: MeltResponse
+
+ interface MeltResponse {
+ // Which of the ``kappa`` indices does the client not have to reveal
+ // by calling the ``/reveal/refresh/`` endpoint.
+ noreveal_index: Integer;
+
+ // Signature of `TALER_RefreshMeltConfirmationPS` whereby the exchange
+ // affirms the successful melt and confirming the ``noreveal_index``.
+ exchange_sig: EddsaSignature;
+
+ // `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;
+
+ // Base URL to use for operations on the refresh context
+ // (so the reveal operation). If not given,
+ // the base URL is the same as the one used for this request.
+ // Can be used if the base URL for ``/reveal/`` differs from that
+ // for ``/melt/``, i.e. for load balancing. Clients SHOULD
+ // respect the refresh_base_url if provided. Any HTTP server
+ // belonging to an exchange MUST generate a 307 or 308 redirection
+ // to the correct base URL should a client uses the wrong base
+ // URL, or if the base URL has changed since the melt.
+ //
+ // When melting the same coin twice (technically allowed
+ // as the response might have been lost on the network),
+ // the exchange may return different values for the ``refresh_base_url``.
+ refresh_base_url?: string;
+
+ }
+
+
+ .. ts:def:: MeltForbiddenResponse
+
+ interface MeltForbiddenResponse {
+ // Text describing the error.
+ hint: string;
+
+ // Detailed error code.
+ code: Integer;
+
+ // The transaction list of the respective coin that failed to have
sufficient funds left.
+ // Note that only the transaction history for one bogus coin is given,
+ // even if multiple coins would have failed the check.
+ history: CoinSpendHistoryItem[];
+ }
+
+
+.. _pre24refresh:
+.. http:post:: /coins/$COIN_PUB/melt
+
+ .. note::
+ This endpoint will become depreciated starting with version v24 of the API.
+ Use ``/melt/$COIN_PUB`` instead, see `melt`_.
+
+ "Melts" a coin. Invalidates the coins and prepares for exchanging of fresh
+ coins. Taler uses a global parameter ``kappa`` for the cut-and-choose
+ component of the protocol, for which this request is the commitment. Thus,
+ various arguments are given ``kappa``-times in this step. At present
``kappa``
+ is always 3.
+
+ The base URL for ``/coins/``-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.
+
+ :http:statuscode:`200 OK`:
+ The request was successful. The response body is `Pre24MeltResponse` in
this case.
+ :http:statuscode:`403 Forbidden`:
+ One of the signatures is invalid.
+ :http:statuscode:`404 Not found`:
+ The exchange does not recognize the denomination key as belonging to the
exchange,
+ or it has expired.
+ If the 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
+ (``TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS`` or
+ ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY``).
+ The response is `MeltForbiddenResponse` in both cases.
+ :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:: Pre24MeltRequest
+
+ interface Pre24MeltRequest {
// Hash of the denomination public key, to determine total coin value.
denom_pub_hash: HashCode;
@@ -3274,9 +3692,9 @@ the API during normal operation.
the private key of the melted coin, please refer to the
implementation in ``libtalerutil``.
- .. ts:def:: MeltResponse
+ .. ts:def:: Pre24MeltResponse
- interface MeltResponse {
+ interface Pre24MeltResponse {
// Which of the ``kappa`` indices does the client not have to reveal.
noreveal_index: Integer;
@@ -3308,23 +3726,12 @@ the API during normal operation.
}
- .. ts:def:: MeltForbiddenResponse
-
- interface MeltForbiddenResponse {
- // Text describing the error.
- hint: string;
-
- // Detailed error code.
- code: Integer;
-
- // The transaction list of the respective coin that failed to have
sufficient funds left.
- // Note that only the transaction history for one bogus coin is given,
- // even if multiple coins would have failed the check.
- history: CoinSpendHistoryItem[];
- }
+.. http:post:: /refreshes/$RCH/reveal
+ .. note::
-.. http:post:: /refreshes/$RCH/reveal
+ This endpoint will become depreciated starting with version v24 of the
API.
+ Use ``/reveal/refresh/$RCH`` then instead, see `Reveal`_.
Reveal previously committed values to the exchange, except for the values
corresponding to the ``noreveal_index`` returned by the ``/coins/``-melt
step.
@@ -3367,9 +3774,9 @@ the API during normal operation.
Request body contains a JSON object with the following fields:
- .. ts:def:: RevealRequest
+ .. ts:def:: Pre24RevealRequest
- interface RevealRequest {
+ interface Pre24RevealRequest {
// Array of ``n`` new hash codes of denomination public keys to order.
new_denoms_h: HashCode[];
@@ -3399,26 +3806,6 @@ the API during normal operation.
}
- .. ts:def:: RevealResponse
-
- type RevealResponse = BatchWithdrawResponse;
-
-
- .. ts:def:: RevealConflictResponse
-
- interface RevealConflictResponse {
- // Text describing the error.
- hint: string;
-
- // Detailed error code.
- code: Integer;
-
- // Commitment as calculated by the exchange from the revealed data.
- rc_expected: HashCode;
-
- }
-
-
.. http:get:: /coins/$COIN_PUB/link
Link the old public key of a melted coin to the coin(s) that were exchanged
during the refresh operation.
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.