summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/api-auditor.rst2413
-rw-r--r--core/api-bank-conversion-info.rst4
-rw-r--r--core/api-bank-integration.rst157
-rw-r--r--core/api-bank-wire.rst24
-rw-r--r--core/api-challenger.rst85
-rw-r--r--core/api-common.rst55
-rw-r--r--core/api-corebank.rst113
-rw-r--r--core/api-exchange.rst863
-rw-r--r--core/api-merchant.rst196
-rw-r--r--core/api-terminal.rst356
-rw-r--r--core/index-bank-apis.rst1
11 files changed, 3795 insertions, 472 deletions
diff --git a/core/api-auditor.rst b/core/api-auditor.rst
index 61e448b8..932da735 100644
--- a/core/api-auditor.rst
+++ b/core/api-auditor.rst
@@ -97,58 +97,6 @@ know-your-customer (KYC) registration before issuing contracts.
time of this writing).
-.. _exchange_signkeys-list:
-
-------------------------------------
-Obtaining Exchange Signing Keys List
-------------------------------------
-
-This API is used by auditor to obtain a list of all exchanges signing keys to be audited.
-
-.. http:get:: /exchange-sign-keys
-
- Get a list of all exchange signing keys to be audited by the auditor.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- The auditor responds with a :ts:type:`ExchangeSignKeysList` object. This request should
- virtually always be successful.
-
- **Details:**
-
- .. ts:def:: ExchangeSignKeysList
-
- interface ExchangeSignKeysList {
- // Exchange signing keys to be audited by the auditor.
- exchange-sign-key: ExchangeSignKeyEntry[];
- }
-
- .. ts:def:: ExchangeSignKeyEntry
-
- interface ExchangeSignKeyEntry {
-
- // Public online signing key of the exchange.
- exchange_pub: EddsaPublicKey;
-
- // Base URL of the exchange.
- master_sig: EddsaSignature;
-
- // Time when online signing key will first be use.
- ep_valid_from: Timestamp;
-
- // Time when this online signing key will no longer be used.
- ep_expire_sign: Timestamp;
-
- // Time when this online signing key legally expires.
- ep_expire_legal: Timestamp;
- }
-
- .. note::
-
- This API is still experimental (and is not yet implemented at the
- time of this writing).
-
.. _deposit-confirmation:
---------------------
@@ -257,55 +205,1259 @@ paid out first.
time of this writing). A key open question is whether the auditor
should sign the response information.
-This API is used by the auditor to obtain a list of all deposit confirmations that the auditor
-did not receive by the exchange, only by the merchant.
-.. http:get:: /deposit-confirmation
+.. _spa-api:
+
+---------------------------
+Single Page Application API
+---------------------------
+
+The following entries specify how to access the results of an audit.
+
+For most endpoints, rows may be marked as 'suppressed', to not send them again upon subsequent GET requests.
+To do this, a :ts:type:`GenericUpdate` object may be used.
+
+**Details:**
+
+ .. ts:def:: GenericUpdate
+
+ interface GenericUpdate {
+
+ // the row_id of a respective table that should be changed
+ row_id : Integer;
+
+ // if true, subsequent GET requests will not, by default, receive the row specified in row_id.
+ suppressed : boolean;
+
+ // unused
+ ancient? : boolean;
+
+ }
+
+
+
+.. fee-time-inconsistency-list:
- Get a list of all deposit confirmations that were not received by the auditor from the exchange to be manually audited.
+Fee Time Inconsistencies
+------------------------
+
+This API is used to obtain a list of fee time inconsistencies
+
+.. http:get:: /fee-time-inconsistency
+
+ Get a list of fee time inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
**Response:**
:http:statuscode:`200 OK`:
- The auditor responds with a :ts:type:`DepositConfirmationList` object.
- :http:statuscode:`204 No Content`:
- No missing deposit confirmations found.
+ The auditor responds with a top level array of :ts:type:`FeeTimeInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
**Details:**
- .. ts:def:: DepositConfirmationList
+ .. ts:def:: FeeTimeInconsistency
+
+ interface FeeTimeInconsistency {
- interface DepositConfirmationList {
- // Deposit confirmations to be audited.
- deposit-confirmations: DepositConfirmation[];
+
+ row_id : Integer;
+
+ type : string;
+
+ time : Timestamp;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
}
- .. ts:def:: DepositConfirmation
+ .. note::
- interface DepositConfirmation {
+ This API is still experimental. The API will be further developed as needed.
- // Database row id of entry
- row_id: Integer;
- // Time when the deposit confirmation confirmation was generated.
- timestamp: Timestamp;
- // How much time does the merchant have to issue a refund
- // request? Zero if refunds are not allowed.
- refund_deadline: Timestamp;
- // By what time does the exchange have to wire the funds?
- wire_deadline: Timestamp;
+This API is used to suppress select elements of fee time inconsistencies
- // Amount to be deposited, excluding fee. Calculated from the
- // amount with fee and the fee from the deposit request.
- amount_without_fee: Amount;
+.. http:patch:: /fee-time-inconsistency
+
+ Update the 'suppressed' field of an fee time inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. emergency-by-count-list:
+
+Emergencies By Count
+--------------------
+
+This API is used to obtain a list of emergencies by count
+
+.. http:get:: /emergency-by-count
+
+ Get a list of emergencies by count stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`EmergencyByCount` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: EmergencyByCount
+
+ interface EmergencyByCount {
+
+
+ row_id : Integer;
+
+ denompub_h : HashCode;
+
+ num_issued : Integer;
+
+ num_known : Integer;
+
+ risk : Amount;
+
+ start : Timestamp;
+
+ deposit_end : Timestamp;
+
+ value : Amount;
+
+ suppressed : boolean;
+
+
}
.. note::
- This API is still experimental (and is not yet implemented at the
- time of this writing).
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of emergencies by count
+
+.. http:patch:: /emergency-by-count
+
+ Update the 'suppressed' field of an emergency by count element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. row-inconsistency-list:
+
+Row Inconsistencies
+-------------------
+
+This API is used to obtain a list of row inconsistencies
+
+.. http:get:: /row-inconsistency
+
+ Get a list of row inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`RowInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: RowInconsistency
+
+ interface RowInconsistency {
+
+
+ row_id : Integer;
+
+ row_table : string;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of row inconsistencies
+
+.. http:patch:: /row-inconsistency
+
+ Update the 'suppressed' field of an row inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. reserve-in-inconsistency-list:
+
+Reserve In Inconsistencies
+--------------------------
+
+This API is used to obtain a list of reserve in inconsistencies
+
+.. http:get:: /reserve-in-inconsistency
+
+ Get a list of reserve in inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ReserveInInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ReserveInInconsistency
+
+ interface ReserveInInconsistency {
+
+
+ row_id : Integer;
+
+ amount_exchange_expected : Amount;
+
+ amount_wired : Amount;
+
+ reserve_pub : EddsaPublicKey;
+
+ timestamp : Timestamp;
+
+ account : string;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of reserve in inconsistencies
+
+.. http:patch:: /reserve-in-inconsistency
+
+ Update the 'suppressed' field of an reserve in inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. purse-not-closed-inconsistencies-list:
+
+Purse Not Closed Inconsistencies
+--------------------------------
+
+This API is used to obtain a list of purse not closed inconsistencies
+
+.. http:get:: /purse-not-closed-inconsistencies
+
+ Get a list of purse not closed inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`PurseNotClosedInconsistencies` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: PurseNotClosedInconsistencies
+
+ interface PurseNotClosedInconsistencies {
+
+
+ row_id : Integer;
+
+ purse_pub : EddsaPublicKey;
+
+ amount : Amount;
+
+ expiration_date : Timestamp;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of purse not closed inconsistencies
+
+.. http:patch:: /purse-not-closed-inconsistencies
+
+ Update the 'suppressed' field of an purse not closed inconsistencies element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. reserve-not-closed-inconsistency-list:
+
+Reserve Not Closed Inconsistencies
+----------------------------------
+
+This API is used to obtain a list of reserve not closed inconsistencies
+
+.. http:get:: /reserve-not-closed-inconsistency
+
+ Get a list of reserve not closed inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ReserveNotClosedInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ReserveNotClosedInconsistency
+
+ interface ReserveNotClosedInconsistency {
+
+
+ row_id : Integer;
+
+ reserve_pub : EddsaPublicKey;
+
+ balance : Amount;
+
+ expiration_time : Timestamp;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of reserve not closed inconsistencies
+
+.. http:patch:: /reserve-not-closed-inconsistency
+
+ Update the 'suppressed' field of an reserve not closed inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. reserve-balance-insufficient-inconsistency-list:
+
+Reserve Balance Insufficient Inconsistencies
+--------------------------------------------
+
+This API is used to obtain a list of reserve balance insufficient inconsistencies
+
+.. http:get:: /reserve-balance-insufficient-inconsistency
+
+ Get a list of reserve balance insufficient inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ReserveBalanceInsufficientInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ReserveBalanceInsufficientInconsistency
+
+ interface ReserveBalanceInsufficientInconsistency {
+
+
+ row_id : Integer;
+
+ reserve_pub : EddsaPublicKey;
+
+ inconsistency_gain : boolean;
+
+ inconsistency_amount : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of reserve balance insufficient inconsistencies
+
+.. http:patch:: /reserve-balance-insufficient-inconsistency
+
+ Update the 'suppressed' field of an reserve balance insufficient inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. bad-sig-losses-list:
+
+Bad Sig Losses
+--------------
+
+This API is used to obtain a list of bad sig losses
+
+.. http:get:: /bad-sig-losses
+
+ Get a list of bad sig losses stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+ :query operation: A string. If specified, only returns eligible rows with this :ts:type:`BadSigLosses`.operation value. The default value is NULL.
+ :query use_op_spec_pub: A boolean. If true, use the value of :ts:type:`OpSpecPub` to only return eligible rows with this :ts:type:`BadSigLosses`.operation_specific_pub value. The default value is NULL.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`BadSigLosses` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: BadSigLosses
+
+ interface BadSigLosses {
+
+
+ row_id : Integer;
+
+ operation : string;
+
+ loss : Amount;
+
+ operation_specific_pub : EddsaPublicKey;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of bad sig losses
+
+.. http:patch:: /bad-sig-losses
+
+ Update the 'suppressed' field of an bad sig losses element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. coin-inconsistency-list:
+
+Coin Inconsistencies
+--------------------
+
+This API is used to obtain a list of coin inconsistencies
+
+.. http:get:: /coin-inconsistency
+
+ Get a list of coin inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`CoinInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: CoinInconsistency
+
+ interface CoinInconsistency {
+
+
+ row_id : Integer;
+
+ operation : string;
+
+ exchange_amount : Amount;
+
+ auditor_amount : Amount;
+
+ coin_pub : EddsaPublicKey;
+
+ profitable : boolean;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of coin inconsistencies
+
+.. http:patch:: /coin-inconsistency
+
+ Update the 'suppressed' field of an coin inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. balances-list:
+
+Balances
+--------
+
+This API is used to obtain a list of balances
+
+.. http:get:: /balances
+
+ Get a list of balances stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+ :query balance_key: a string identifying a balance. If specified, only returns elements with this exact key. The default value is NULL.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`Balances` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: Balances
+
+ interface Balances {
+
+
+ row_id : Integer;
+
+ balance_key : string;
+
+ balance_value : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of balances
+
+.. http:patch:: /balances
+
+ Update the 'suppressed' field of an balances element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. denominations-without-sigs-list:
+
+Denominations Without Sigs
+--------------------------
+
+This API is used to obtain a list of denominations without sigs
+
+.. http:get:: /denominations-without-sigs
+
+ Get a list of denominations without sigs stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`DenominationsWithoutSigs` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: DenominationsWithoutSigs
+
+ interface DenominationsWithoutSigs {
+
+
+ row_id : Integer;
+
+ denompub_h : HashCode;
+
+ value : Amount;
+
+ start_time : Timestamp;
+
+ end_time : Timestamp;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of denominations without sigs
+
+.. http:patch:: /denominations-without-sigs
+
+ Update the 'suppressed' field of an denominations without sigs element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. misattribution-in-inconsistency-list:
+
+Misattribution In Inconsistencies
+---------------------------------
+
+This API is used to obtain a list of misattribution in inconsistencies
+
+.. http:get:: /misattribution-in-inconsistency
+
+ Get a list of misattribution in inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`MisattributionInInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: MisattributionInInconsistency
+
+ interface MisattributionInInconsistency {
+
+
+ row_id : Integer;
+
+ amount : Amount;
+
+ bank_row : Integer;
+
+ reserve_pub : EddsaPublicKey;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of misattribution in inconsistencies
+
+.. http:patch:: /misattribution-in-inconsistency
+
+ Update the 'suppressed' field of an misattribution in inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. progress-list:
+
+Progress
+--------
+
+This API is used to obtain a list of progress
+
+.. http:get:: /progress
+
+ Get a list of progress stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`Progress` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: Progress
+
+ interface Progress {
+
+
+ progress_key : string;
+
+ progress_offset : Integer;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of progress
+
+.. http:patch:: /progress
+
+ Update the 'suppressed' field of an progress element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. reserves-list:
+
+Reserves
+--------
+
+This API is used to obtain a list of reserves
+
+.. http:get:: /reserves
+
+ Get a list of reserves stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`Reserves` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: Reserves
+
+ interface Reserves {
+
+
+ auditor_reserves_rowid : Integer;
+
+ reserve_pub : EddsaPublicKey;
+
+ reserve_balance : Amount;
+
+ reserve_loss : Amount;
+
+ withdraw_fee_balance : Amount;
+
+ close_fee_balance : Amount;
+
+ purse_fee_balance : Amount;
+
+ open_fee_balance : Amount;
+
+ history_fee_balance : Amount;
+
+ expiration_date : Timestamp;
+
+ origin_account : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of reserves
+
+.. http:patch:: /reserves
+
+ Update the 'suppressed' field of an reserves element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. deposit-confirmations-list:
+
+Deposit Confirmations
+---------------------
+
+This API is used to obtain a list of deposit confirmations
+
+.. http:get:: /deposit-confirmations
+
+ Get a list of deposit confirmations stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`DepositConfirmations` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: DepositConfirmations
+
+ interface DepositConfirmations {
+
+
+ deposit_confirmation_serial_id : Integer;
+
+ h_contract_terms : HashCode;
+
+ h_policy : HashCode;
+
+ h_wire : HashCode;
+
+ exchange_timestamp : Timestamp;
+
+ refund_deadline : Timestamp;
+
+ wire_deadline : Timestamp;
+
+ total_without_fee : Amount;
+
+ coin_pubs : EddsaPublicKey;
+
+ coin_sigs : EddsaSignature;
+
+ merchant_pub : EddsaPublicKey;
+
+ exchange_sig : EddsaSignature;
+
+ exchange_pub : EddsaPublicKey;
+
+ master_sig : EddsaSignature;
+
+ suppressed : boolean;
+
+ ancient : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of deposit confirmations
+
+.. http:patch:: /deposit-confirmations
+
+ Update the 'suppressed' field of an deposit confirmations element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
This API is used by the auditor to delete an audited deposit confirmation.
@@ -329,95 +1481,1108 @@ This API is used by the auditor to delete an audited deposit confirmation.
This API is still experimental (and is not yet implemented at the
time of this writing).
-.. balances-list:
-----------------------------------
-Obtaining list of auditor balances
-----------------------------------
+.. denomination-key-validity-withdraw-inconsistency-list:
-This API is used to obtain a list of all the balances that are stored by the auditor.
+Denomination Key Validity Withdraw Inconsistencies
+--------------------------------------------------
-.. http:get:: /balances
+This API is used to obtain a list of denomination key validity withdraw inconsistencies
+
+.. http:get:: /denomination-key-validity-withdraw-inconsistency
+
+ Get a list of denomination key validity withdraw inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
- Get a list of all balances stored by the auditor.
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
**Response:**
:http:statuscode:`200 OK`:
- The auditor responds with a :ts:type:`BalanceList` object.
+ The auditor responds with a top level array of :ts:type:`DenominationKeyValidityWithdrawInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
- :http:statuscode:`409 Conflict`:
- Balance missing or other error occured.
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
**Details:**
- .. ts:def:: BalanceList
+ .. ts:def:: DenominationKeyValidityWithdrawInconsistency
+
+ interface DenominationKeyValidityWithdrawInconsistency {
+
+
+ row_id : Integer;
- interface BalanceList {
- // Total amount reported
- auditor_total_reported_balance: Amount;
+ execution_date : Timestamp;
- // Amount potentially missing
- auditor_missing_balance: Amount;
+ reserve_pub : EddsaPublicKey;
- //...
+ denompub_h : HashCode;
+
+ suppressed : boolean;
+
+
}
.. note::
- This API is still experimental (and is not yet implemented at the
- time of this writing). The API will be further developed as needed.
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of denomination key validity withdraw inconsistencies
+
+.. http:patch:: /denomination-key-validity-withdraw-inconsistency
+
+ Update the 'suppressed' field of an denomination key validity withdraw inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. purses-list:
+
+Purses
+------
+
+This API is used to obtain a list of purses
-.. denominations-pending-list:
+.. http:get:: /purses
----------------------------------------
-Obtaining list of pending denominations
----------------------------------------
+ Get a list of purses stored by the auditor.
-This API is used by the auditor to obtain a list of pending denominations
+ The following query parameters are optional, and can be used to customise the response:
-.. http:get:: /pending-denominations
+ **Request:**
- Get a list of all pending denominations.
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
**Response:**
:http:statuscode:`200 OK`:
- The auditor responds with a :ts:type:`PendingDenominationList` object.
+ The auditor responds with a top level array of :ts:type:`Purses` objecs.
- :http:statuscode:`204 No content`:
- No pending demoninations found.
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
**Details:**
- .. ts:def:: PendingDenominationList
+ .. ts:def:: Purses
+
+ interface Purses {
+
+
+ auditor_purses_rowid : Integer;
+
+ purse_pub : EddsaPublicKey;
+
+ balance : Amount;
+
+ target : Amount;
+
+ expiration_date : Timestamp;
+
+ suppressed : boolean;
- interface PendingDenominationList {
- // PendingDenominationList of the auditor.
- pending_denomination: PendingDenomination[];
+
}
- .. ts:def:: PendingDenomination
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of purses
+
+.. http:patch:: /purses
+
+ Update the 'suppressed' field of an purses element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. amount-arithmetic-inconsistency-list:
+
+Amount Arithmetic Inconsistencies
+---------------------------------
+
+This API is used to obtain a list of amount arithmetic inconsistencies
+
+.. http:get:: /amount-arithmetic-inconsistency
+
+ Get a list of amount arithmetic inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`AmountArithmeticInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: AmountArithmeticInconsistency
+
+ interface AmountArithmeticInconsistency {
- interface PendingDenomination {
+
+ row_id : Integer;
- // Balance of denomination.
- denom_balance: Amount;
+ operation : string;
- // Amount that was lost due to failures by the exchange.
- denom_loss: Amount;
+ exchange_amount : Amount;
- // Amount at risk of loss due to recoup operations.
- denom_risk: Amount;
+ auditor_amount : Amount;
- // Amount actually lost due to recoup operations after a revocation.
- recoup_loss: Amount;
+ profitable : boolean;
+
+ suppressed : boolean;
+
+
}
.. note::
- This API is still experimental (and is not yet implemented at the
- time of this writing).
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of amount arithmetic inconsistencies
+
+.. http:patch:: /amount-arithmetic-inconsistency
+
+ Update the 'suppressed' field of an amount arithmetic inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. historic-denomination-revenue-list:
+
+Historic Denomination Revenue
+-----------------------------
+
+This API is used to obtain a list of historic denomination revenue
+
+.. http:get:: /historic-denomination-revenue
+
+ Get a list of historic denomination revenue stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`HistoricDenominationRevenue` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: HistoricDenominationRevenue
+
+ interface HistoricDenominationRevenue {
+
+
+ denom_pub_hash : HashCode;
+
+ revenue_timestamp : Timestamp;
+
+ revenue_balance : Amount;
+
+ loss_balance : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of historic denomination revenue
+
+.. http:patch:: /historic-denomination-revenue
+
+ Update the 'suppressed' field of an historic denomination revenue element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. denomination-pending-list:
+
+Denomination Pending
+--------------------
+
+This API is used to obtain a list of denomination pending
+
+.. http:get:: /denomination-pending
+
+ Get a list of denomination pending stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`DenominationPending` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: DenominationPending
+
+ interface DenominationPending {
+
+
+ denom_pub_hash : HashCode;
+
+ denom_balance : Amount;
+
+ denom_loss : Amount;
+
+ num_issued : Integer;
+
+ denom_risk : Amount;
+
+ recoup_loss : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of denomination pending
+
+.. http:patch:: /denomination-pending
+
+ Update the 'suppressed' field of an denomination pending element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. historic-reserve-summary-list:
+
+Historic Reserve Summary
+------------------------
+
+This API is used to obtain a list of historic reserve summary
+
+.. http:get:: /historic-reserve-summary
+
+ Get a list of historic reserve summary stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`HistoricReserveSummary` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: HistoricReserveSummary
+
+ interface HistoricReserveSummary {
+
+
+ row_id : Integer;
+
+ start_date : Timestamp;
+
+ end_date : Timestamp;
+
+ reserve_profits : Amount;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of historic reserve summary
+
+.. http:patch:: /historic-reserve-summary
+
+ Update the 'suppressed' field of an historic reserve summary element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. exchange-signkeys-list:
+
+Exchange Signkeys
+-----------------
+
+This API is used to obtain a list of exchange signkeys
+
+.. http:get:: /exchange-signkeys
+
+ Get a list of exchange signkeys stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ExchangeSignkeys` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ExchangeSignkeys
+
+ interface ExchangeSignkeys {
+
+
+ exchange_pub : EddsaPublicKey;
+
+ master_sig : EddsaSignature;
+
+ ep_valid_from : Timestamp;
+
+ ep_expire_sign : Timestamp;
+
+ ep_expire_legal : Timestamp;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of exchange signkeys
+
+.. http:patch:: /exchange-signkeys
+
+ Update the 'suppressed' field of an exchange signkeys element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. wire-format-inconsistency-list:
+
+Wire Format Inconsistencies
+---------------------------
+
+This API is used to obtain a list of wire format inconsistencies
+
+.. http:get:: /wire-format-inconsistency
+
+ Get a list of wire format inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`WireFormatInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: WireFormatInconsistency
+
+ interface WireFormatInconsistency {
+
+
+ row_id : Integer;
+
+ amount : Amount;
+
+ wire_offset : Integer;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of wire format inconsistencies
+
+.. http:patch:: /wire-format-inconsistency
+
+ Update the 'suppressed' field of an wire format inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. refreshes-hanging-list:
+
+Refreshes Hanging
+-----------------
+
+This API is used to obtain a list of refreshes hanging
+
+.. http:get:: /refreshes-hanging
+
+ Get a list of refreshes hanging stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`RefreshesHanging` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: RefreshesHanging
+
+ interface RefreshesHanging {
+
+
+ row_id : Integer;
+
+ amount : Amount;
+
+ coin_pub : EddsaPublicKey;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of refreshes hanging
+
+.. http:patch:: /refreshes-hanging
+
+ Update the 'suppressed' field of an refreshes hanging element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. emergency-list:
+
+Emergencies
+-----------
+
+This API is used to obtain a list of emergencies
+
+.. http:get:: /emergency
+
+ Get a list of emergencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`Emergency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: Emergency
+
+ interface Emergency {
+
+
+ row_id : Integer;
+
+ denompub_h : HashCode;
+
+ denom_risk : Amount;
+
+ denom_loss : Amount;
+
+ deposit_start : Timestamp;
+
+ deposit_end : Timestamp;
+
+ value : Amount;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of emergencies
+
+.. http:patch:: /emergency
+
+ Update the 'suppressed' field of an emergency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. closure-lags-list:
+
+Closure Lags
+------------
+
+This API is used to obtain a list of closure lags
+
+.. http:get:: /closure-lags
+
+ Get a list of closure lags stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ClosureLags` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ClosureLags
+
+ interface ClosureLags {
+
+
+ row_id : Integer;
+
+ amount : Amount;
+
+ deadline : Timestamp;
+
+ wtid : Integer;
+
+ account : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of closure lags
+
+.. http:patch:: /closure-lags
+
+ Update the 'suppressed' field of an closure lags element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. wire-out-inconsistency-list:
+
+Wire Out Inconsistencies
+------------------------
+
+This API is used to obtain a list of wire out inconsistencies
+
+.. http:get:: /wire-out-inconsistency
+
+ Get a list of wire out inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`WireOutInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: WireOutInconsistency
+
+ interface WireOutInconsistency {
+
+
+ row_id : Integer;
+
+ destination_account : string;
+
+ expected : Amount;
+
+ claimed : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of wire out inconsistencies
+
+.. http:patch:: /wire-out-inconsistency
+
+ Update the 'suppressed' field of an wire out inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. reserve-balance-summary-wrong-inconsistency-list:
+
+Reserve Balance Summary Wrong Inconsistencies
+---------------------------------------------
+
+This API is used to obtain a list of reserve balance summary wrong inconsistencies
+
+.. http:get:: /reserve-balance-summary-wrong-inconsistency
+
+ Get a list of reserve balance summary wrong inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`ReserveBalanceSummaryWrongInconsistency` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: ReserveBalanceSummaryWrongInconsistency
+
+ interface ReserveBalanceSummaryWrongInconsistency {
+
+
+ row_id : Integer;
+
+ reserve_pub : EddsaPublicKey;
+
+ exchange_amount : Amount;
+
+ auditor_amount : Amount;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of reserve balance summary wrong inconsistencies
+
+.. http:patch:: /reserve-balance-summary-wrong-inconsistency
+
+ Update the 'suppressed' field of an reserve balance summary wrong inconsistency element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+.. row-minor-inconsistencies-list:
+
+Row Minor Inconsistencies
+-------------------------
+
+This API is used to obtain a list of row minor inconsistencies
+
+.. http:get:: /row-minor-inconsistencies
+
+ Get a list of row minor inconsistencies stored by the auditor.
+
+ The following query parameters are optional, and can be used to customise the response:
+
+ **Request:**
+
+ :query limit: A signed integer, indicating how many elements relative to the offset query parameter should be returned. The default value is -20.
+ :query offset: An unsigned integer, indicating from which row onward to return elements. The default value is INT_MAX.
+ :query return_suppressed: A boolean. If true, returns all eligible rows, otherwise only returns eligible rows that are not suppressed. The default value is false.
+
+
+ The default values, thus, return at max the 20 latest elements that are not suppressed.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The auditor responds with a top level array of :ts:type:`RowMinorInconsistencies` objecs.
+
+ :http:statuscode:`403 Forbidden`:
+ No or bad Bearer token provided.
+
+ :http:statuscode:`404 Not Found`:
+ No elements could be found.
+
+ **Details:**
+
+ .. ts:def:: RowMinorInconsistencies
+
+ interface RowMinorInconsistencies {
+
+
+ row_id : Integer;
+
+ row_table : Integer;
+
+ diagnostic : string;
+
+ suppressed : boolean;
+
+
+ }
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
+
+This API is used to suppress select elements of row minor inconsistencies
+
+.. http:patch:: /row-minor-inconsistencies
+
+ Update the 'suppressed' field of an row minor inconsistencies element according to :ts:type:`GenericUpdate`, stored by the auditor.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ The element has been accepted for processing.
+
+ .. note::
+
+ This API is still experimental. The API will be further developed as needed.
+
+
+
----------
Complaints
diff --git a/core/api-bank-conversion-info.rst b/core/api-bank-conversion-info.rst
index 322e9403..63856142 100644
--- a/core/api-bank-conversion-info.rst
+++ b/core/api-bank-conversion-info.rst
@@ -108,7 +108,7 @@ is used by wallets for withdrawals that involve a currency conversion.
* ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount.
* ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency.
:http:statuscode:`409 Conflict`:
- The amount is too small to be converted, either because it produces produce an amount less than zero, or because the server requires a higher minimum amount than that supplied.
+ The amount is too small to be converted because it produces an amount less than zero.
:http:statuscode:`501 Not implemented`:
This server does not support conversion, client should check config response.
@@ -154,7 +154,7 @@ is used by wallets for withdrawals that involve a currency conversion.
* ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount.
* ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency.
:http:statuscode:`409 Conflict`:
- The amount is too small to be converted, either because it produces produce an amount less than zero, or because the server requires a higher minimum amount than that supplied.
+ The amount is too small to be converted because it produces an amount less than zero.
:http:statuscode:`501 Not implemented`:
This server does not support conversion, client should check config response.
diff --git a/core/api-bank-integration.rst b/core/api-bank-integration.rst
index ac1ba63a..e7db1efc 100644
--- a/core/api-bank-integration.rst
+++ b/core/api-bank-integration.rst
@@ -1,7 +1,7 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -29,7 +29,7 @@ to tightly integrate with GNU Taler.
.. http:get:: /config
Return the protocol version and configuration information about the bank.
- This specification corresponds to ``current`` protocol being version **2**.
+ This specification corresponds to ``current`` protocol being **v2**.
**Response:**
@@ -47,6 +47,7 @@ to tightly integrate with GNU Taler.
// libtool-style representation of the Bank protocol version, see
// https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+
// The format is "current:revision:age".
version: string;
@@ -67,7 +68,7 @@ Withdrawing
-----------
Withdrawals with a Taler-integrated bank are based on withdrawal operations.
-Some user interaction (on the bank's website or a Taler-enabled ATM) creates a
+Some user interaction (on the bank's websitei) creates a
withdrawal operation record in the bank's database. The wallet can use a unique identifier
for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdrawal operation.
@@ -91,36 +92,63 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
The withdrawal operation is known to the bank, and details are given
in the `BankWithdrawalOperationStatus` response body.
:http:statuscode:`404 Not found`:
- The operation was not found
+ The operation was not found.
**Details:**
.. ts:def:: BankWithdrawalOperationStatus
- export class BankWithdrawalOperationStatus {
+ interface BankWithdrawalOperationStatus {
// Current status of the operation
// pending: the operation is pending parameters selection (exchange and reserve public key)
// selected: the operations has been selected and is pending confirmation
// aborted: the operation has been aborted
// confirmed: the transfer has been confirmed and registered by the bank
- // @since v1
+ // @since **v1**
status: "pending" | "selected" | "aborted" | "confirmed";
// Amount that will be withdrawn with this operation
- // (raw amount without fee considerations).
- amount: Amount;
-
- // Bank account of the customer that is withdrawing, as a
- // ``payto`` URI.
+ // (raw amount without fee considerations). Only
+ // given once the amount is fixed and cannot be changed.
+ // Optional since **vC2EC**.
+ amount?: Amount;
+
+ // Suggestion for the amount to be withdrawn with this
+ // operation. Given if a suggestion was made but the
+ // user may still change the amount.
+ // Optional since **vC2EC**.
+ suggested_amount?: Amount;
+
+ // Maximum amount that the wallet can choose to withdraw.
+ // Only applicable when the amount is not fixed.
+ // @since **vC2EC**.
+ max_amount?: Amount;
+
+ // The non-Taler card fees the customer will have
+ // to pay to the bank / payment service provider
+ // they are using to make the withdrawal.
+ // @since **vC2EC**
+ card_fees?: Amount;
+
+ // Bank account of the customer that is debiting, as an
+ // RFC 8905 ``payto`` URI.
sender_wire?: string;
- // Suggestion for an exchange given by the bank.
+ // Base URL of the suggested exchange. The bank may have
+ // neither a suggestion nor a requirement for the exchange.
+ // This value is typically set in the bank's configuration.
suggested_exchange?: string;
+ // Base URL of an exchange that must be used. Optional,
+ // not given *unless* a particular exchange is mandatory.
+ // This value is typically set in the bank's configuration.
+ // @since **vC2EC**
+ required_exchange?: string;
+
// URL that the user needs to navigate to in order to
// complete some final confirmation (e.g. 2FA).
// Only applicable when ``status`` is ``selected`` or ``pending``.
- // It may contain withdrawal operation id
+ // It may contain the withdrawal operation id.
confirm_transfer_url?: string;
// Wire transfer types supported by the bank.
@@ -128,43 +156,54 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
// Reserve public key selected by the exchange,
// only non-null if ``status`` is ``selected`` or ``confirmed``.
- // @since v1
+ // @since **v1**
selected_reserve_pub?: EddsaPublicKey;
- // Exchange account selected by the wallet
+ // Exchange account selected by the wallet;
// only non-null if ``status`` is ``selected`` or ``confirmed``.
- // @since v1
+ // @since **v1**
selected_exchange_account?: string;
- // @deprecated since v1, use ``status`` instead
+ // @deprecated since **v1**, use ``status`` instead
// Indicates whether the withdrawal was aborted.
aborted: boolean;
- // @deprecated since v1, use ``status`` instead
+ // @deprecated since **v1**, use ``status`` instead
// Has the wallet selected parameters for the withdrawal operation
// (exchange and reserve public key) and successfully sent it
// to the bank?
selection_done: boolean;
- // @deprecated since v1, use ``status`` instead
+ // @deprecated since **v1**, use ``status`` instead
// The transfer has been confirmed and registered by the bank.
// Does not guarantee that the funds have arrived at the exchange already.
transfer_done: boolean;
}
-
+
.. http:post:: /withdrawal-operation/$WITHDRAWAL_ID
+ This endpoint is used by the GNU Taler wallet to supply additional
+ details needed to complete a withdraw operation.
+
**Request:**
.. ts:def:: BankWithdrawalOperationPostRequest
interface BankWithdrawalOperationPostRequest {
- // Reserve public key.
+
+ // Reserve public key that should become the wire transfer
+ // subject to fund the withdrawal.
reserve_pub: EddsaPublicKey;
- // Payto address of the exchange selected for the withdrawal.
- selected_exchange?: string;
+ // RFC 8905 (payto) address of the exchange account to be
+ // credited for the withdrawal.
+ selected_exchange: string;
+
+ // Selected amount to be transferred. Optional if the
+ // backend already knows the amount.
+ // @since **vC2EC**
+ amount?: Amount;
}
**Response:**
@@ -175,11 +214,15 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
:http:statuscode:`404 Not found`:
The bank does not know about a withdrawal operation with the specified ``WITHDRAWAL_ID``.
:http:statuscode:`409 Conflict`:
- * ``TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT`` :
+ * ``TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT``:
The wallet selected a different exchange or reserve public key under the same withdrawal ID.
- * ``TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT`` : the reserve public key is already used.
- * ``TALER_EC_BANK_UNKNOWN_ACCOUNT`` : the selected exchange account was not found.
- * ``TALER_EC_BANK_ACCOUNT_IS_NOT_EXCHANGE`` : the selected account is not an exchange.
+ * ``TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT``: the reserve public key is already used.
+ * ``TALER_EC_BANK_UNKNOWN_ACCOUNT``: the selected exchange account was not found.
+ * ``TALER_EC_BANK_ACCOUNT_IS_NOT_EXCHANGE``: the selected account is not an exchange.
+ * ``TALER_EC_BANK_AMOUNT_DIFFERS`` : the specified amount will not work for this
+ withdrawal (since **vC2EC**).
+ * ``TALER_EC_BANK_AMOUNT_REQUIRED`` : the backend requires an amount to be
+ specified (since **vC2EC**).
**Details:**
@@ -199,66 +242,25 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
// Only applicable when ``status`` is ``selected`` or ``pending``.
// It may contain withdrawal operation id
confirm_transfer_url?: string;
+
// The transfer has been confirmed and registered by the bank.
// Does not guarantee that the funds have arrived at the exchange already.
transfer_done: boolean;
}
-.. http:post:: /withdrawal-operation/$WITHDRAWAL_ID/confirm
- Since protocol vC2EC
+.. http:post:: /withdrawal-operation/$WITHDRAWAL_ID/abort
- Allows a provider to notify the Bank about the payment. This will trigger a payment
- attestation at the provider, which eventually confirms the payment and allows the
- withdrawal. The API is idempotent, meaning sending a payment
- notification for the same ``WITHDRAWAL_ID`` return successfuly but not change anything.
+ Aborts ``WITHDRAWAL_ID`` operation. Has no effect on an already aborted
+ operation. This endpoint can be used by the wallet if the user aborts
+ the transaction, ensuring that the operation is also aborted at the
+ bank.
- Attention: A bank shall **never** just accept the payment directly but instead attest
- the payment using provider specific attestation logic!
+ Since protocol **v2**.
**Request:**
-
- .. ts:def:: BankWithdrawalConfirmationRequest
-
- interface WithdrawalConfirmationRequest {
- // The provider specific transaction identifier.
- // This identifier is used by the bank to attest the
- // payment at the providers backend.
- provider_transaction_id: string;
-
- // An identifier, which identifies the device
- // processing the payment for the withdrawal
- // triggering the confirmation (e.g. Terminal
- // or ATM). This is needed to link the withdrawal
- // to a terminal owned by a specific provider.
- // This will decide about how the withdrawal
- // is attested. The device must be known to
- // the exchange and be somehow registered.
- terminal_id: number;
-
- // The amount to withdraw. Fees are to be sent in the
- // separate field 'fees' and not included in the amount.
- amount: Amount;
-
- // The fees, the customer payed at the providers facility.
- card_fees: Amount;
- }
- **Response**
-
- :http:statuscode:`204 No content`:
- The payment notification was processed successfully.
- :http:statuscode:`404 Not found`:
- The withdrawal operation was not found.
- :http:statuscode:`409 Conflict`:
- The withdrawal operation has been aborted previously and can't be aborted
-
-
-.. http:post:: /withdrawal-operation/$WITHDRAWAL_ID/abort
-
- Aborts ``WITHDRAWAL_ID`` operation. Has no effect on an already aborted
- operation.
- Since protocol v2.
+ The request body is empty.
**Response:**
@@ -267,4 +269,5 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
:http:statuscode:`404 Not found`:
The withdrawal operation was not found.
:http:statuscode:`409 Conflict`:
- The withdrawal operation has been confirmed previously and can't be aborted.
+ The withdrawal operation has been confirmed previously and
+ can't be aborted.
diff --git a/core/api-bank-wire.rst b/core/api-bank-wire.rst
index a76f5195..84184ec9 100644
--- a/core/api-bank-wire.rst
+++ b/core/api-bank-wire.rst
@@ -133,7 +133,8 @@ Making Transactions
// time period a transaction belongs to).
timestamp: Timestamp;
- // Opaque ID of the transaction that the bank has made.
+ // Opaque ID of the wire transfer initiation performed by the bank.
+ // It is different from the /history endpoints row_id.
row_id: SafeUint64;
}
@@ -429,6 +430,25 @@ exposed by bank gateways in production.
// time period a transaction belongs to).
timestamp: Timestamp;
- // Opaque ID of the transaction that the bank has made.
+ // Opaque ID of the wire transfer initiation performed by the bank.
+ // It is different from the /history endpoints row_id.
row_id: SafeUint64;
}
+
+
+Security Considerations
+=======================
+
+For implementors:
+
+* The withdrawal operation ID must contain enough entropy to be unguessable.
+
+Design:
+
+* The user must complete the 2FA step of the withdrawal in the context of their banking
+ app or online banking Website.
+ We explicitly reject any design where the user would have to enter a confirmation code
+ they get from their bank in the context of the wallet, as this would teach and normalize
+ bad security habits.
+
+
diff --git a/core/api-challenger.rst b/core/api-challenger.rst
index f8631977..afb3096d 100644
--- a/core/api-challenger.rst
+++ b/core/api-challenger.rst
@@ -120,6 +120,19 @@ Receiving Configuration
// @since v0, may become mandatory in the future.
implementation?: string;
+ // @since v2.
+ // Object; map of keys (names of the fields of the address
+ // to be entered by the user) to objects with a "regex" (string)
+ // containing an extended Posix regular expression for allowed
+ // address field values, and a "hint"/"hint_i18n" giving a
+ // human-readable explanation to display if the value entered
+ // by the user does not match the regex. Keys that are not mapped
+ // to such an object have no restriction on the value provided by
+ // the user. See "ADDRESS_RESTRICTIONS" in the challenger configuration.
+ restrictions: Object;
+
+ // @since v2.
+ address_type: "email" | "phone";
}
.. _challenger-setup:
@@ -216,15 +229,8 @@ Login
.. ts:def:: ChallengeStatus
interface ChallengeStatus {
- // Object; map of keys (names of the fields of the address
- // to be entered by the user) to objects with a "regex" (string)
- // containing an extended Posix regular expression for allowed
- // address field values, and a "hint"/"hint_i18n" giving a
- // human-readable explanation to display if the value entered
- // by the user does not match the regex. Keys that are not mapped
- // to such an object have no restriction on the value provided by
- // the user. See "ADDRESS_RESTRICTIONS" in the challenger configuration.
- restrictions: Object;
+ // @deprecated since v2, use /config
+ restrictions?: Object;
// indicates if the given address cannot be changed anymore, the
// form should be read-only if set to true.
@@ -232,11 +238,29 @@ Login
// form values from the previous submission if available, details depend
// on the ``ADDRESS_TYPE``, should be used to pre-populate the form
- last_address: Object;
+ last_address?: Object;
// number of times the address can still be changed, may or may not be
// shown to the user
changes_left: Integer;
+
+ // when we would re-transmit the challenge the next
+ // time (at the earliest) if requested by the user
+ // only present if challenge already created
+ // @since v2
+ retransmission_time: Timestamp;
+
+ // how many times might the PIN still be retransmitted
+
+ // how many times might the PIN still be retransmitted
+ // only present if challenge already created
+ // @since v2
+ pin_transmissions_left?: Integer;
+
+ // how many times might the user still try entering the PIN code
+ // only present if challenge already created
+ // @since v2
+ auth_attempts_left?: Integer;
}
@@ -259,10 +283,17 @@ Challenge
**Response:**
:http:statuscode:`200 OK`:
- If the request ask for application/json the response is `ChallengeCreateResponse`. Since protocol **v1**.
+ If the request ask for application/json the response is `ChallengeResponse`. Since protocol **v2**.
Otherwise, the body contains a form asking for the answer to
the challenge to be entered by the user using the
template :ref:`enter-tan-form <challenger_enter-tan-form>`.
+ :http:statuscode:`302 Found`:
+ Only possible if request didn't ask for application/json. Since protocol **v2**.
+ The user is redirected to the redirect URI of the client to pass the
+ grant to the client. The target will be the redirect URI specified
+ by the client (during registration and again upon ``/authorize``),
+ plus a ``code`` argument with the authorization code, and the
+ ``state`` argument from the ``/authorize`` endpoint.
:http:statuscode:`400 Bad Request`:
The request does not follow the spec.
If the request ask for application/json the response will include error
@@ -287,9 +318,21 @@ Challenge
code, hint and detail. Since protocol **v1**.
Otherwise, the body contains information using the template :ref:`internal-error <challenger_internal-error>`.
+ .. ts:def:: ChallengeResponse
+
+ interface ChallengeResponse = ChallengeRedirect | ChallengeCreateResponse
+
+ .. ts:def:: ChallengeRedirect
+
+ // @since v2
+ interface ChallengeRedirect {
+ // challenge is completed, use should redirect here
+ redirect_url: string;
+ }
+
.. ts:def:: ChallengeCreateResponse
- interface ChallengeCreateResponse {
+ interface ChallengeCreateResponse {
// how many more attempts are allowed, might be shown to the user,
// highlighting might be appropriate for low values such as 1 or 2 (the
@@ -304,10 +347,13 @@ Challenge
// might make a useful hint to the user
transmitted: boolean;
- // timestamp explaining when we would re-transmit the challenge the next
- // time (at the earliest) if requested by the user
- next_tx_time: String;
+ // @deprecated in v2, use retransmission_time
+ next_tx_time?: string;
+ // when we would re-transmit the challenge the next
+ // time (at the earliest) if requested by the user
+ // @since v2
+ retransmission_time: Timestamp;
}
@@ -330,7 +376,10 @@ Solve
**Response:**
+ :http:statuscode:`200 OK`:
+ If the request ask for application/json the response is `ChallengeSolveResponse`. Since protocol **v2**.
:http:statuscode:`302 Found`:
+ Only possible if request didn't ask for application/json. Since protocol **v2**.
The user is redirected to the redirect URI of the client to pass the
grant to the client. The target will be the redirect URI specified
by the client (during registration and again upon ``/authorize``),
@@ -360,6 +409,10 @@ Solve
code, hint and detail. Since protocol **v1**.
Otherwise, the body contains information using the template :ref:`internal-error <challenger_internal-error>`.
+ .. ts:def:: ChallengeSolveResponse
+
+ type ChallengeSolveResponse = ChallengeRedirect | InvalidPinResponse;
+
.. ts:def:: InvalidPinResponse
interface InvalidPinResponse {
@@ -369,7 +422,7 @@ Solve
// human-readable Taler error code, should be shown for the user to
// understand the error
- hint: String;
+ hint: string;
// how many times is the user still allowed to change the address;
// if 0, the user should not be shown a link to jump to the
diff --git a/core/api-common.rst b/core/api-common.rst
index 521b2fc0..2208eb8d 100644
--- a/core/api-common.rst
+++ b/core/api-common.rst
@@ -255,6 +255,11 @@ hashed data. See `base32`_.
// 32-byte hash code.
type ShortHashCode = string;
+.. ts:def:: AccountAccessToken
+
+ // 32-byte nonce.
+ type AccountAccessToken = string;
+
.. ts:def:: WireSalt
// 16-byte salt.
@@ -758,6 +763,56 @@ denoting microseconds since the UNIX Epoch. ``UINT64_MAX`` represents "never".
uint64_t abs_value_us__; // in network byte order
};
+.. _LegalTrouble:
+
+451 Responses
+^^^^^^^^^^^^^
+
+When KYC operations are required, various endpoints may respond with a
+``451 Unavailable for Legal Reasons`` status code and a `LegitimizationNeededResponse`
+body.
+
+.. ts:def:: LegitimizationNeededResponse
+
+ // Implemented in this style since exchange
+ // protocol **v20**.
+ interface LegitimizationNeededResponse {
+
+ // Numeric `error code <error-codes>` unique to the condition.
+ // Should always be ``TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED``.
+ code: number;
+
+ // Human-readable description of the error, i.e. "missing parameter",
+ // "commitment violation", ... Should give a human-readable hint
+ // about the error's nature. Optional, may change without notice!
+ hint?: string;
+
+ // Hash of the payto:// account URI for which KYC
+ // is required.
+ h_payto: PaytoHash;
+
+ // Public key associated with the account. The client must sign
+ // the initial request for the KYC status using the corresponding
+ // private key. Will be either a reserve public key or a merchant
+ // (instance) public key.
+ //
+ // Absent if no public key is currently associated
+ // with the account and the client MUST thus first
+ // credit the exchange via an inbound wire transfer
+ // to associate a public key with the debited account.
+ account_pub?: EddsaPublicKey;
+
+ // Identifies a set of measures that were triggered and that are
+ // now preventing this operation from proceeding. Gives the
+ // account holder a starting point for understanding why the
+ // transaction was blocked and how to lift it. The account holder
+ // should use the number to check for the account's AML/KYC status
+ // using the ``/kyc-check/$REQUIREMENT_ROW`` endpoint.
+ requirement_row: Integer;
+
+ }
+
+
Cryptographic primitives
^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/core/api-corebank.rst b/core/api-corebank.rst
index 680b2724..f9ab7caa 100644
--- a/core/api-corebank.rst
+++ b/core/api-corebank.rst
@@ -88,7 +88,7 @@ Config
// @since v4, will become mandatory in the next version.
bank_name?: string;
- // Advertised base URL to use when you sharing an URL with another
+ // Advertised base URL to use when you sharing an URL with another
// program.
// @since v4.
base_url?: string;
@@ -188,6 +188,11 @@ Account Management
// Only admin can set this property.
debit_threshold?: Amount;
+ // If present, set a custom minimum cashout amount for this account.
+ // Only admin can set this property
+ // @since v4
+ min_cashout?: Amount;
+
// If present, enables 2FA and set the TAN channel used for challenges
// Only admin can set this property, other user can reconfig their account
// after creation.
@@ -220,6 +225,7 @@ Account Management
* ``TALER_EC_BANK_UNALLOWED_DEBIT`` : admin account does not have sufficient funds to grant bonus.
* ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank``
* ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to create an account with a customer debt limit.
+ * ``TALER_EC_BANK_NON_ADMIN_SET_MIN_CASHOUT`` : a non-admin user has tried to create an account with a custom min cashout amount.
* ``TALER_EC_BANK_NON_ADMIN_SET_TAN_CHANNEL`` : a non-admin user has tried to create an account with 2fa.
* ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED``: ``tan_channel`` is not supported, check bank config to find supported ones.
* ``TALER_EC_BANK_MISSING_TAN_INFO``: the user did not share any contact data where to send the TAN via ``tan_channel``.
@@ -233,28 +239,6 @@ Account Management
internal_payto_uri: string;
}
-.. _delete-account:
-
-.. http:delete:: /accounts/$USERNAME
-
- Delete the account whose username is ``$USERNAME``. The deletion
- succeeds only if the balance is *zero*. Typically only available to
- the administrator, but can be configured to allow ordinary users too.
-
- **Response:**
-
- :http:statuscode:`202 Accepted`:
- 2FA is required for this operation. This returns the `Challenge` response.
- :http:statuscode:`204 No content`:
- The account was successfully deleted.
- :http:statuscode:`401 Unauthorized`:
- Invalid credentials or missing rights.
- :http:statuscode:`404 Not found`:
- The account pointed by ``$USERNAME`` was not found.
- :http:statuscode:`409 Conflict`:
- * ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank``.
- * ``TALER_EC_BANK_ACCOUNT_BALANCE_NOT_ZERO``: the account balance was not zero.
-
.. _account-reconfig:
.. http:patch:: /accounts/$USERNAME
@@ -288,6 +272,11 @@ Account Management
// Only admin can change this property.
debit_threshold?: Amount;
+ // If present, change the custom minimum cashout amount for this account.
+ // Only admin can set this property
+ // @since v4
+ min_cashout?: Amount;
+
// If present, enables 2FA and set the TAN channel used for challenges
tan_channel?: TanChannel;
}
@@ -306,6 +295,7 @@ Account Management
* ``TALER_EC_BANK_NON_ADMIN_PATCH_LEGAL_NAME`` : a non-admin user has tried to change their legal name.
* ``TALER_EC_BANK_NON_ADMIN_PATCH_CASHOUT`` : a non-admin user has tried to change their cashout account.
* ``TALER_EC_BANK_NON_ADMIN_PATCH_DEBT_LIMIT`` : a non-admin user has tried to change their debt limit.
+ * ``TALER_EC_BANK_NON_ADMIN_SET_MIN_CASHOUT`` : a non-admin user has tried to change their custom min cashout amount.
* ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED`` : ``tan_channel`` is not supported, check bank config to find supported ones.
* ``TALER_EC_BANK_MISSING_TAN_INFO`` : the user did not share any contact data where to send the TAN via ``tan_channel``.
@@ -343,6 +333,29 @@ Account Management
* ``TALER_EC_BANK_NON_ADMIN_PATCH_MISSING_OLD_PASSWORD``: a non-admin user has tried to change their password whihout providing the current one.
* ``TALER_EC_BANK_PATCH_BAD_OLD_PASSWORD`` : provided old password does not match current password.
+
+.. _delete-account:
+
+.. http:delete:: /accounts/$USERNAME
+
+ Delete the account whose username is ``$USERNAME``. The deletion
+ succeeds only if the balance is *zero*. Typically only available to
+ the administrator, but can be configured to allow ordinary users too.
+
+ **Response:**
+
+ :http:statuscode:`202 Accepted`:
+ 2FA is required for this operation. This returns the `Challenge` response.
+ :http:statuscode:`204 No content`:
+ The account was successfully deleted.
+ :http:statuscode:`401 Unauthorized`:
+ Invalid credentials or missing rights.
+ :http:statuscode:`404 Not found`:
+ The account pointed by ``$USERNAME`` was not found.
+ :http:statuscode:`409 Conflict`:
+ * ``TALER_EC_BANK_RESERVED_USERNAME_CONFLICT`` : a reserved username was attempted, like ``admin`` or ``bank``.
+ * ``TALER_EC_BANK_ACCOUNT_BALANCE_NOT_ZERO``: the account balance was not zero.
+
.. _account-list:
.. http:get:: /public-accounts
@@ -460,6 +473,11 @@ Account Management
// Number indicating the max debit allowed for the requesting user.
debit_threshold: Amount;
+ // Custom minimum cashout amount for this account.
+ // If null or absent, the global conversion fee is used.
+ // @since v4
+ min_cashout?: Amount;
+
// Is this account visible to anyone?
is_public: boolean;
@@ -472,7 +490,7 @@ Account Management
// Current status of the account
// active: the account can be used
- // deleted: the account has been deleted but is retained for compliance
+ // deleted: the account has been deleted but is retained for compliance
// reasons, only the administrator can access it
// Default to 'active' is missing
// @since v4, will become mandatory in the next version.
@@ -513,6 +531,11 @@ Account Management
// Number indicating the max debit allowed for the requesting user.
debit_threshold: Amount;
+ // Custom minimum cashout amount for this account.
+ // If null or absent, the global conversion fee is used.
+ // @since v4
+ min_cashout?: Amount;
+
// Addresses where to send the TAN for transactions.
// Currently only used for cashouts.
// If missing, cashouts will fail.
@@ -539,7 +562,7 @@ Account Management
// Current status of the account
// active: the account can be used
- // deleted: the account has been deleted but is retained for compliance
+ // deleted: the account has been deleted but is retained for compliance
// reasons, only the administrator can access it
// Default to 'active' is missing
// @since v4, will become mandatory in the next version.
@@ -682,8 +705,8 @@ Transactions
row_id: Integer;
}
-Taler Withdrawals
------------------
+Account withdrawals
+-------------------
.. http:post:: /accounts/$USERNAME/withdrawals
@@ -691,12 +714,7 @@ Taler Withdrawals
**Request:**
- .. ts:def:: BankAccountCreateWithdrawalRequest
-
- interface BankAccountCreateWithdrawalRequest {
- // Amount to withdraw.
- amount: Amount;
- }
+ The request must be a `BankAccountCreateWithdrawalRequest`.
**Response:**
@@ -709,6 +727,28 @@ Taler Withdrawals
**Details:**
+ .. ts:def:: BankAccountCreateWithdrawalRequest
+
+ interface BankAccountCreateWithdrawalRequest {
+
+ // Amount to withdraw. If given, the wallet
+ // cannot change the amount.
+ // Optional since **vC2EC**.
+ amount?: Amount;
+
+ // Suggested amount to withdraw. The wallet can
+ // still change the suggestion.
+ // @since **vC2EC**
+ suggested_amount?: Amount;
+
+ // The non-Taler card fees the customer will have
+ // to pay to the account owner, bank and/or
+ // payment service provider
+ // they are using to make this withdrawal.
+ // @since **vC2EC**
+ card_fees?: Amount;
+ }
+
.. ts:def:: BankAccountCreateWithdrawalResponse
interface BankAccountCreateWithdrawalResponse {
@@ -866,9 +906,10 @@ Cashouts
The account pointed by ``$USERNAME`` was not found.
:http:statuscode:`409 Conflict`:
* ``TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED``: an operation with the same ``request_uid`` but different details has been submitted before.
- * ``TALER_EC_BANK_BAD_CONVERSION`` : exchange rate was calculated incorrectly by the client.
- * ``TALER_EC_BANK_UNALLOWED_DEBIT`` : the account does not have sufficient funds.
- * ``TALER_EC_BANK_CONFIRM_INCOMPLETE`` : the user did not share any cashout payto to uri where to wire funds.
+ * ``TALER_EC_BANK_BAD_CONVERSION``: exchange rate was calculated incorrectly by the client.
+ * ``TALER_EC_BANK_BANK_CONVERSION_AMOUNT_TO_SMALL``: the amount of the cashout is too small.
+ * ``TALER_EC_BANK_UNALLOWED_DEBIT``: the account does not have sufficient funds.
+ * ``TALER_EC_BANK_CONFIRM_INCOMPLETE``: the user did not share any cashout payto to uri where to wire funds.
:http:statuscode:`501 Not Implemented`:
* ``TALER_EC_BANK_TAN_CHANNEL_NOT_SUPPORTED``: the chosen ``tan_channel`` is not currently supported.
* This server does not support conversion, client should check config response.
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 4c5be000..31d46158 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -62,7 +62,7 @@ possibly by using HTTPS.
as well as the list of possible KYC requirements. This endpoint is largely
for the SPA for AML officers. Merchants should use ``/keys`` which also
contains the protocol version and currency.
- This specification corresponds to ``current`` protocol being **v19**.
+ This specification corresponds to ``current`` protocol being **v20**.
**Response:**
@@ -1323,19 +1323,188 @@ to allow exchange staff to monitor suspicious transactions
and freeze or unfreeze accounts suspected of money laundering.
-.. http:get:: /aml/$OFFICER_PUB/decisions/$STATE
+.. http:get:: /aml/$OFFICER_PUB/measures
- Obtain list of AML decisions (filtered by $STATE). ``$STATE`` must be either ``normal``, ``pending`` or ``frozen``.
+ To enable the AML staff SPA to give AML staff a choice of possible measures, a
+ new endpoint ``/aml/$OFFICER_PUB/measures`` is added that allows the AML SPA
+ to dynamically GET the list of available measures. It returns a list of known
+ KYC checks (by name) with their descriptions and a list of AML programs with
+ information about the required context.
- *Taler-AML-Officer-Signature*: The client must provide Base-32 encoded EdDSA signature with ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that this is merely a simple authentication mechanism, the details of the request are not protected by the signature.
+ This endpoint was introduced in protocol **v20**.
- :query delta: *Optional*. takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries (before ``start``).
- :query start: *Optional*. Row number threshold, see ``delta`` for its interpretation. Defaults to ``INT64_MAX``, namely the biggest row id possible in the database.
+ **Request:**
- **Response**
+ *Taler-AML-Officer-Signature*:
+ The client must provide Base-32 encoded EdDSA signature with
+ ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that
+ this is merely a simple authentication mechanism, the details of the
+ request are not protected by the signature.
+
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ Information about possible measures is returned in a
+ `AvailableMeasureSummary` object.
+
+ **Details:**
+
+ .. ts:def:: AvailableMeasureSummary
+
+ interface AvailableMeasureSummary {
+
+ // Available original measures that can be
+ // triggered directly by default rules.
+ roots: { "$measure_name" : MeasureInformation; };
+
+ // Available AML programs.
+ programs: { "$prog_name" : AmlProgramRequirement; };
+
+ // Available KYC checks.
+ checks: { "$check_name" : KycCheckInformation; };
+
+ }
+
+ .. ts:def:: MeasureInformation
+
+ interface MeasureInformation {
+
+ // Name of a KYC check.
+ check_name: string;
+
+ // Name of an AML program.
+ prog_name: string;
+
+ // Context for the check. Optional.
+ context?: Object;
+
+ }
+
+ .. ts:def:: AmlProgramRequirement
+
+ interface AmlProgramRequirement {
+
+ // Description of what the AML program does.
+ description: string;
+
+ // List of required field names in the context to run this
+ // AML program. SPA must check that the AML staff is providing
+ // adequate CONTEXT when defining a measure using this program.
+ context: string[];
+
+ // List of required attribute names in the
+ // input of this AML program. These attributes
+ // are the minimum that the check must produce
+ // (it may produce more).
+ inputs: string[];
+
+ }
+
+ .. ts:def:: KycCheckInformation
+
+ interface KycCheckInformation {
+
+ // Description of the KYC check. Should be shown
+ // to the AML staff but will also be shown to the
+ // client when they initiate the check in the KYC SPA.
+ description: string;
+ description_i18n: {};
+
+ // Names of the fields that the CONTEXT must provide
+ // as inputs to this check.
+ // SPA must check that the AML staff is providing
+ // adequate CONTEXT when defining a measure using
+ // this check.
+ requires: string[];
+
+ // Names of the attributes the check will output.
+ // SPA must check that the outputs match the
+ // required inputs when combining a KYC check
+ // with an AML program into a measure.
+ outputs: string[];
+
+ // Name of a root measure taken when this check fails.
+ fallback: string;
+ }
+
+.. http:get:: /aml/$OFFICER_PUB/kyc-statistics/$NAME
+
+ Returns the number of KYC events matching the given event type ``$NAME`` in
+ the specified time range. Note that this query can be slow as the
+ statistics are computed on-demand. (This is OK as such requests should be
+ rare.)
+
+ This endpoint was introduced in protocol **v20**.
+
+ **Request:**
+
+ *Taler-AML-Officer-Signature*:
+ The client must provide Base-32 encoded EdDSA signature with
+ ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that this
+ is merely a simple authentication mechanism, the details of the request are
+ not protected by the signature.
+
+ :query start_date=TIMESTAMP:
+ *Optional*. Specifies the date when to
+ start looking (inclusive). If not given, the start time of the
+ exchange operation is used.
+ :query end_date=TIMESTAMP:
+ *Optional*. Specifies the date when to
+ stop looking (exclusive). If not given, the current date is used.
+
+ **Response:**
:http:statuscode:`200 OK`:
- The responds will be an `AmlRecords` message.
+ The responds will be an `EventCounter` message.
+
+ **Details:**
+
+ .. ts:def:: EventCounter
+
+ interface EventCounter {
+ // Number of events of the specified type in
+ // the given range.
+ counter: Integer;
+ }
+
+
+.. http:get:: /aml/$OFFICER_PUB/decisions
+
+ **Request:**
+
+ *Taler-AML-Officer-Signature*:
+ The client must provide Base-32 encoded EdDSA signature with
+ ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that
+ this is merely a simple authentication mechanism, the details of the
+ request are not protected by the signature.
+
+ This endpoint was introduced in this form in protocol **v20**.
+
+ :query limit:
+ *Optional*. takes value of the form ``N (-N)``, so that at
+ most ``N`` values strictly older (younger) than ``start`` are returned.
+ Defaults to ``-20`` to return the last 20 entries (before ``start``).
+ :query offset:
+ *Optional*. Row number threshold, see ``delta`` for its
+ interpretation. Defaults to ``INT64_MAX``, namely the biggest row id
+ possible in the database.
+ :query h_payto:
+ *Optional*. Account selector. All matching accounts are returned if this
+ filter is absent, otherwise only decisions for this account.
+ :query active:
+ *Optional*. If set to yes, only return active decisions, if no only
+ decisions that have been superceeded. Do not give (or use "all") to
+ see all decisions regardless of activity status.
+ :query investigation:
+ *Optional*. If set to yes, only return accounts that are under
+ AML investigation, if no only accounts that are not under investigation.
+ Do not give (or use "all") to see all accounts regardless of
+ investigation status.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The responds will be an `AmlDecisions` message.
:http:statuscode:`204 No content`:
There are no matching AML records.
:http:statuscode:`403 Forbidden`:
@@ -1347,100 +1516,217 @@ and freeze or unfreeze accounts suspected of money laundering.
**Details:**
- .. ts:def:: AmlRecords
+ .. ts:def:: AmlDecisions
- interface AmlRecords {
+ interface AmlDecisions {
- // Array of AML records matching the query.
- records: AmlRecord[];
+ // Array of AML decisions matching the query.
+ records: AmlDecision[];
}
- .. ts:def:: AmlRecord
+ .. ts:def:: AmlDecision
- interface AmlRecord {
+ interface AmlDecision {
// Which payto-address is this record about.
// Identifies a GNU Taler wallet or an affected bank account.
h_payto: PaytoHash;
- // What is the current AML state.
- current_state: Integer;
+ // Row ID of the record. Used to filter by offset.
+ rowid: Integer;
- // Monthly transaction threshold before a review will be triggered
- threshold: Amount;
+ // Justification for the decision.
+ justification: string;
- // RowID of the record.
- rowid: Integer;
+ // When was the decision made?
+ decision_time: Timestamp;
+
+ // Free-form properties about the account.
+ // Can be used to store properties such as PEP,
+ // risk category, type of business, hits on
+ // sanctions lists, etc.
+ properties?: AccountProperties;
+
+ // What are the new rules?
+ limits: LegitimizationRuleSet;
+
+ // True if the account is under investigation by AML staff
+ // after this decision.
+ to_investigate: boolean;
+
+ // True if this is the active decision for the
+ // account.
+ is_active: boolean;
}
+ .. ts:def:: AccountProperties
-.. http:get:: /aml/$OFFICER_PUB/decision/$H_PAYTO
+ // All fields in this object are optional. The actual
+ // properties collected depend fully on the discretion
+ // of the exchange operator;
+ // however, some common fields are standardized
+ // and thus described here.
+ interface AccountProperties {
- Obtain deails about an AML decision.
+ // True if this is a politically exposed account.
+ // Rules for classifying accounts as politically
+ // exposed are country-dependent.
+ pep?: boolean;
- *Taler-AML-Officer-Signature*: The client must provide Base-32 encoded EdDSA signature with ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that this is merely a simple authentication mechanism, the details of the request are not protected by the signature.
+ // True if this is a sanctioned account.
+ // Rules for classifying accounts as sanctioned
+ // are country-dependent.
+ sanctioned?: boolean;
- :query history: *Optional*. If set to yes, we return all historic decisions and not only the last one.
+ // True if this is a high-risk account.
+ // Rules for classifying accounts as at-risk
+ // are exchange operator-dependent.
+ high_risk?: boolean;
- **Response**
+ // Business domain of the account owner.
+ // The list of possible business domains is
+ // operator- or country-dependent.
+ business_domain?: string;
- :http:statuscode:`200 OK`:
- The responds will be an `AmlDecisionDetails` message.
- :http:statuscode:`204 No content`:
- There are no matching AML records for the given payto://-URI.
- :http:statuscode:`403 Forbidden`:
- The signature is invalid.
- :http:statuscode:`404 Not found`:
- The designated AML account is not known.
- :http:statuscode:`409 Conflict`:
- The designated AML account is not enabled.
+ // Is the client's account currently frozen?
+ is_frozen?: boolean;
- **Details:**
+ // Was the client's account reported to the authorities?
+ was_reported?: boolean;
- .. ts:def:: AmlDecisionDetails
+ }
- interface AmlDecisionDetails {
+ .. ts:def:: LegitimizationRuleSet
+
+ interface LegitimizationRuleSet {
+
+ // When does this set of rules expire and
+ // we automatically transition to the successor
+ // measure?
+ expiration_time: Timestamp;
- // Array of AML decisions made for this account. Possibly
- // contains only the most recent decision if "history" was
- // not set to 'true'.
- aml_history: AmlDecisionDetail[];
+ // Name of the measure to apply when the expiration time is
+ // reached. If not set, we refer to the default
+ // set of rules (and the default account state).
+ successor_measure?: string;
+
+ // Legitimization rules that are to be applied
+ // to this account.
+ rules: KycRule[];
+
+ // Custom measures that KYC rules and the
+ // ``successor_measure`` may refer to.
+ custom_measures: { "$measure_name" : MeasureInformation; };
- // Array of KYC attributes obtained for this account.
- kyc_attributes: KycDetail[];
}
- .. ts:def:: AmlDecisionDetail
+ .. ts:def:: KycRule
- interface AmlDecisionDetail {
+ interface KycRule {
- // What was the justification given?
- justification: string;
+ // Type of operation to which the rule applies.
+ operation_type: string;
- // FIXME: review!
- // What is the new AML state.
- new_state: Integer;
+ // The measures will be taken if the given
+ // threshold is crossed over the given timeframe.
+ threshold: Amount;
- // When was this decision made?
- decision_time: Timestamp;
+ // Over which duration should the ``threshold`` be
+ // computed. All amounts of the respective
+ // ``operation_type`` will be added up for this
+ // duration and the sum compared to the ``threshold``.
+ timeframe: RelativeTime;
+
+ // Array of names of measures to apply.
+ // Names listed can be original measures or
+ // custom measures from the `AmlOutcome`.
+ // A special measure "verboten" is used if the
+ // threshold may never be crossed.
+ measures: string[];
+
+ // If multiple rules apply to the same account
+ // at the same time, the number with the highest
+ // rule determines which set of measures will
+ // be activated and thus become visible for the
+ // user.
+ display_priority: Integer;
+
+ // True if the rule (specifically, operation_type,
+ // threshold, timeframe) and the general nature of
+ // the measures (verboten or approval required)
+ // should be exposed to the client.
+ // Defaults to "false" if not set.
+ exposed?: boolean;
+
+ // True if all the measures will eventually need to
+ // be satisfied, false if any of the measures should
+ // do. Primarily used by the SPA to indicate how
+ // the measures apply when showing them to the user;
+ // in the end, AML programs will decide after each
+ // measure what to do next.
+ // Default (if missing) is false.
+ is_and_combinator?: boolean;
+
+ }
+
+.. http:get:: /aml/$OFFICER_PUB/attributes/$H_PAYTO
+
+ Obtain attributes obtained as part of AML/KYC processes for a
+ given account.
+
+ This endpoint was introduced in protocol **v20**.
+
+ **Request:**
+
+ *Taler-AML-Officer-Signature*:
+ The client must provide Base-32 encoded EdDSA signature with
+ ``$OFFICER_PRIV``, affirming the desire to obtain AML data. Note that
+ this is merely a simple authentication mechanism, the details of the
+ request are not protected by the signature.
+
+ :query limit:
+ *Optional*. takes value of the form ``N (-N)``, so that at
+ most ``N`` values strictly older (younger) than ``start`` are returned.
+ Defaults to ``-20`` to return the last 20 entries (before ``start``).
+ :query offset:
+ *Optional*. Row number threshold, see ``delta`` for its
+ interpretation. Defaults to ``INT64_MAX``, namely the biggest row id
+ possible in the database.
+
+ **Response:**
- // What is the new AML decision threshold (in monthly transaction volume)?
- new_threshold: Amount;
+ :http:statuscode:`200 OK`:
+ The responds will be an `KycAttributes` message.
+ :http:statuscode:`204 No content`:
+ There are no matching KYC attributes.
+ :http:statuscode:`403 Forbidden`:
+ The signature is invalid.
+ :http:statuscode:`404 Not found`:
+ The designated AML account is not known.
+ :http:statuscode:`409 Conflict`:
+ The designated AML account is not enabled.
+
+ .. ts:def:: KycAttributes
- // Who made the decision?
- decider_pub: AmlOfficerPublicKeyP;
+ interface KycAttributes {
+
+ // Matching KYC attribute history of the account.
+ details: KycAttributeCollectionEvent[];
}
- .. ts:def:: KycDetail
+ .. ts:def:: KycAttributeCollectionEvent
- interface KycDetail {
+ interface KycAttributeCollectionEvent {
- // Name of the configuration section that specifies the provider
- // which was used to collect the KYC details
- // FIXME: review!
- provider_section: string;
+ // Row ID of the record. Used to filter by offset.
+ rowid: Integer;
+
+ // Name of the provider
+ // which was used to collect the attributes. NULL if they were
+ // just uploaded via a form by the account owner.
+ provider_name?: string;
// The collected KYC data. NULL if the attribute data could not
// be decrypted (internal error of the exchange, likely the
@@ -1450,9 +1736,6 @@ and freeze or unfreeze accounts suspected of money laundering.
// Time when the KYC data was collected
collection_time: Timestamp;
- // Time when the validity of the KYC data will expire
- expiration_time: Timestamp;
-
}
@@ -1487,17 +1770,17 @@ and freeze or unfreeze accounts suspected of money laundering.
// Human-readable justification for the decision.
justification: string;
- // At what monthly transaction volume should the
- // decision be automatically reviewed?
- new_threshold: Amount;
-
// Which payto-address is the decision about?
// Identifies a GNU Taler wallet or an affected bank account.
h_payto: PaytoHash;
- // What is the new AML state (e.g. frozen, unfrozen, etc.)
- // Numerical values are defined in `AmlDecisionState`.
- new_state: Integer;
+ // What are the new rules?
+ // New since protocol **v20**.
+ new_rules: LegitimizationRuleSet;
+
+ // True if the account should remain under investigation by AML staff.
+ // New since protocol **v20**.
+ keep_investigating: boolean;
// Signature by the AML officer over a `TALER_AmlDecisionPS`.
// Must have purpose ``TALER_SIGNATURE_MASTER_AML_KEY``.
@@ -1506,9 +1789,6 @@ and freeze or unfreeze accounts suspected of money laundering.
// When was the decision made?
decision_time: Timestamp;
- // Optional argument to impose new KYC requirements
- // that the customer has to satisfy to unblock transactions.
- kyc_requirements?: string[];
}
@@ -1769,7 +2049,7 @@ Batch Withdraw
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.
+ The response will be an `LegitimizationNeededResponse` object.
Implementation note: internally, we need to
distinguish between upgrading the reserve to an
@@ -1857,29 +2137,6 @@ Batch Withdraw
}
- .. ts:def:: KycNeededRedirect
-
- interface KycNeededRedirect {
-
- // Numeric `error code <error-codes>` unique to the condition.
- // Should always be ``TALER_EC_EXCHANGE_GENERIC_KYC_REQUIRED``.
- code: number;
-
- // Human-readable description of the error, i.e. "missing parameter", "commitment violation", ...
- // Should give a human-readable hint about the error's nature. Optional, may change without notice!
- hint?: string;
-
- // Hash of the payto:// account URI that identifies
- // the account which is being KYCed.
- 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;
-
- }
-
.. ts:def:: WithdrawError
interface WithdrawError {
@@ -1986,7 +2243,7 @@ If so, the exchange will blindly sign ``n`` undisclosed coins from the request.
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.
+ The response will be an `LegitimizationNeededResponse` object.
.. ts:def:: AgeWithdrawRequest
@@ -3970,6 +4227,7 @@ typically also view the balance.)
// Current AML state for the target account. Non-zero
// values indicate that the transfer is blocked due to
// AML enforcement.
+ // Removed in protocol **v20**.
aml_decision: Integer;
// True if the KYC check for the merchant has been
@@ -4465,7 +4723,7 @@ Wallet-to-wallet transfers
: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.
- The response will be an `KycNeededRedirect` object.
+ The response will be an `LegitimizationNeededResponse` object.
**Details:**
@@ -4576,7 +4834,7 @@ Wallet-to-wallet transfers
: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.
- The response will be an `KycNeededRedirect` object.
+ The response will be an `LegitimizationNeededResponse` object.
**Details:**
@@ -4869,6 +5127,17 @@ regulatory compliance.
.. http:post:: /kyc-wallet
+ The ``/wallet-kyc`` POST endpoint allows a wallet to notify an exchange if
+ it will cross a balance threshold. Here, the ``balance`` specified should be
+ the threshold (from the ``wallet_balance_limit_without_kyc`` array) that the
+ wallet would cross, and *not* the *exact* balance of the wallet. The exchange
+ will respond with a wire target UUID. The wallet can then use this UUID to
+ being the KYC process at ``/kyc-check/``. The wallet must only proceed to
+ obtain funds exceeding the threshold after the KYC process has concluded.
+ While wallets could be "hacked" to bypass this measure (we cannot
+ cryptographically enforce this), such modifications are a terms of service
+ violation which may have legal consequences for the user.
+
Setup KYC identification for a wallet. Returns the KYC UUID.
This endpoint is used by compliant Taler wallets when they
are about to hit the balance threshold and thus need to have
@@ -4892,7 +5161,7 @@ regulatory compliance.
This response comes with a standard `ErrorDetail` response.
:http:statuscode:`451 Unavailable for Legal Reasons`:
The wallet must undergo a KYC check. A KYC ID was created.
- The response will be a `WalletKycUuid` object.
+ The response will be a `LegitimizationNeededResponse` object (changed in protocol **v20**).
**Details:**
@@ -4915,73 +5184,74 @@ regulatory compliance.
reserve_pub: EddsaPublicKey;
}
- .. ts:def:: WalletKycUuid
+.. http:get:: /kyc-check/$REQUIREMENT_ROW
- interface WalletKycUuid {
+ Checks the KYC status of a particular payment target and possibly begins a
+ KYC process by allowing the customer to choose the next KYC measure to
+ satisfy. This endpoint is typically used by wallets or merchants that
+ have been told that a transaction is not happening because it triggered
+ some KYC/AML measure and now want to check how the KYC/AML
+ requirement could be fulfilled (or whether it already has been
+ statisfied and the operation can now proceed). Long-polling may be used
+ to instantly observe a change in the KYC requirement status.
- // UUID that the wallet should use when initiating
- // the KYC check.
- requirement_row: number;
+ The requirement row of the ``/kyc-check/`` endpoint encodes the
+ legitimization measure's serial number. It is returned in
+ `LegitimizationNeededResponse` responses via the ``requirement_row`` field.
- // Hash of the payto:// account URI for the wallet.
- h_payto: PaytoHash;
-
- }
+ Given a valid pair of requirement row and account owner signature, the
+ ``/kyc-check/`` endpoint returns either just the KYC status or redirects the
+ client (202) to the next required stage of the KYC process. The redirection
+ must be for an HTTP(S) endpoint to be triggered via a simple HTTP GET. It
+ must always be the same endpoint for the same client, as the wallet/merchant
+ backend are not required to check for changes to this endpoint. Clients
+ that received a 202 status code may repeat the request and use long-polling
+ to detect a change of the HTTP status.
+ This endpoint exists in this specific form only since protocol **v20**.
-.. http:get:: /kyc-check/$REQUIREMENT_ROW/$H_PAYTO/$USERTYPE
-
- Checks the KYC status of a particular payment target and possibly begins the
- KYC process. This endpoint is used by wallets or merchants that have been
- told about a KYC requirement and now want to check if the KYC requirement
- has been fulfilled. Long-polling may be used to instantly observe a change
- in the KYC requirement status.
+ **Request:**
- Returns the current KYC status of the requirement process and, if negative,
- returns the URL where the KYC process can be initiated. The
- ``$REQUIREMENT_ROW`` must have been returned previously from an exchange API
- endpoint that determined that KYC was needed. The ``$H_PATYO`` must be the
- hash of the "payto://" URI of the payment target. The ``$USERTYPE`` states
- whether the entity to perform the KYC is an "individual" or a "business".
+ *Account-Owner-Signature*:
- **Request:**
+ The client must provide Base-32 encoded EdDSA signature with
+ ``$ACCOUNT_PRIV``, affirming the desire to obtain KYC data. Note that
+ this is merely a simple authentication mechanism, the details of the
+ request are not protected by the signature. The ``$ACCOUNT_PRIV`` is
+ either the (wallet long-term) reserve private key or the merchant instance
+ private key.
:query timeout_ms=NUMBER: *Optional.* If specified, the exchange will
- wait up to ``timeout_ms`` milliseconds if the payment target
- is currently not legitimized. Ignored if the payment target
- is already legitimized. Note that the legitimization would be
- triggered by another request to the same endpoint with a valid
- ``token``.
+ wait up to ``timeout_ms`` milliseconds if the requirement continues
+ to be mandatory provisioning of KYC data by the client.
+ Ignored if the HTTP status code is already ``200 Ok``. Note that
+ clients cannot long-poll for AML staff actions, so status information
+ about an account being under AML review needs to be requested
+ periodically.
**Response:**
:http:statuscode:`200 Ok`:
- The KYC operation succeeded, the exchange confirms that the
- payment target already authorized to transact.
- The response will be an `AccountKycStatus` object.
+ No mandatory KYC actions are required by the client at this time.
+ The client *may* still visit the KYC URL to initiate voluntary checks.
+ The response will be an `AccountKycStatus` object which specifies
+ restrictions that currently apply to the account. If the
+ client attempts to exceed *soft* limits, the status may change
+ to a ``202 Accepted``. Hard limits cannot be lifted by passing KYC checks.
:http:statuscode:`202 Accepted`:
- The user should be redirected to the provided location to perform
+ The account holder performed an operation that would have crossed
+ *soft* limits and must be redirected to the provided location to perform
the required KYC checks to satisfy the legal requirements. Afterwards, the
``/kyc-check/`` request should be repeated to check whether the
user has completed the process.
- The response will be an `AccountKycRedirect` object.
+ The response will be an `AccountKycStatus` object.
:http:statuscode:`204 No content`:
The exchange is not configured to perform KYC and thus
the legal requirements are already satisfied.
- :http:statuscode:`402 Payment Required`:
- The client must pay the KYC fee for the KYC process.
- **This is currently not implemented, see #7365.**
:http:statuscode:`403 Forbidden`:
- The provided hash does not match the payment target.
+ The provided signature is not acceptable for the requirement row.
:http:statuscode:`404 Not found`:
- The payment target is unknown.
- :http:statuscode:`451 Unavailable for Legal Reasons`:
- The transaction cannot be completed due to AML rules.
- Thus, the operation is currently not stuck on KYC, but
- on exchange staff performing their AML review. The user
- should be told to wait and/or contact the exchange operator
- if the situation persists.
- The response will be a `AccountAmlBlocked` object.
+ The requirement row is unknown.
**Details:**
@@ -4989,75 +5259,274 @@ regulatory compliance.
interface AccountKycStatus {
- // Details about the KYC check that the user
- // passed.
- kyc_details: KycDetails;
+ // Current AML state for the target account. True if
+ // operations are not happening due to staff processing
+ // paperwork *or* due to legal requirements (so the
+ // client cannot do anything but wait).
+ //
+ // Note that not every AML staff action may be legally
+ // exposed to the client, so this is merely a hint that
+ // a client should be told that AML staff is currently
+ // reviewing the account. AML staff *may* review
+ // accounts without this flag being set!
+ aml_review: boolean;
+
+ // Access token needed to construct the ``/kyc-spa/``
+ // URL that the user should open in a browser to
+ // proceed with the KYC process (optional if the status
+ // type is ``200 Ok``, mandatory if the HTTP status
+ // is ``202 Accepted``).
+ access_token: AccountAccessToken;
+
+ // Array with limitations that currently apply to this
+ // account and that may be increased or lifted if the
+ // KYC check is passed.
+ // Note that additional limits *may* exist and not be
+ // communicated to the client. If such limits are
+ // reached, this *may* be indicated by the account
+ // going into ``aml_review`` state. However, it is
+ // also possible that the exchange may legally have
+ // to deny operations without being allowed to provide
+ // any justification.
+ // The limits should be used by the client to
+ // possibly structure their operations (e.g. withdraw
+ // what is possible below the limit, ask the user to
+ // pass KYC checks or withdraw the rest after the time
+ // limit is passed, warn the user to not withdraw too
+ // much or even prevent the user from generating a
+ // request that would cause it to exceed hard limits).
+ limits?: AccountLimit[];
+
+ }
+
+ .. ts:def:: AccountLimit
+
+ interface AccountLimit {
+
+ // Operation that is limited.
+ // Must be one of "WITHDRAW", "DEPOSIT", "P2P-RECEIVE"
+ // or "WALLET-BALANCE".
+ operation_type: string;
+
+ // Timeframe during which the limit applies.
+ timeframe: RelativeTime;
+
+ // Maximum amount allowed during the given timeframe.
+ // Zero if the operation is simply forbidden.
+ threshold: Amount;
- // Current time of the exchange, used as part of
- // what the exchange signs over.
- now: Timestamp;
+ // True if this is a soft limit that could be raised
+ // by passing KYC checks. Clients *may* deliberately
+ // try to cross limits and trigger measures resulting
+ // in 451 responses to begin KYC processes.
+ // Clients that are aware of hard limits *should*
+ // inform users about the hard limit and prevent flows
+ // in the UI that would cause violations of hard limits.
+ soft_limit: boolean;
+ }
+
+.. http:get:: /kyc-spa/$ACCESS_TOKEN
+.. http:get:: /kyc-spa/$FILENAME
+
+ A set of ``/kyc-spa/$ACCESS_TOKEN`` GET endpoints is created per account
+ hash that serves the KYC SPA. This is where the ``/kyc-check/`` endpoint
+ will in principle redirect clients. The KYC SPA will use the
+ ``$ACCESS_TOKEN`` of its URL to initialize itself via the
+ ``/kyc-info/$ACCESS_TOKEN`` endpoint family. The KYC SPA may download
+ additional resources via ``/kyc-spa/$FILENAME``. The filenames must not
+ match base32-encoded 256-bit values.
+
+ This endpoint was introduced in protocol **v20**.
+
+
+.. http:get:: /kyc-info/$ACCESS_TOKEN
+
+ The ``/kyc-info/$ACCESS_TOKEN`` endpoints are created per client
+ account hash (but access controlled via a unique target token)
+ to return information about the state of the KYC or AML process
+ to the KYC SPA. The SPA uses this information to show the user an
+ appropriate dialog. The SPA should also long-poll this endpoint for changes
+ to the AML/KYC state. Note that this is a client-facing endpoint, so it will
+ only provide a restricted amount of information to the customer (as some
+ laws may forbid us to inform particular customers about their true status).
+ The endpoint will typically inform the SPA about possible choices to
+ proceed, such as directly uploading files, contacting AML staff, or
+ proceeding with a particular KYC process at an external provider (such as
+ Challenger). If the user chooses to initate a KYC process at an external
+ provider, the SPA must request the respective process to be set-up by the
+ exchange via the ``/kyc-start/`` endpoint.
+
+ This endpoint was introduced in protocol **v20**.
- // EdDSA signature of the exchange affirming the account
- // is KYC'ed, must be of purpose
- // ``TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS``
- // and over ``TALER_AccountSetupStatusSignaturePS``.
- exchange_sig: EddsaSignature;
+ **Request:**
- // public key used to create the signature.
- exchange_pub: EddsaPublicKey;
+ *If-None-Match*:
+ The client MAY provide an ``If-None-Match`` header with an ETag.
- // Current AML state for the target account. Non-zero
- // values indicate that the transfer is blocked due to
- // AML enforcement.
- aml_status: Integer;
+ :query timeout_ms=MILLISECONDS:
+ *Optional.* If specified, the exchange will wait up to MILLISECONDS for
+ a change to a more recent legitimization measure before returning a 304
+ Not Modified status.
+ **Response:**
+
+ *Etag*: Will be set to the serial ID of the measure. Used for long-polling (only for 200 OK responses).
+
+ :http:statuscode:`200 OK`:
+ The body is a `KycProcessClientInformation`.
+ :http:statuscode:`204 No Content`:
+ There are no open KYC requirements or possible voluntary checks
+ the client might perform.
+ :http:statuscode:`304 Not Modified`:
+ The KYC requirements did not change.
+
+
+ **Details:**
+
+ .. ts:def:: KycProcessClientInformation
+
+ interface KycProcessClientInformation {
+
+ // List of requirements.
+ requirements?: { name : KycRequirementInformation};
+
+ // True if the client is expected to eventually satisfy all requirements.
+ // Default (if missing) is false.
+ is_and_combinator?: boolean
+
+ // List of available voluntary checks the client could pay for.
+ // Since **vATTEST**.
+ voluntary_checks?: { name : KycCheckInformation};
}
- .. ts:def:: AccountKycRedirect
+ .. ts:def:: KycRequirementInformation
- interface AccountKycRedirect {
+ interface KycRequirementInformation {
- // URL that the user should open in a browser to
- // proceed with the KYC process.
- kyc_url: string;
+ // Which form should be used? Common values include "INFO"
+ // (to just show the descriptions but allow no action),
+ // "LINK" (to enable the user to obtain a link via
+ // ``/kyc-start/``) or any build-in form name supported
+ // by the SPA.
+ form: string;
- // Current AML state for the target account. Non-zero
- // values indicate that the transfer is blocked due to
- // AML enforcement.
- aml_status: Integer;
+ // English description of the requirement.
+ description: string;
+
+ // Map from IETF BCP 47 language tags to localized
+ // description texts.
+ description_i18n ?: { [lang_tag: string]: string };
+
+ // ID of the requirement, useful to construct the
+ // ``/kyc-upload/$ID`` or ``/kyc-start/$ID`` endpoint URLs.
+ // Present if and only if "form" is not "INFO". The
+ // ``$ID`` value may itself contain ``/`` or ``?`` and
+ // basically encode any URL path (and optional arguments).
+ id?: string;
}
- .. ts:def:: AccountAmlBlocked
+ .. ts:def:: KycCheckInformation
- interface AccountAmlBlocked {
+ // Since **vATTEST**.
+ interface KycCheckInformation {
- // Current AML state for the target account. Non-zero
- // values indicate that the transfer is blocked due to
- // AML enforcement.
- aml_status: Integer;
+ // English description of the check.
+ description: string;
+
+ // Map from IETF BCP 47 language tags to localized
+ // description texts.
+ description_i18n ?: { [lang_tag: string]: string };
+ // FIXME: is the above in any way sufficient
+ // to begin the check? Do we not need at least
+ // something more??!?
}
- .. ts:def:: KycDetails
- // Object that specifies which KYC checks are satisfied.
- interface KycDetails {
+.. http:post:: /kyc-upload/$ID
+
+ The ``/kyc-upload/$ID`` POST endpoint allows the SPA to upload
+ client-provided evidence. The ``$ID`` will be provided as part of the
+ ``/kyc-info`` body. This is for checks of type ``FORM``. In practice,
+ ``$ID`` will encode both the ``$ACCESS_TOKEN`` and the index of the selected
+ measure (but this should be irrelevant for the client).
+
+ This endpoint was introduced in protocol **v20**.
- // Keys are the names of the check(s).
- // The values are for now always empty objects.
+ **Request:**
+
+ Basically oriented along the possible formats of a HTTP form being
+ POSTed. Details will depend on the form. The server will try to decode the
+ uploaded body from whatever format it is provided in.
+
+ **Response:**
+
+ :http:statuscode:`204 No Content`:
+ The information was successfully uploaded. The SPA should fetch
+ an updated ``/kyc-info/``.
+ :http:statuscode:`404 Not Found`:
+ The ``$ID`` is unknown to the exchange.
+ :http:statuscode:`409 Conflict`:
+ The upload conflicts with a previous upload.
+ :http:statuscode:`413 Request Entity Too Large`:
+ The body is too large.
+
+.. http:post:: /kyc-start/$ID
+
+ The ``/kyc-start/$ID`` POST endpoint allows the SPA to set up a new external
+ KYC process. It will return the URL that the client must GET to begin the
+ KYC process. The SPA should probably open this URL in a new window or tab.
+ The ``$ID`` will be provided as part of the ``/kyc-info`` body. In
+ practice, ``$ID`` will encode both the ``$ACCESS_TOKEN`` and the index of
+ the selected measure (but this should be irrelevant for the client).
+
+ **Request:**
+
+ Use empty JSON body for now.
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ The KYC process was successfully initiated. The URL is in a
+ `KycProcessStartInformation` object.
+ :http:statuscode:`404 Not Found`:
+ The ``$ID`` is unknown to the exchange.
+
+ **Details:**
+
+ .. ts:def:: KycProcessStartInformation
+
+ interface KycProcessStartInformation {
+
+ // URL to open.
+ redirect_url: string;
}
-.. http:get:: /kyc-proof/$PROVIDER_SECTION?state=$H_PAYTO
+ .. note::
+
+ As this endpoint is involved in every KYC check at the beginning, this
+ is also the place where we could integrate the payment process for the KYC fee
+ in the future (since **vATTEST**).
+
+.. http:get:: /kyc-proof/$PROVIDER_NAME?state=$H_PAYTO
+
+ Upon completion of the process at the external KYC provider, the provider
+ must redirect the client (browser) to trigger a GET request to a new
+ ``/kyc-proof/$H_PAYTO/$PROVIDER_NAME`` endpoint. Once this endpoint is
+ triggered, the exchange will pass the received arguments to the respective
+ logic plugin. The logic plugin will then (asynchronously) update the KYC
+ status of the user. The logic plugin should redirect the user to the KYC
+ SPA. This endpoint deliberately does not use the ``$ACCESS_TOKEN`` as the
+ external KYC provider should not learn that token.
- Endpoint accessed from the user's browser at the *end* of a
+ This endpoint is thus accessed from the user's browser at the *end* of a
KYC process, possibly providing the exchange with additional
credentials to obtain the results of the KYC process.
Specifically, the URL arguments should provide
information to the exchange that allows it to verify that the
user has completed the KYC process. The details depend on
- the logic, which is selected by the "$PROVIDER_SECTION".
+ the logic, which is selected by the "$PROVIDER_NAME".
While this is a GET (and thus safe, and idempotent), the operation
may actually trigger significant changes in the exchange's state.
@@ -5071,8 +5540,10 @@ regulatory compliance.
If the KYC plugin logic is OAuth 2.0, the query parameters are:
- :query code=CODE: OAuth 2.0 code argument.
- :query state=STATE: OAuth 2.0 state argument with the H_PAYTO.
+ :query code=CODE:
+ OAuth 2.0 code argument.
+ :query state=STATE:
+ OAuth 2.0 state argument with the H_PAYTO.
.. note::
@@ -5102,8 +5573,8 @@ regulatory compliance.
service within a reasonable time period.
-.. http:get:: /kyc-webhook/$PROVIDER_SECTION/*
-.. http:post:: /kyc-webhook/$PROVIDER_SECTION/*
+.. http:get:: /kyc-webhook/$PROVIDER_NAME/*
+.. http:post:: /kyc-webhook/$PROVIDER_NAME/*
.. http:get:: /kyc-webhook/$LOGIC/*
.. http:post:: /kyc-webhook/$LOGIC/*
@@ -5111,7 +5582,7 @@ regulatory compliance.
payment target. They provide information to the KYC logic of the exchange
that allows it to verify that the user has completed the KYC process. May
be a GET or a POST request, depending on the specific "$LOGIC" and/or the
- "$PROVIDER_SECTION".
+ "$PROVIDER_NAME".
**Request:**
@@ -5176,7 +5647,7 @@ designated account.
:http:statuscode:`451 Unavailable For Legal Reasons`:
This account has not yet passed the KYC checks.
The client must pass KYC checks before the reserve can be opened.
- The response will be an `KycNeededRedirect` object.
+ The response will be an `LegitimizationNeededResponse` object.
**Details:**
@@ -5392,7 +5863,7 @@ designated account.
This account has not yet passed the KYC checks, hence wiring
funds to a non-origin account is not allowed.
The client must pass KYC checks before the reserve can be opened.
- The response will be an `KycNeededRedirect` object.
+ The response will be an `LegitimizationNeededResponse` object.
**Details:**
diff --git a/core/api-merchant.rst b/core/api-merchant.rst
index 4d74d4b2..0e45cbad 100644
--- a/core/api-merchant.rst
+++ b/core/api-merchant.rst
@@ -123,7 +123,7 @@ such as the implemented version of the protocol and the currency used.
.. http:get:: /config
Return the protocol version and currency supported by this merchant backend.
- This specification corresponds to ``current`` protocol being version **v14**.
+ This specification corresponds to ``current`` protocol being version **v15**.
**Response:**
@@ -342,6 +342,11 @@ Making the payment
// payment.
pos_confirmation?: string;
+ // Signed tokens. Returned in the same order as the
+ // token envelopes were provided in the request.
+ // @since protocol **vSUBSCRIBE**
+ token_sigs?: SignedTokenEnvelope[];
+
}
.. ts:def:: PayRequest
@@ -350,22 +355,17 @@ Making the payment
// The coins used to make the payment.
coins: CoinPaySig[];
- // Index of the selected choice within the ``choices`` array of
- // the contract terms.
- // @since protocol **vSUBSCRIBE**
- choice_index?: Integer;
-
// Input tokens required by choice indicated by ``choice_index``.
// @since protocol **vSUBSCRIBE**
- tokens: TokenUseSig[];
+ tokens?: TokenUseSig[];
// Array of output tokens to be (blindly) signed by the merchant.
// Output tokens specified in choice indicated by ``choice_index``.
// @since protocol **vSUBSCRIBE**
- tokens_evs: TokenEnvelope[];
+ tokens_evs?: TokenEnvelope[];
// Custom inputs from the wallet for the contract.
- wallet_data?: Object;
+ wallet_data?: PayWalletData;
// The session for which the payment is made (or replayed).
// Only set for session-based payments.
@@ -373,6 +373,59 @@ Making the payment
}
+ .. ts:def:: SignedTokenEnvelope
+
+ interface SignedTokenEnvelope {
+
+ // Blind signature made by the merchant.
+ blind_sig: TokenIssueBlindSig;
+
+ // Hash of the token issue public key.
+ h_issue: HashCode;
+
+ }
+
+ .. ts:def:: TokenIssueBlindSig
+
+ type TokenIssueBlindSig = RSATokenIssueBlindSig | CSTokenIssueBlindSig;
+
+ .. ts:def:: RSATokenIssueBlindSig
+
+ interface RSATokenIssueBlindSig {
+ cipher: "RSA";
+
+ // (blinded) RSA signature
+ blinded_rsa_signature: BlindedRsaSignature;
+ }
+
+ .. ts:def:: CSTokenIssueBlindSig
+
+ interface CSTokenIssueBlindSig {
+ type: "CS";
+
+ // Signer chosen bit value, 0 or 1, used
+ // in Clause Blind Schnorr to make the
+ // ROS problem harder.
+ b: Integer;
+
+ // Blinded scalar calculated from c_b.
+ s: Cs25519Scalar;
+
+ }
+
+ .. ts:def:: PayWalletData
+
+ interface PayWalletData {
+ // Index of the selected choice within the ``choices`` array of
+ // the contract terms.
+ // @since protocol **vSUBSCRIBE**
+ choice_index?: Integer;
+
+ // Output commitment. Hash over output token envelopes.
+ // @since protocol **vSUBSCRIBE**
+ h_outputs?: HashCode;
+ }
+
.. ts:def:: CoinPaySig
export interface CoinPaySig {
@@ -418,27 +471,41 @@ Making the payment
interface TokenUseSig {
- // Signature on ``TALER_DepositRequestPS`` with the public key of the
- // token being provisioned to the merchant.
+ // Signature on ``TALER_TokenUseRequestPS`` with the token use key of
+ // the token being used in this request.
token_sig: EddsaSignature;
- // Public key of the token being provisioned to the merchant.
+ // Token use public key.
token_pub: EddsaPublicKey;
- // Unblinded signature made by the token family public key of the merchant.
+ // Unblinded signature on ``TALER_TokenIssueRequestPS`` with the token
+ // issue public key of the merchant.
ub_sig: UnblindedSignature;
- // The hash of the token family public key associated with this token.
- h_denom: HashCode;
+ // The hash of the token issue public key of the token being using
+ // in this request.
+ h_issue: HashCode;
}
.. ts:def:: TokenEnvelope
+ interface TokenEnvelope {
+
+ // Blinded token use public key.
+ token_ev: BlindedTokenEnvelope;
+
+ // Hash of the token issue public key.
+ h_issue: HashCode;
+
+ }
+
+ .. ts:def:: BlindedTokenEnvelope
+
// This type depends on the cipher used to sign token families. This is
// configured by the merchant and defined for each token family in the
// contract terms.
- type TokenEnvelope = RSATokenEnvelope | CSTokenEnvelope;
+ type BlindedTokenEnvelope = RSATokenEnvelope | CSTokenEnvelope;
.. ts:def:: RSATokenEnvelope
@@ -1851,6 +1918,7 @@ Inspecting inventory
image: ImageDataUrl;
// A list of taxes paid by the merchant for one unit of this product.
+ // Optional since **v15**.
taxes: Tax[];
// Number of units of the product in stock in sum in total,
@@ -1866,7 +1934,8 @@ Inspecting inventory
total_lost: Integer;
// Identifies where the product is in stock.
- address: Location;
+ // Optional since **v15**.
+ address?: Location;
// Identifies when we expect the next restocking to happen.
next_restock?: Timestamp;
@@ -1876,6 +1945,93 @@ Inspecting inventory
}
+.. http:get:: [/instances/$INSTANCE]/private/pos
+
+ This is used to return the point-of-sale (POS) configuration with full details on all items in the inventory.
+
+ Endpoint was introduced in protocol **v15**.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The backend has successfully returned the inventory. Returns
+ a `FullInventoryDetailsResponse`.
+ :http:statuscode:`404 Not found`:
+ The backend has does not know about the instance.
+
+ .. ts:def:: FullInventoryDetailsResponse
+
+ interface FullInventoryDetailsResponse {
+
+ // List of products that are present in the inventory.
+ products: MerchantPosProductDetail[];
+
+ // List of categories in the inventory.
+ categories: MerchantCategory[];
+
+ }
+
+ .. ts:def:: MerchantPosProductDetail
+
+ interface MerchantPosProductDetail {
+
+ // A unique numeric ID of the product
+ product_serial: number;
+
+ // A merchant-internal unique identifier for the product
+ product_id?: string;
+
+ // A list of category IDs this product belongs to.
+ // Typically, a product only belongs to one category, but more than one is supported.
+ categories: number[];
+
+ // Human-readable product description.
+ description: string;
+
+ // Map from IETF BCP 47 language tags to localized descriptions.
+ description_i18n: { [lang_tag: string]: string };
+
+ // Unit in which the product is measured (liters, kilograms, packages, etc.).
+ unit: string;
+
+ // The price for one ``unit`` of the product. Zero is used
+ // to imply that this product is not sold separately, or
+ // that the price is not fixed, and must be supplied by the
+ // front-end. If non-zero, this price MUST include applicable
+ // taxes.
+ price: Amount;
+
+ // An optional base64-encoded product image.
+ image?: ImageDataUrl;
+
+ // A list of taxes paid by the merchant for one unit of this product.
+ taxes?: Tax[];
+
+ // Number of units of the product in stock in sum in total,
+ // including all existing sales ever. Given in product-specific
+ // units.
+ // Optional, if missing treat as "infinite".
+ total_stock?: Integer;
+
+ // Minimum age buyer must have (in years).
+ minimum_age?: Integer;
+
+ }
+
+ .. ts:def:: MerchantCategory
+
+ interface MerchantCategory {
+ // A unique numeric ID of the category
+ id: number;
+
+ // The name of the category. This will be shown to users and used in the order summary.
+ name: string;
+
+ // Map from IETF BCP 47 language tags to localized names
+ name_i18n?: { [lang_tag: string]: string };
+ }
+
+
Reserving inventory
-------------------
@@ -2200,7 +2356,8 @@ protocol **vSUBSCRIBE**.
token_family_slug: string;
// Start of the validity period of the token. Based on this, the merchant
- // will select the relevant signing key.
+ // will select the relevant signing key. This value is rounded down
+ // according to the configured rounding duration in the token family.
valid_after: Timestamp;
// How many units of the input are required.
@@ -2226,7 +2383,8 @@ protocol **vSUBSCRIBE**.
token_family_slug: string;
// Start of the validity period of the token. Based on this, the merchant
- // will select the relevant signing key.
+ // will select the relevant signing key. This value is rounded down
+ // according to the configured rounding duration in the token family.
valid_after: Timestamp;
// How many units of the output are issued by the merchant.
diff --git a/core/api-terminal.rst b/core/api-terminal.rst
new file mode 100644
index 00000000..91d9b7e6
--- /dev/null
+++ b/core/api-terminal.rst
@@ -0,0 +1,356 @@
+..
+ This file is part of GNU TALER.
+
+ Copyright (C) 2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+.. target audience: developer, core developer
+
+.. _terminal-api:
+
+============
+Terminal API
+============
+
+.. contents:: Table of Contents
+ :local:
+
+Introduction
+------------
+
+Terminals are devices where users can withdraw digital cash.
+
+This API is offered by a payment service backend and is used by such
+terminals. It enables imposing limits on withdrawals per unique user ID (and
+communicating such limits to the terminals) as well as setting up and
+triggering withdrawal operations.
+
+Implementations of this API typically interact with a terminal-specific
+payment service (or a bank) to realize the service.
+
+
+Authentication
+--------------
+
+Terminals must authenticate against all terminal API using basic auth according to `HTTP basic auth <https://tools.ietf.org/html/rfc7617>`_.
+
+
+Config
+------
+
+.. http:get:: /config
+
+ Return the protocol version and configuration information about the bank.
+ This specification corresponds to ``current`` protocol being version **0**.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ Response is a `TerminalConfig`.
+
+ **Details:**
+
+ .. ts:def:: TerminalConfig
+
+ interface TerminalConfig {
+ // Name of the API.
+ name: "taler-terminal";
+
+ // libtool-style representation of the Bank protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Terminal provider display name to be used in user interfaces.
+ provider_name: string;
+
+ // The currency supported by this Terminal-API
+ // must be the same as the currency specified
+ // in the currency field of the wire gateway config
+ currency: string;
+
+ // Wire transfer type supported by the terminal.
+ // FIXME: needed?
+ wire_type: string;
+ }
+
+
+.. http:get:: /quotas/$UUID
+
+ Obtain the current transaction limit for the given $UUID.
+ The UUID should be an encoding of a unique identifier of
+ the user.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ Response is a `WithdrawLimit`.
+
+ **Details:**
+
+ .. ts:def:: WithdrawLimit
+
+ interface WithdrawLimit {
+ // Maximum amount that can be withdrawn now.
+ limit: Amount;
+
+ // Time when the limit may increase.
+ expiration: Timestamp;
+ }
+
+
+.. http:post:: /quotas/$UUID/lock
+
+ This endpoint allows a terminal to reserve a given amount
+ from the user's quota, ensuring that a subsequent operation
+ will not fail due to a quota violation.
+
+ **Request:**
+
+ The request should be a `WithdrawLimitLock`.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The change was accepted.
+ :http:statuscode:`409 Conflict`:
+ The proposed lock would push the user above the limit.
+
+ **Details:**
+
+ .. ts:def:: WithdrawLimitLock
+
+ interface WithdrawLimitLock {
+
+ // Amount that should be reserved from the quota.
+ limit: Amount;
+
+ // ID for the lock. FIXME: could also be 32-byte nonce?
+ lock: string;
+
+ // How long should the lock be held?
+ expiration: Timestamp;
+ }
+
+.. http:delete:: /quotas/$UUID/lock/$LOCK
+
+ This endpoint allows the terminal to clear a lock it may have
+ previously created.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The lock was cleared.
+ :http:statuscode:`404 Not found`:
+ The lock is unknown.
+ :http:statuscode:`409 Conflict`:
+ The lock was already used in a withdrawal operation.
+
+
+.. http:post:: /withdrawals
+
+ This endpoint allows the terminal to set up a new withdrawal
+ operation.
+
+ **Request:**
+
+ The request should be a `TerminalWithdrawalSetup`.
+
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ The operation was created. The response will be
+ a `TerminalWithdrawalSetupResponse`.
+ :http:statuscode:`404 Not found`:
+ A lock was specified but the lock is not known for
+ the given user.
+ :http:statuscode:`409 Conflict`:
+ A conflicting withdrawal operation already exists or
+ the amount would violate the quota for the specified user.
+
+ **Details:**
+
+ .. ts:def:: TerminalWithdrawalSetup
+
+ interface TerminalWithdrawalSetup {
+
+ // Amount to withdraw. If given, the wallet
+ // cannot change the amount!
+ amount?: Amount;
+
+ // Suggested amount to withdraw. If given, the wallet can
+ // still change the suggestion.
+ suggested_amount?: Amount;
+
+ // A provider-specific transaction identifier.
+ // This identifier may be used to attest the
+ // payment at the provider's backend. Optional,
+ // as we may not know it at this time.
+ provider_transaction_id?: string;
+
+ // The non-Taler fees the customer will have
+ // to pay to the service provider
+ // they are using to make this withdrawal.
+ // If the fees cannot be precalculated,
+ // they can be specified in the /withdrawals/$WITHDRAWAL_ID/check
+ // request after the transaction was executed.
+ terminal_fees?: Amount;
+
+ // Unique request ID to make retried requests idempotent.
+ request_uid: string;
+
+ // Unique user ID of the user. Optional
+ // in case a user Id is not (yet) known.
+ user_uuid?: string;
+
+ // ID identifying a lock on the quota that the client
+ // may wish to use in this operation. May only be
+ // present if ``user_uuid`` is also given.
+ lock?: string;
+ }
+
+ .. ts:def:: TerminalWithdrawalSetupResponse
+
+ interface TerminalWithdrawalSetupResponse {
+
+ // ID identifying the withdrawal operation being created.
+ withdrawal_id: string;
+ }
+
+
+.. http:post:: /withdrawals/$WITHDRAWAL_ID/check
+
+ Endpoint for providers to notify the terminal backend about a payment having
+ happened. This will cause the bank to validate the transaction and allow
+ the withdrawal to proceed. The API is idempotent, meaning sending a payment
+ notification for the same ``WITHDRAWAL_ID`` return successfuly but not
+ change anything. This endpoint is always *optional*: the bank, exchange and
+ wallet should all eventually notice the wire transfer with or without this
+ endpoint being called. However, by calling this endpoint checks that might
+ otherwise only happen periodically can be triggered immediately.
+
+ The endpoint may also be used to associate a user ID at a very late stage
+ with the withdrawal --- and still get an immediate failure if we are above
+ the quota.
+
+ .. note::
+
+ The backend shall **never** just accept this claim that the payment was
+ confirmed, but instead needs to internally attest that the payment was
+ successful using provider-specific transaction validation logic! The point
+ of this endpoint is merely to trigger this validation **now**.
+
+ **Request:**
+
+ The body of the request must be a `TerminalWithdrawalConfirmationRequest`.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The payment notification was processed successfully.
+ :http:statuscode:`404 Not found`:
+ The withdrawal operation was not found.
+ :http:statuscode:`409 Conflict`:
+ The withdrawal operation has been previously aborted
+ and cannot be confirmed anymore.
+ :http:statuscode:`451 Unavailable for Legal Reasons`:
+ The withdrawal operation cannot be confirmed because
+ it would put the user above the legal limit. The
+ payment service will eventually bounce the transfer
+ (if it were to become effective), but the user should
+ already be shown an error.
+
+ **Details:**
+
+ .. ts:def:: TerminalWithdrawalConfirmationRequest
+
+ interface TerminalWithdrawalConfirmationRequest {
+
+ // A provider-specific transaction identifier.
+ // This identifier may be used to facilitate the
+ // backend to check that the credit was confirmed.
+ provider_transaction_id?: string;
+
+ // The fees which the customer had to pay to the
+ // provider
+ terminal_fees?: Amount;
+
+ // A user-specific identifier for quota checks.
+ user_uuid?: string;
+
+ // ID identifying a lock on the quota that the client
+ // may wish to use in this operation. May only be
+ // present if ``user_uuid`` is also given.
+ lock?: string;
+ }
+
+.. http:get:: /withdrawals/$WITHDRAWAL_ID
+
+ Query information about a withdrawal, identified by the ``WITHDRAWAL_ID``.
+
+ **Request:**
+
+ :query long_poll_ms:
+ *Optional.* If specified, the bank will wait up to ``long_poll_ms``
+ milliseconds for operationt state to be different from ``old_state`` before sending the HTTP
+ response. A client must never rely on this behavior, as the bank may
+ return a response immediately.
+ :query old_state:
+ *Optional.* Default to "pending".
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The withdrawal operation is known to the bank, and details are given
+ in the `BankWithdrawalOperationStatus` response body.
+ :http:statuscode:`404 Not found`:
+ The operation was not found.
+
+.. http:delete:: /withdrawals/$WITHDRAWAL_ID/abort
+
+ Aborts ``WITHDRAWAL_ID`` operation. Has no effect on an already aborted
+ operation. This endpoint can be used by the terminal if the terminal aborts
+ the transaction, ensuring that the operation is also aborted at the
+ bank.
+
+ **Request:**
+
+ The request body is empty.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The withdrawal operation has been aborted.
+ :http:statuscode:`404 Not found`:
+ The withdrawal operation was not found.
+ :http:statuscode:`409 Conflict`:
+ The withdrawal operation has been confirmed previously and
+ can't be aborted.
+
+
+Endpoints for Integrated Sub-APIs
+---------------------------------
+
+.. http:any:: /taler-integration/*
+
+ All endpoints under this prefix are specified by the.
+ :doc:`GNU Taler bank integration API </core/api-bank-integration>`.
+ This API handles the communication with Taler wallets.
+
+
+.. http:any:: /taler-wire-gateway/*
+
+ All endpoints under this prefix are specified
+ by the :doc:`GNU Taler wire gateway API </core/api-bank-wire>`.
+
+ The endpoints are only available for accounts configured with ``is_taler_exchange=true``.
diff --git a/core/index-bank-apis.rst b/core/index-bank-apis.rst
index f108df32..1097126a 100644
--- a/core/index-bank-apis.rst
+++ b/core/index-bank-apis.rst
@@ -33,6 +33,7 @@ Bank RESTful APIs
api-bank-revenue
api-bank-integration
api-bank-conversion-info
+ api-terminal
.. toctree::
:hidden: