summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-06-02 12:56:14 +0200
committerChristian Grothoff <christian@grothoff.org>2022-06-02 12:56:14 +0200
commitf13f8118e78cde34dd321485e193cd9bbf2e34c6 (patch)
tree67c59b492ecafda02b5dfc9fe1851768e5bc60bf /core
parent319cbc562b6b4627e4ec5ac23d8cb8a059d33409 (diff)
downloaddocs-f13f8118e78cde34dd321485e193cd9bbf2e34c6.tar.gz
docs-f13f8118e78cde34dd321485e193cd9bbf2e34c6.tar.bz2
docs-f13f8118e78cde34dd321485e193cd9bbf2e34c6.zip
-document current P2P API
Diffstat (limited to 'core')
-rw-r--r--core/api-exchange.rst547
1 files changed, 316 insertions, 231 deletions
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 0a1a1f8f..4ae050d1 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -1134,11 +1134,9 @@ exchange.
:http:statuscode:`200 OK`:
The exchange responds with a `ReserveStatus` object; the reserve was known to the exchange.
- :http:statuscode:`401 Unauthorized`:
- The *TALER_SIGNATURE_RESERVE_STATUS_REQUEST* signature is invalid.
- This response comes with a standard `ErrorDetail` response.
:http:statuscode:`403 Forbidden`:
- The provided timestamp is not close to the current time.
+ 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.
:http:statuscode:`404 Not found`:
The reserve key does not belong to a reserve known to the exchange.
@@ -1387,11 +1385,9 @@ exchange.
:http:statuscode:`200 OK`:
The exchange responds with a `ReserveStatus` object; the reserve was known to the exchange.
- :http:statuscode:`401 Unauthorized`:
- The *TALER_SIGNATURE_RESERVE_HISTORY_REQUEST* is invalid.
- This response comes with a standard `ErrorDetail` response.
:http:statuscode:`403 Forbidden`:
- The provided timestamp is not close to the current time.
+ 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`:
@@ -1680,7 +1676,7 @@ exchange.
The operation succeeded, the exchange provides details
about the account deletion.
The response will include a `ReserveClosedResponse` object.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
The *Account-Request-Signature* is invalid.
This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
@@ -1752,8 +1748,9 @@ denomination.
:http:statuscode:`200 OK`:
The operation succeeded, the exchange confirms that no double-spending took
place. The response will include a `DepositSuccess` object.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
One of the signatures is invalid.
+ This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
Either the denomination key is not recognized (expired or invalid),
or the wire type is not recognized.
@@ -1764,7 +1761,8 @@ denomination.
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_DEPOSIT_INSUFFICIENT_FUNDS`` or ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY``).
+ (``TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS`` or
+ ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY``).
The fields of the response are the same in both cases.
The request should not be repeated again with this coin.
In this case, the response is a `DepositDoubleSpendError`.
@@ -2298,7 +2296,8 @@ the API during normal operation.
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_MELT_INSUFFICIENT_FUNDS`` or ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY``).
+ (``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.
@@ -2579,8 +2578,9 @@ in using this API.
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:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
The coin's signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
The denomination key is unknown, or the blinded
coin is not known to have been withdrawn.
@@ -2658,8 +2658,9 @@ in using this API.
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:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
The coin's signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
The denomination key is unknown, or the blinded
coin is not known to have been withdrawn.
@@ -2831,8 +2832,9 @@ typically also view the balance.)
executed. Hence the exchange does not yet have a wire transfer identifier. The
merchant should come back later and ask again.
The response body is a `TrackTransactionAcceptedResponse`.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
A signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
The deposit operation is unknown to the exchange.
@@ -2901,7 +2903,7 @@ Refunds
:http:statuscode:`200 OK`:
The operation succeeded, the exchange confirms that the coin can now be refreshed. The response will include a `RefundSuccess` object.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
Merchant signature is invalid.
This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
@@ -3055,13 +3057,14 @@ Wallet-to-wallet transfers
}
-.. http:POST:: /purses/$PURSE_PUB/deposit
- Deposit money into a purse. Endpoint used by the buyer.
+.. http:POST:: /purses/$PURSE_PUB/create
+
+ Create a purse by depositing money into it. First step of a PUSH payment.
**Request:**
- The request body must be a `PurseRequest` object.
+ The request body must be a `PurseCreate` object.
**Response:**
@@ -3069,55 +3072,59 @@ Wallet-to-wallet transfers
The operation succeeded, the exchange confirms that all
coins were deposited into the purse.
The response will include a `PurseDepositSuccess` object.
- :http:statuscode:`202 Accepted`:
- The payment was accepted, but insufficient to reach the
- specified purse balance. If an encrypted contract was
- provided, it will have been stored in the database.
- The client should make further
- purse deposits before the expiration deadline.
- The response will include a `PurseDepositAccepted` object.
- :http:statuscode:`401 Unauthorized`:
- A coin signature is invalid. The response will
- include a `PurseDepositSignatureErrorDetail`
:http:statuscode:`403 Forbidden`:
- The server is denying the operation as a purse with a
- different contract or total amount already exists.
- This response comes with a standard `PurseConflict` response.
- :http:statuscode:`404 Not found`:
- FIXME: when exactly does this happen?
+ A coin, denomination or contract signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`404 Not Found`:
+ The denomination of one of the coins is unknown to the exchange.
:http:statuscode:`409 Conflict`:
The deposit operation has either failed because a 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
+ previously used with a different denomination, or because a purse with
+ the same public key but different meta data was created previously.
+ Which case it is
can be decided by looking at the error code
- (``TALER_EC_EXCHANGE_DEPOSIT_INSUFFICIENT_FUNDS`` or
- ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY``).
- The fields of the response are the same in both cases.
- The request should not be repeated again with this coin.
- In this case, the response is a `PurseDepositDoubleSpendError`.
- If the value of all successful coins is below the purse fee,
- the exchange may not setup the purse at all. The encrypted
- contract will not have been associated with the purse if this
- status code is returned. However, all coins that were not
- double-spent will have been deposited into the purse.
+ (``TALER_EC_EXCHANGE_GENERIC_INSUFFICIENT_FUNDS`` or
+ ``TALER_EC_EXCHANGE_GENERIC_COIN_CONFLICTING_DENOMINATION_KEY`` or
+ ``TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA`` or
+ ``TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA`` or
+ ``TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA``).
+ The specific fields of the response depend on the error code
+ and include the signatures (and what was signed over) proving the
+ conflict.
:http:statuscode:`425 Too Early`:
This response type is used if the given purse expiration time
is too far in the future (at least from the perspective
of the exchange). Thus, retrying at a later time may
- succeed. The client should look at the ``Date:`` header of the response to see if a minor time difference is to blame and possibly adjust the request accordingly.
+ succeed. The client should look at the ``Date:`` header
+ of the response to see if a minor time difference is to
+ blame and possibly adjust the request accordingly.
+ (Note: this status code is not yet used.)
**Details:**
- .. ts:def:: PurseRequest
+ interface PurseCreate {
- interface PurseRequest {
+ // Total value of the purse, excluding fees.
+ amount: Amount;
- // Array of coins to deposit into the purse.
- deposits: PurseDeposit[];
- }
+ // Minimum age required for all coins deposited into the purse.
+ min_age: Integer;
- interface PurseDeposit {
+ // Optional encrypted contract, in case the buyer is
+ // proposing the contract and thus establishing the
+ // purse with the payment.
+ econtract?: string;
+
+ // Signature over the contract.
+ econtract_sig?: EddsaSignature;
+
+ // Ephemeral public key for the DH operation to decrypt the contract.
+ contract_pub?: EddsaPublicKey;
+
+ // EdDSA public key used to approve merges of this purse.
+ merge_pub: EddsaPublicKey;
// EdDSA signature of the purse over a
// `TALER_PurseRequestSignaturePS`
@@ -3127,65 +3134,27 @@ Wallet-to-wallet transfers
// (amount, h_contract_terms, expiration).
purse_sig: EddsaSignature;
- // EdDSA public key used to approve merges of this purse.
- merge_pub: EddsaPublicKey;
-
- // Total amount to be paid into the purse.
- // Clients may make several requests, i.e. if a
- // first request failed with a double-spending error.
- // The exchange will confirm the creation of the
- // purse once the amount given here is reached.
- merge_value_after_fees: Amount;
-
// SHA-512 hash of the contact of the purse.
h_contract_terms: HashCode;
- // Minimum age of deposits made into the purse
- minimum_age: Integer;
+ // Array of coins being deposited into the purse.
+ // Maximum length is 128.
+ deposits: PurseDeposit[];
// 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 will be auto-refunded.
purse_expiration: Timestamp;
- // Optional encrypted contract, in case the buyer is
- // proposing the contract and thus establishing the
- // purse with the payment.
- contract?: EncryptedContract;
-
- // Array of coins being deposited into the purse.
- // Maximum length is 128.
- deposits: PurseDeposit[];
- }
-
- .. ts:def:: EncryptedContract
-
- interface EncryptedContract {
-
- // ECDH contract_public key used to encrypt the contract.
- // Optional as the contract terms may already be known
- // to the exchange or the other wallet from a different
- // interaction.
- contract_pub: TALER_EcdhEphemeralPublicKeyP;
-
- // AES-GCM Encrypted contract terms using encryption
- // key derived from DH of ``contract_pub`` and the ``purse_pub``.
- // Optional as the contract terms may already be known
- // to the exchange or the other wallet from a different
- // interaction.
- e_contract_terms: string;
}
.. ts:def:: PurseDeposit
interface PurseDeposit {
- // Public key of the coin being deposited into the purse.
- coin_pub: EddsaPublicKey;
-
// Amount to be deposited, can be a fraction of the
// coin's total value.
- contribution: Amount;
+ amount: Amount;
// Hash of denomination RSA key with which the coin is signed.
denom_pub_hash: HashCode;
@@ -3193,23 +3162,31 @@ Wallet-to-wallet transfers
// Exchange's unblinded RSA signature of the coin.
ub_sig: DenominationSignature;
+ // Age commitment hash for the coin, if the denomination is age-restricted.
+ h_age_commitment?: AgeCommitment;
+
+ // FIXME-Oec: proof of age is missing.
+
// Signature over `TALER_PurseDepositSignaturePS`
// of purpose ``TALER_SIGNATURE_WALLET_PURSE_DEPOSIT``
// made by the customer with the
// `coin's private key <coin-priv>`.
coin_sig: EddsaSignature;
+ // Public key of the coin being deposited into the purse.
+ coin_pub: EddsaPublicKey;
+
}
.. ts:def:: PurseDepositSuccess
interface PurseDepositSuccess {
- // Total amount paid into the purse.
- total_purse_amount: Amount;
+ // Total amount deposited into the purse so far (without fees).
+ total_deposited: Amount;
- // Total deposit fees charged.
- total_deposit_fees: Amount;
+ // Time at the exchange.
+ exchange_timestamp: Timestamp;
// EdDSA signature of the exchange affirming the payment,
// of purpose ``TALER_SIGNATURE_PURSE_DEPOSIT_CONFIRMED``
@@ -3223,39 +3200,26 @@ Wallet-to-wallet transfers
}
- .. ts:def:: PurseDepositAccepted
-
- interface PurseDepositAccepted {
-
- // Total amount paid so far into the purse, in this
- // and previous requests.
- total_amount_deposited: Amount;
-
- // Total amount contributed by the current request.
- total_amount_contributed: Amount;
-
- }
-
.. ts:def:: PurseConflict
- // Union discriminated by the "type" field.
+ // Union discriminated by the "code" field.
type PurseConflict =
- | PurseMergeConflict
- | PurseRequestConflict;
+ | DepositDoubleSpendError
+ | PurseCreateConflict
+ | PurseDepositConflict
+ | PurseContractConflict;
- .. ts:def:: PurseMergeConflict
+ .. ts:def:: PurseCreateConflict
- interface PurseMergeConflict {
- type: "MERGE";
+ interface PurseCreateConflict {
+ code: TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA;
- // SHA-512 hash of the contact of the purse.
- h_contract_terms: HashCode;
-
- // Hash of the wire details of the reserve.
- h_wire: HashCode;
+ // Total amount to be merged into the reserve.
+ // (excludes fees).
+ amount: Amount;
- // Reserve merging the purse.
- reserve_pub: EddsaPublicKey;
+ // Minimum age required for all coins deposited into the purse.
+ min_age: Integer;
// Indicative time by which the purse should expire
// if it has not been merged into an account. At this
@@ -3263,100 +3227,65 @@ Wallet-to-wallet transfers
// auto-refunded.
purse_expiration: Timestamp;
- // When was the merge request generated.
- merge_timestamp: Timestamp;
-
- // Total amount to be merged into the reserve.
- // (excludes fees).
- merge_value_after_fees: Amount;
-
// EdDSA signature of the purse over
// `TALER_PurseMergeSignaturePS` of
// purpose ``TALER_SIGNATURE_WALLET_PURSE_MERGE``
// confirming that the
// above details hold for this purse.
purse_sig: EddsaSignature;
- }
-
- .. ts:def:: PurseRequestConflict
-
- interface PurseRequestConflict {
- type: "REQUEST";
// SHA-512 hash of the contact of the purse.
h_contract_terms: HashCode;
- // 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;
+ // EdDSA public key used to approve merges of this purse.
+ merge_pub: EddsaPublicKey;
+ }
- // Total amount to be paid into the purse as per
- // the previous request.
- total_purse_amount: Amount;
+ .. ts:def:: PurseDepositConflict
- // EdDSA signature of the purse over
- // `TALER_PurseRequestSignaturePS` of
- // purpose ``TALER_SIGNATURE_PURSE_REQUEST``
- // confirming that the
- // above details hold for this purse.
- purse_sig: EddsaSignature;
-
- }
+ interface PurseDepositConflict {
+ code: TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA;
- .. ts:def:: PurseDepositDoubleSpendError
+ // Public key of the coin being deposited into the purse.
+ coin_pub: EddsaPublicKey;
- interface DepositDoubleSpendError {
- // Taler error code.
- code: number;
+ // Signature over `TALER_PurseDepositSignaturePS`
+ // of purpose ``TALER_SIGNATURE_WALLET_PURSE_DEPOSIT``
+ // made by the customer with the
+ // `coin's private key <coin-priv>`.
+ coin_sig: EddsaSignature;
- // Human-readable description of the error, i.e. "insufficient funds".
- hint?: string;
+ // Target exchange URL for the purse. Not present for the
+ // same exchange.
+ partner_url?: string;
- // Total amount contributed by the current request.
- // Note that some coins may have been successfully
- // deposited into the purse, so the total amount
- // from these coins is listed here.
- total_amount_contributed: Amount;
+ // Amount to be contributed to the purse by this coin.
+ amount: Amount;
- // Public keys of coins that could not be deposited
- // into the purse, mapped to the coin's histories.
- coin_map: EddsaPublicKey -> CoinSpendHistoryItem[];
}
+ .. ts:def:: PurseContractConflict
- .. ts:def:: PurseDepositSignatureErrorDetail
+ interface PurseContractConflict {
+ code: TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA;
- interface PurseDepositSignatureErrorDetail {
- // Taler error code, summarizing the problem.
- // Note that for problems about specific
- // coins, the 'coin_error_map' should be consulted.
- // The 'coin_error_map' will be empty if the
- // 'purse_sig' was invalid. In this case,
- // the coins will not even have been checked by
- // the exchange.
- code: number;
+ // Encrypted contract.
+ econtract: string;
- // Human-readable description of the error, i.e. "invalid signature".
- hint?: string;
+ // Signature over the contract.
+ econtract_sig: EddsaSignature;
- // Total amount contributed by the current request.
- // Note that some coins may have been successfully
- // deposited into the purse, so the total amount
- // from these coins is listed here.
- total_amount_contributed: Amount;
-
- // Public keys of coins that could not be deposited
- // into the purse, mapped to the coin's histories.
- coin_error_map: EddsaPublicKey -> ErrorDetail[];
+ // Ephemeral public key for the DH operation to decrypt the contract.
+ pub_ckey: EddsaPublicKey;
}
+
+
.. http:POST:: /purses/$PURSE_PUB/merge
Merge purse with account, adding the value of the purse into
- the account. Endpoint to be used by the seller.
+ the account. Endpoint to be used by the receiver of a PUSH payment.
**Request:**
@@ -3368,25 +3297,26 @@ Wallet-to-wallet transfers
The operation succeeded, the exchange confirms that the
funds were merged into the account.
The response will include a `MergeSuccess` object.
- :http:statuscode:`202 Accepted`:
- The operation succeeded, the exchange confirms that the
- merge request is valid. Alas, the purse was still not
- funded and thus the actual merge is delayed.
- The response will include a `MergeAccepted` object.
- :http:statuscode:`401 Unauthorized`:
- Account signature is invalid.
+ :http:statuscode:`402 Payment Required`:
+ The purse is not yet full and more money needs to be deposited
+ before the merge can be made.
+ :http:statuscode:`403 Forbidden`:
+ The signature of the merge request or the reserve was invalid.
This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
- The refund operation failed as we could not find the purse.
+ The merge operation failed as we could not find the purse
+ or the partner exchange.
This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`409 Conflict`:
+ The purse was already merged into a different reserve.
+ The response will include a `MergeConflict` object.
:http:statuscode:`410 Gone`:
The purse has already expired and thus can no longer be merged.
This response comes with a standard `ErrorDetail` response.
- :http:statuscode:`429 Too Many Requests`:
- This account is not at this exchange, has not yet passed the
- KYC checks, or it has exceeded the number of open purses.
- The client must include payment to create another purse or
- wait until existing purses have expired.
+ :http:statuscode:`451 Unavailable For Legal Reasons`:
+ This account has not yet passed the KYC checks.
+ The client must pass KYC checks before proceeding with the merge.
+ FIXME: not yet implemented, response format to be specified!
**Details:**
@@ -3436,21 +3366,31 @@ Wallet-to-wallet transfers
}
- .. ts:def:: MergeAccepted
+ .. ts:def:: MergeConflict
- interface MergeAccepted {
+ interface MergeConflict {
- // Current balance in the purse.
- balance: Amount;
+ // Client-side timestamp of when the merge request was made.
+ merge_timestamp: Timestamp;
+
+ // EdDSA signature of the purse private key affirming the merge
+ // over a `TALER_PurseMergeSignaturePS`.
+ // Must be of purpose ``TALER_SIGNATURE_PURSE_MERGE``.
+ merge_sig: EddsaSignature;
+ // Base URL of the exchange receiving the payment, only present
+ // if the exchange hosting the reserve is not this exchange.
+ partner_base_url?: string;
+
+ // Public key of the reserve that the purse was merged into.
+ reserve_pub: EddsaPublicKey;
}
.. http:POST:: /reserves/$RESERVE_PUB/purse
- Create purse for an account.
- Endpoint to be used by the seller.
+ Create purse for an account. First step of a PULL payment.
**Request:**
@@ -3461,16 +3401,33 @@ Wallet-to-wallet transfers
:http:statuscode:`200 OK`:
The operation succeeded, the exchange confirms that the
purse was allocated.
- The response will include a `MergePending` object.
- :http:statuscode:`401 Unauthorized`:
- Account signature is invalid.
- This response comes with a standard `ErrorDetail` response.
+ The response will include a `PurseDepositSuccess` object.
:http:statuscode:`402 Payment Required`:
The account needs to contain more funding to create more purses.
This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`403 Forbidden`:
+ Account or contract signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
:http:statuscode:`404 Not found`:
- The refund operation failed as we could not find the purse.
+ The purse creation operation failed as we could not find the reserve.
This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`409 Conflict`:
+ The purse creation failed because a purse with
+ the same public key but different meta data was
+ created previously. Which specific conflict it is
+ can be decided by looking at the error code
+ (``TALER_EC_EXCHANGE_PURSE_CREATE_CONFLICTING_META_DATA`` or
+ ``TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA`` or
+ ``TALER_EC_EXCHANGE_PURSE_ECONTRACT_CONFLICTING_META_DATA``).
+ The specific fields of the response depend on the error code
+ and include the signatures (and what was signed over) proving the
+ conflict.
+ The response will be a `PurseConflict` response
+ (but not a `DepositDoubleSpendError`).
+ :http:statuscode:`451 Unavailable For Legal Reasons`:
+ This account has not yet passed the KYC checks.
+ The client must pass KYC checks before proceeding with the merge.
+ FIXME: not yet implemented, response format to be specified!
**Details:**
@@ -3478,16 +3435,53 @@ Wallet-to-wallet transfers
interface ReservePurseRequest {
- // EdDSA signature of the account/reserve affirming the merge
- // over a `TALER_XXX`.
- // Must be of purpose ``TALER_SIGNATURE_XXX``
- reserve_sig: EddsaSignature;
-
// Minimum amount that must be credited to the reserve, that is
// the total value of the purse minus the deposit fees.
// If the deposit fees are lower, the contribution to the
// reserve can be higher!
- merge_value_after_fees: Amount;
+ purse_value: Amount;
+
+ // Minimum age required for all coins deposited into the purse.
+ min_age: Integer;
+
+ // Purse fee the reserve owner is willing to pay
+ // for the purse creation. Optional, if not present
+ // the purse is to be created from the purse quota
+ // of the reserve.
+ purse_fee: Amount;
+
+ // Optional encrypted contract, in case the buyer is
+ // proposing the contract and thus establishing the
+ // purse with the payment.
+ econtract?: string;
+
+ // Signature over the contract.
+ econtract_sig?: EddsaSignature;
+
+ // Ephemeral public key for the DH operation to decrypt the contract.
+ contract_pub?: EddsaPublicKey;
+
+ // EdDSA public key used to approve merges of this purse.
+ merge_pub: EddsaPublicKey;
+
+ // EdDSA signature of the purse private key affirming the merge
+ // over a `TALER_PurseMergeSignaturePS`.
+ // Must be of purpose ``TALER_SIGNATURE_PURSE_MERGE``.
+ merge_sig: EddsaSignature;
+
+ // EdDSA signature of the account/reserve affirming the merge.
+ // Must be of purpose ``TALER_SIGNATURE_WALLET_ACCOUNT_MERGE``
+ reserve_sig: EddsaSignature;
+
+ // Purse public key.
+ purse_pub: EddsaPublicKey;
+
+ // EdDSA signature of the purse over
+ // `TALER_PurseRequestSignaturePS` of
+ // purpose ``TALER_SIGNATURE_PURSE_REQUEST``
+ // confirming that the
+ // above details hold for this purse.
+ purse_sig: EddsaSignature;
// SHA-512 hash of the contact of the purse.
h_contract_terms: HashCode;
@@ -3499,25 +3493,115 @@ Wallet-to-wallet transfers
// if it has not been paid.
purse_expiration: Timestamp;
- // Optional encrypted contract, in case the seller is
- // proposing the contract and thus establishing the
- // purse with the payment.
- contract?: EncryptedContract;
+ }
+
+
+.. http:POST:: /purses/$PURSE_PUB/deposit
+
+ Deposit money into a purse. Used by the buyer for a PULL payment.
+
+ **Request:**
+
+ The request body must be a `PurseDeposits` object.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The operation succeeded, the exchange confirms that all
+ coins were deposited into the purse.
+ The response will include a `PurseDepositSuccess` object.
+ :http:statuscode:`403 Forbidden`:
+ A coin or denomination signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`404 Not found`:
+ The purse is unknown.
+ This response comes with a standard `ErrorDetail` response.
+ :http:statuscode:`409 Conflict`:
+ The deposit operation has either failed because a 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`` or
+ ``TALER_EC_EXCHANGE_PURSE_DEPOSIT_CONFLICTING_META_DATA``).
+ This response comes with a standard `PurseConflict` response
+ (alas some cases are impossible).
+ :http:statuscode:`410 Gone`:
+ The purse has expired.
+
+ **Details:**
+
+ .. ts:def:: PurseDeposits
+
+ interface PurseDeposits {
+
+ // Array of coins to deposit into the purse.
+ deposits: PurseDeposit[];
}
- .. ts:def:: MergePending
+ .. ts:def:: PurseDeposit
- interface MergePending {
+ interface PurseDeposit {
- // The number of remaining purses that can still be opened
- // under the given account.
- remaining_purses: Integer;
+ // Amount to be deposited, can be a fraction of the
+ // coin's total value.
+ amount: Amount;
+
+ // Hash of denomination RSA key with which the coin is signed.
+ denom_pub_hash: HashCode;
+
+ // Exchange's unblinded RSA signature of the coin.
+ ub_sig: DenominationSignature;
+
+ // Age commitment hash for the coin, if the denomination is age-restricted.
+ h_age_commitment?: AgeCommitment;
+
+ // FIXME-Oec: proof of age is missing.
+
+ // Signature over `TALER_PurseDepositSignaturePS`
+ // of purpose ``TALER_SIGNATURE_WALLET_PURSE_DEPOSIT``
+ // made by the customer with the
+ // `coin's private key <coin-priv>`.
+ coin_sig: EddsaSignature;
+
+ // Public key of the coin being deposited into the purse.
+ coin_pub: EddsaPublicKey;
}
+ .. ts:def:: PurseDepositSuccess
+
+ interface PurseDepositSuccess {
+
+ // Total amount paid into the purse.
+ total_deposited: Amount;
+
+ // Total amount expected in the purse.
+ purse_value_after_fees: Amount;
+
+ // Time at which the deposit came into effect.
+ exchange_timestamp: Timestamp;
+
+ // 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 will be auto-refunded.
+ purse_expiration: Timestamp;
+
+ // SHA-512 hash of the contact of the purse.
+ h_contract_terms: HashCode;
+
+ // EdDSA signature of the exchange affirming the payment,
+ // of purpose ``TALER_SIGNATURE_PURSE_DEPOSIT_CONFIRMED``
+ // over a `TALER_PurseDepositConfirmedSignaturePS`.
+ // Signs over the above and the purse public key and
+ // the hash of the contract terms.
+ exchange_sig: EddsaSignature;
--- TODO: API to deposit into existing purse
+ // public key used to create the signature.
+ exchange_pub: EddsaPublicKey;
+
+ }
.. _exchange_wads:
@@ -3643,8 +3727,9 @@ KYC status updates
The response will be a `WalletKycUuid` object.
:http:statuscode:`204 No Content`:
KYC is disabled at this exchange.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
The provided signature is invalid.
+ This response comes with a standard `ErrorDetail` response.
**Details:**
@@ -3705,7 +3790,7 @@ KYC status updates
:http:statuscode:`204 No content`:
The exchange is not configured to perform KYC and thus
generally all accounts are simply considered legitimate.
- :http:statuscode:`401 Unauthorized`:
+ :http:statuscode:`403 Forbidden`:
The provided hash does not match the payment target.
:http:statuscode:`404 Not found`:
The payment target is unknown.