summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api-bank.rst178
-rw-r--r--api-common.rst11
-rw-r--r--api-exchange.rst141
-rw-r--r--api-merchant.rst81
-rw-r--r--conf.py4
-rw-r--r--exts/__pycache__/tsref.cpython-35.pycbin7463 -> 7453 bytes
-rw-r--r--index.rst2
7 files changed, 259 insertions, 158 deletions
diff --git a/api-bank.rst b/api-bank.rst
index 401847f8..3d61bb47 100644
--- a/api-bank.rst
+++ b/api-bank.rst
@@ -1,31 +1,27 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014, 2015, 2016 INRIA
+
+ Copyright (C) 2014, 2015, 2016, 2017 Taler Systems SA
+
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU 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 Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public License along with
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
@author Marcello Stanisci
+ @author Christian Grothoff
=========
Bank API
=========
-The following APIs are served from banks, in order to allow exchanges to
-deposit funds to money recipients. A typical scenario for calling this
-APIs is after a merchant has deposited coins to the exchange, and the exchange
-needs to give real money to the merchant.
-
-------------------
-Administrative API
-------------------
-
-This API allows one user to send money to another user, withing the same "test"
+This API allows one user to send money to another user, within the same "test"
bank. The user calling it has to authenticate by including his credentials in the
request.
@@ -45,13 +41,13 @@ request.
.. code-block:: tsref
interface BankDepositDetails {
-
+
// Timestamp related to the transaction being made.
timestamp: Timestamp;
- // Serial id identifying the transaction into the bank's
+ // Row id number identifying the transaction in the bank's
// database.
- serial_id: number;
+ row_id: number;
}
.. _BankDepositRequest:
@@ -77,10 +73,8 @@ request.
// the wire transfer subject of their respective banking system.
exchange_url: string;
- // The id of this wire transfer, a `TALER_WireTransferIdentifierRawP`.
- // Should be encoded together with a checksum in actual wire transfers.
- // (See `TALER_WireTransferIdentifierP`_ for an encoding with CRC8.).
- wtid: base32;
+ // The subject of this wire transfer.
+ subject: string;
// The sender's account identificator. NOTE, in the current stage
// of development this field is _ignored_, as it's always the bank account
@@ -104,7 +98,7 @@ request.
// only value "basic" is accepted in this field.
// The credentials must be indicated in the following HTTP
// headers: "X-Taler-Bank-Username" and "X-Taler-Bank-Password".
- type: string;
+ type: string;
}
@@ -116,11 +110,49 @@ request.
// Human readable explanation of the failure.
error: string;
+ // Numeric Taler error code (`enum TALER_ErrorCode`)
+ ec: number;
+
}
---------
-User API
---------
+
+.. http:put:: /reject
+
+ Rejects an inbound transaction. This can be used by the receiver of a wire transfer to
+ cancel that transaction, nullifying its effect. This basically creates a correcting
+ entry that voids the original transaction. Henceforth, the /history must show
+ the original transaction as "cancelled+" or "cancelled-" for creditor and debitor respectively.
+ This API is used when the exchange receives a wire transfer with an invalid wire
+ transfer subject that fails to decode to a public key.
+
+ **Request** The body of this request must have the format of a `BankCancelRequest`_.
+
+ :query auth: authentication method used. At this stage of development, only value `basic` is accepted. Note that username and password need to be given as request's headers. The dedicated headers are: `X-Taler-Bank-Username` and `X-Taler-Bank-Password`.
+ :query row_id: row identifier of the transaction that should be cancelled.
+ :query account_number: bank account for which the incoming transfer was made and for which `auth` provides the authentication data. *Currently ignored*, as multiple bank accounts per user are not implemented yet.
+
+ .. _BankCancelRequest:
+ .. code-block:: tsref
+
+ interface BankCancelRequest {
+
+ // Authentication method used
+ auth: BankAuth;
+
+ // The row id of the wire transfer to cancel
+ row_id: number;
+
+ // The recipient's account identificator
+ credit_account: number;
+
+ }
+
+ **Response** In case of an error, the body is a `BankError`_ object.
+
+ :status 204 No Content: The request has been correctly handled, so the original transaction was voided. The body is empty.
+ :status 400 Bad Request: The bank replies a `BankError`_ object.
+ :status 404 Not Found: The bank does not know this rowid for this account.
+
.. http:get:: /history
@@ -131,10 +163,12 @@ User API
:query auth: authentication method used. At this stage of development, only value `basic` is accepted. Note that username and password need to be given as request's headers. The dedicated headers are: `X-Taler-Bank-Username` and `X-Taler-Bank-Password`.
:query delta: returns the first `N` records younger (older) than `start` if `+N` (`-N`) is specified.
:query start: according to `delta`, only those records with row id strictly greater (lesser) than `start` will be returned. This argument is optional; if not given, `delta` youngest records will be returned.
- :query direction: optional argument taking values `debit` or `credit`, according to the caller willing to receive both incoming and outgoing, only outgoing, or only incoming records.
- :query account_number: optional argument indicating the bank account number whose history is to be returned. If not given, then the history of the calling user will be returned.
+ :query direction: argument taking values `debit` or `credit`, according to the caller willing to receive both incoming and outgoing, only outgoing, or only incoming records. Use `both` to return both directions.
+ :query cancelled: argument taking values `omit` or `show` to filter out rejected transactions
+ :query account_number: bank account whose history is to be returned. *Currently ignored*, as multiple bank accounts per user are not implemented yet.
+
- **Response**
+ **Response**
:status 200 OK: JSON object whose field `data` is an array of type `BankTransaction`_.
:status 204 No content: in case no records exist for the targeted user.
@@ -143,7 +177,7 @@ User API
.. code-block:: tsref
interface BankTransaction {
-
+
// identification number of the record
row_id: number;
@@ -154,17 +188,17 @@ User API
amount: Amount;
// "-" if the transfer was outgoing, "+" if it was
- // incoming. This field is only present if the
- // argument `direction` was NOT given.
+ // incoming; "cancel+" or "cancel-" if the transfer
+ // was /reject-ed by the receiver.
sign: string;
// Bank account number of the other party involved in the
// transaction.
- counterpart: number;
+ counterpart: number;
// Wire transfer subject line.
wt_subject: string;
-
+
}
..
@@ -172,3 +206,83 @@ User API
the client using the bank. A reasonable improvement is to
specify a bank URI too, so that Taler can run across multiple
banks.
+
+------------------------
+Interactions with wallet
+------------------------
+
+A bank and a wallet need to communicate for (1) make some elements visible
+only if the wallet is installed, (2) exchange information when the user withdraws
+coins.
+
+Make elements visible.
+^^^^^^^^^^^^^^^^^^^^^^
+
+This feature works via CSS injection from the wallet. To enable it, the
+page must contain the ``<html data-taler-nojs="true">`` element, so that
+the wallet will do the injection.
+
+Whenever a element ``<x>`` needs to be visualized (hidden) if the wallet is
+installed, the special class ``taler-installed-show`` (``taler-installed-hide``)
+must be added to ``x``, as follows:
+
+* ``<x class="taler-installed-show">y</x>`` will make ``y`` visible.
+* ``<x class="taler-installed-hide">y</x>`` will make ``y`` visible.
+
+Clearly, a fallback page must be provided, which will be useful if the
+wallet is *not* installed. This special page will hide any element of
+the class ``taler-install-show``; it can be downloaded at the following
+URI: ``git://taler.net/web-common/taler-fallback.css``.
+
+Withdrawing coins.
+^^^^^^^^^^^^^^^^^^
+
+After the user confirms the withdrawal, the bank must return a `202 Accepted` response,
+along with the following HTTP headers:
+
+* ``X-Taler-Operation: create-reserve``
+* ``X-Taler-Callback-Url: <callback_url>``; this URL will be automatically visited by the wallet after the user confirms the exchange.
+* ``X-Taler-Wt-Types: '["test"]'``; stringified JSON list of supported wire transfer types (only 'test' supported so far).
+* ``X-Taler-Amount: <amount_string>``; stringified Taler-style JSON :ref:`amount <amount>`.
+* ``X-Taler-Sender-Wire: <wire_details>``; stringified WireDetails_.
+* ``X-Taler-Suggested-Exchange: <URL>``; this header is optional, and ``<URL>`` is the suggested exchange URL as given in the `SUGGESTED_EXCHANGE` configuration option.
+
+.. _WireDetails:
+.. code-block:: tsref
+
+ interface WireDetails {
+ type: string; // Only 'test' value admitted so far.
+ bank_uri: URI of the bank.
+ account_number: bank account number of the user attempting to withdraw.
+ }
+
+After the user confirms the exchange to withdraw coins from, the wallet will
+visit the callback URL, in order to let the user answer some security questions
+and provide all relevant data to create a reserve.
+
+.. note::
+ Currently, the bank is in charge of creating the reserve at the chosen
+ exchange. In future, the exchange will "poll" its bank account and automatically
+ creating a reserve whenever it receives any funds, without any bank's
+ intervention.
+
+The callback URL implements the following API.
+
+.. http:get:: <callback_url>
+
+ **Request**
+
+ :query amount_value: integer part of the amount to be withdrawn.
+ :query amount_fraction: fractional part of the amount to be withdrawn.
+ :query amount_currency: currency of the amount to be withdrawn.
+ :query exchange: base URL of the exchange where the reserve is to be created.
+ :query reserve_pub: public key of the reserve to create.
+ :query wire_details: stringification of WireDetails_.
+
+ **Response**
+
+ Because the wallet is not supposed to take action according to this response,
+ the bank implementers are not required to return any particular status code here.
+
+ For example, our demonstrator bank always redirects the browser to the user's
+ profile page and let them know the outcome via a informational bar.
diff --git a/api-common.rst b/api-common.rst
index b9acd5cc..1526d7ef 100644
--- a/api-common.rst
+++ b/api-common.rst
@@ -724,6 +724,17 @@ within the
struct TALER_AmountNBO refund_fee;
};
+ struct TALER_MerchantRefundConfirmationPS {
+ /**
+ * purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND_OK
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+ /**
+ * Hash of the order ID (a string), hashed without the 0-termination.
+ */
+ struct GNUNET_HashCode h_order_id;
+ };
+
.. _TALER_PaybackRequestPS:
.. sourcecode:: c
diff --git a/api-exchange.rst b/api-exchange.rst
index f2af78ca..507eb568 100644
--- a/api-exchange.rst
+++ b/api-exchange.rst
@@ -719,8 +719,8 @@ denomination.
// Deposit fee in case of type "MELT".
melt_fee: Amount;
- // Session hash for the melt operation.
- session_hash: HashCode;
+ // Commitment from the melt operation.
+ rc: TALER_RefreshCommitmentP;
// Hash of the bank account from where we received the funds.
h_wire: HashCode;
@@ -795,35 +795,8 @@ the API during normal operation.
.. code-block:: tsref
interface MeltRequest {
- // Array of `n` new denominations to order.
- new_denoms: RsaPublicKey[];
- // Information about coin being melted.
- melt_coin: MeltCoin;
-
- // The outer dimension of the 2d array has `kappa` entries
- // for the cut-and-choose protocol.
- // The inner array contains `n` entries with blinded coins,
- // matching the respective entries in `new_denoms`.
- coin_evs: CoinEnvelope[][];
-
- // `kappa` transfer public keys (ephemeral ECDHE keys)
- transfer_pubs: EddsaPublicKey[];
-
- }
-
- For details about the HKDF used to derive the new coin private keys and
- the blinding factors from ECDHE between the transfer public keys and
- the private key of the melted coin, please refer to the
- implementation in `libtalerutil`. The `melt_coin` field is a list of JSON
- objects with the following fields:
-
-
- .. _tsref-type-MeltCoin:
- .. code-block:: tsref
-
- interface MeltCoin {
- // `Coin public key <eddsa-coin-pub>`_, uniquely identifies the coin
+ // `Coin public key <eddsa-coin-pub>`_, uniquely identifies the coin to be melted
coin_pub: string;
// The denomination public key allows the exchange to determine total coin value.
@@ -832,22 +805,23 @@ the API during normal operation.
// Signature over the `coin public key <eddsa-coin-pub>`_ by the denomination.
denom_sig: RsaSignature;
- // Signature by the `coin <coin-priv>`_ over the session public key.
+ // Signature by the `coin <coin-priv>`_ over the melt commitment.
confirm_sig: EddsaSignature;
// Amount of the value of the coin that should be melted as part of
// this refresh operation, including melting fee.
value_with_fee: Amount;
- }
- Errors such as failing to do proper arithmetic when it comes to calculating
- the total of the coin values and fees are simply reported as bad requests.
- This includes issues such as melting the same coin twice in the same session,
- which is simply not allowed. However, theoretically it is possible to melt a
- coin twice, as long as the `value_with_fee` of the two melting operations is
- not larger than the total remaining value of the coin before the melting
- operations. Nevertheless, this is not really useful.
+ // Melt commitment. Hash over the various coins to be withdrawn.
+ // See also `TALER_refresh_get_commitment()`
+ rc: TALER_RefreshCommitmentP;
+ }
+
+ For details about the HKDF used to derive the new coin private keys and
+ the blinding factors from ECDHE between the transfer public keys and
+ the private key of the melted coin, please refer to the
+ implementation in `libtalerutil`.
.. _tsref-type-MeltResponse:
.. _MeltResponse:
@@ -900,8 +874,14 @@ the API during normal operation.
Reveal previously commited values to the exchange, except for the values
corresponding to the `noreveal_index` returned by the /exchange/melt step.
- Request body contains a JSON object with the following fields:
+ Errors such as failing to do proper arithmetic when it comes to calculating
+ the total of the coin values and fees are simply reported as bad requests.
+ This includes issues such as melting the same coin twice in the same session,
+ which is simply not allowed. However, theoretically it is possible to melt a
+ coin twice, as long as the `value_with_fee` of the two melting operations is
+ not larger than the total remaining value of the coin before the melting
+ operations. Nevertheless, this is not really useful.
:status 200 OK:
The transfer private keys matched the commitment and the original request was well-formed.
@@ -913,22 +893,31 @@ the API during normal operation.
but of course expected to be primarily used for diagnostics.
The response body is a `RevealConflictResponse`_.
+ **Details:**
+ Request body contains a JSON object with the following fields:
.. code-block:: tsref
interface RevealRequest {
- // Hash over most of the arguments to the /exchange/melt step. Used to
- // identify the corresponding melt operation. For details on which elements
- // must be hashed in which order, please consult the source code of the exchange
- // reference implementation.
- session_hash: HashCode;
-
- // Array of `kappa - 1` ECDHE transfer private keys.
- // The exchange will use those to decrypt the transfer secrets,
- // and then decrypt the private keys and blinding factors
- // of the coins to be generated and check all this against the commitments.
+
+ // Array of `n` new hash codes of denomination public keys to order.
+ new_denoms_h: HashCode[];
+
+ // Array of `n` entries with blinded coins,
+ // matching the respective entries in `new_denoms`.
+ coin_evs: CoinEnvelope[];
+
+ // `kappa - 1` transfer private keys (ephemeral ECDHE keys)
transfer_privs: EddsaPrivateKey[];
+
+ // transfer public key at the `noreveal_index`.
+ transfer_pub: EddsaPublicKey;
+
+ // The original commitment, used to match the /refresh/reveal
+ // to the corresponding /refresh/melt operation.
+ rc: TALER_RefreshCommitmentP;
+
}
@@ -950,48 +939,11 @@ the API during normal operation.
// Constant "commitment violation"
error: string;
- // Signature of the coin over the melting operation.
- coin_sig: EddsaSignature;
-
- // Coin that we failed to successfully melt.
- coin_pub: EddsaPublicKey;
-
- // Amount of the value of the coin to be melted in the refresh session.
- melt_amount_with_fee: Amount;
-
- // Fee that was due for the melting for the coin.
- melt_fee: Amount;
+ // Detailed error code
+ code: integer;
- // Denomination keys to be used for the coins to be withdrawn.
- newcoin_infos: RsaPublicKey[];
-
- // Array of blinded coins to be withdrawn. Same length as
- // `newcoin_infos`.
- commit_infos: CoinEnvelope[];
-
- // Transfer public key at index `gamma`.
- gamma_tp: EddsaPublicKey;
-
- // Specific `gamma` value chosen by the exchange.
- gamma: number;
-
- }
-
-
- .. _tsref-type-LinkInfo:
- .. code-block:: tsref
-
- interface LinkInfo {
- // the transfer ECDHE public key
- transfer_pub: EddsaPublicKey;
-
- }
-
- .. _tsref-type-CommitInfo:
- .. code-block:: tsref
-
- interface CommitInfo {
- coin_ev: BlindedRsaSignature;
+ // Commitment as calculated by the exchange from the revealed data.
+ rc_expected: TALER_RefreshCommitmentP;
}
@@ -1021,14 +973,9 @@ the API during normal operation.
interface LinkResponse {
// transfer ECDHE public key corresponding to the `coin_pub`, used to
- // decrypt the `secret_enc` in combination with the private key of
- // `coin_pub`.
+ // compute the blinding factor and private key of the fresh coins.
transfer_pub: EcdhePublicKey;
- // ECDHE-encrypted link secret that, once decrypted, can be used to
- // decrypt/unblind the `new_coins`.
- secret_enc: Base32;
-
// array with (encrypted/blinded) information for each of the coins
// exchangeed in the refresh operation.
new_coins: NewCoinInfo[];
diff --git a/api-merchant.rst b/api-merchant.rst
index abee1d52..6330f3c8 100644
--- a/api-merchant.rst
+++ b/api-merchant.rst
@@ -42,14 +42,14 @@ The Frontend HTTP API
triggered by a "402 Payment Required" response, it will issue a GET request to
the proposal URL and show the proposal to the user.
The "402 Payment Required" trigger instructs the wallet whether or
- not to provide the optional `nonce` parameter.
+ not to provide the optional `nonce` parameter.
**Request:**
:query nonce: Any string value. This value will be
included in the proposal, so that when the wallet receives the proposal it can
easily check whether it was the genuine receiver of the proposal it got.
- This value is needed to avoid having multiple customers pay for
+ This value is needed to avoid having multiple customers pay for
the same proposal, which might be bad if the number of goods that can
be shipped is limited.
@@ -255,7 +255,7 @@ The following API are made available by the merchant's `backend` to the merchant
The request body is a `RefundRequest`_ object.
**Response**
-
+
:status 200 OK:
The refund amount has been increased, the backend responds with a `RefundConfirmation`_
:status 400 Bad request:
@@ -282,13 +282,11 @@ The following API are made available by the merchant's `backend` to the merchant
.. code-block:: tsref
interface RefundConfirmation {
- // Merchant signature over the hashed order id. Note
- // that the purpose is set to zero. However, this value
- // is not meant to be soon verified by the frontend, but
- // could be showed in court.
- sig: EddsaSignature
+ // Merchant signature over the hashed order id.
+ // The purpose is `TALER_SIGNATURE_MERCHANT_REFUND_OK`.
+ sig: EddsaSignature
}
-
+
.. http:get:: /refund
Shows the refund situation about a transaction
@@ -310,14 +308,18 @@ The following API are made available by the merchant's `backend` to the merchant
.. _RefundLookup:
.. code-block:: tsref
+<<<<<<< HEAD
interface RefundLookupResponse {
refund_permissions: RefundPermission[];
}
interface RefundPermission {
+=======
+ interface RefundLookup {
+>>>>>>> fd0e5260107f6c418659808b2620484332afd774
// Coin from which the refund is going to be taken
- coin_pub: EddsaPublicKey;
+ coin_pub: EddsaPublicKey;
// Refund amount taken from coin_pub
refund_amount: Amount;
@@ -336,20 +338,52 @@ The following API are made available by the merchant's `backend` to the merchant
}
+.. http:post:: /tip-enable
+
+ Enable tipping by telling the backend that a reserve was created with funds for tipping.
+
+ **Request**
+
+ The request body is a `TipEnable`_ object. Note that if an existing,
+ non-expired reserve is credited, the credits are added and the
+ expiration time is updated to the max of the expiration times.
+
+ **Response**
+
+ :status 200 OK:
+ A reserve with credit for tipping has been created. The response is empty.
+
+ .. _TipEnable:
+ .. code-block:: tsref
+
+ interface TipEnable {
+ // Amount that was credited to the reserve
+ credit: Amount;
+
+ // Expiration time for the reserve
+ expiration: Timestamp;
+
+ // Private key of the reserve
+ reserve_priv: ReservePrivateKeyP;
+
+ // Unique ID for the wire transfer, used to detect duplicate credits
+ credit_uuid: HashCode;
+ }
+
.. http:post:: /tip-authorize
Authorize a tip that can be picked up by the customer's wallet by POSTing to `/tip-pickup`. Note that this is simply the authorization step the back office has to trigger first. The frontend must return the tip's identifier (and exchange URL) via a "402 Payment Required" response to the wallet.
- Note that tipping is not yet implemented!
-
**Request**
The request body is a `TipCreateRequest`_ object.
**Response**
-
+
:status 200 OK:
A tip has been created. The backend responds with a `TipCreateConfirmation`_
+ :status 404 Not Found:
+ The instance is unknown to the backend, expired or was never enabled.
:status 412 Precondition Failed:
The tip amount requested exceeds the available reserve balance for tipping.
@@ -358,7 +392,7 @@ The following API are made available by the merchant's `backend` to the merchant
interface TipCreateRequest {
// Amount that the customer should be tipped
- refund: Amount;
+ amount: Amount;
// Merchant instance issuing the request
instance: string;
@@ -375,7 +409,7 @@ The following API are made available by the merchant's `backend` to the merchant
tip_id: HashCode;
// Expiration time for obtaining the tip
- tip_expiration: Timestamp;
+ expiration: Timestamp;
// URI of the exchange from where the tip can be withdrawn
exchange_uri: String;
@@ -386,14 +420,12 @@ The following API are made available by the merchant's `backend` to the merchant
Handle request from wallet to pick up a tip.
- Note that tipping is not yet implemented!
-
**Request**
The request body is a `TipPickupRequest`_ object.
**Response**
-
+
:status 200 OK:
A tip is being returned. The backend responds with a `TipResponse`_
:status 401 Unauthorized:
@@ -408,9 +440,6 @@ The following API are made available by the merchant's `backend` to the merchant
interface TipPickupRequest {
- // Merchant instance issuing the request
- instance: string;
-
// Identifier of the tip.
tip_id: HashCode;
@@ -425,7 +454,7 @@ The following API are made available by the merchant's `backend` to the merchant
// coin's blinded public key
coin_ev: CoinEnvelope;
-
+
}
.. _TipResponse:
@@ -439,7 +468,7 @@ The following API are made available by the merchant's `backend` to the merchant
reserve_sigs: EddsaSignature[];
}
-
+
.. http:get:: /track/transfer
Provides deposits associated with a given wire transfer.
@@ -447,9 +476,9 @@ The following API are made available by the merchant's `backend` to the merchant
**Request**
:query wtid: raw wire transfer identifier identifying the wire transfer (a base32-encoded value)
- :query wire_method: name of the wire transfer method used for the wire transfer
+ :query wire_method: name of the wire transfer method used for the wire transfer
:query exchange: base URI of the exchange that made the wire transfer
- :query instance: (optional) identificative token of the merchant `instance <https://docs.taler.net/operate-merchant.html#instances-lab>`_ which is being tracked.
+ :query instance: (optional) identificative token of the merchant `instance <https://docs.taler.net/operate-merchant.html#instances-lab>`_ which is being tracked.
**Response:**
@@ -686,7 +715,7 @@ The following API are made available by the merchant's `backend` to the merchant
A typical usage is to firstly call this API without `start` and `date` parameter, then fetch the oldest
`row_id` from the results, and then keep calling the API by using the oldest row ID as `start` parameter.
This way we simply "scroll" results from the youngest to the oldest, `delta` entries at time.
-
+
**Response**
:status 200 OK: The response is a JSON `array` of `TransactionHistory`_. The array is sorted such that entry `i` is younger than entry `i+1`.
diff --git a/conf.py b/conf.py
index 9031f050..6758983b 100644
--- a/conf.py
+++ b/conf.py
@@ -75,9 +75,9 @@ copyright = u'2014, 2015, 2016 Florian Dold, Benedikt Muller, Sree Harsha Totaku
# built documents.
#
# The short X.Y version.
-version = '0.2'
+version = '0.4'
# The full version, including alpha/beta/rc tags.
-release = '0.2.0'
+release = '0.4.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/exts/__pycache__/tsref.cpython-35.pyc b/exts/__pycache__/tsref.cpython-35.pyc
index b209b4b6..bbfb48dc 100644
--- a/exts/__pycache__/tsref.cpython-35.pyc
+++ b/exts/__pycache__/tsref.cpython-35.pyc
Binary files differ
diff --git a/index.rst b/index.rst
index ff65b794..d96cd388 100644
--- a/index.rst
+++ b/index.rst
@@ -1,6 +1,6 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014, 2015, 2016 GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016, 2017 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software