taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

api-exchange.rst (35040B)


      1 ..
      2   This file is part of GNU TALER.
      3   Copyright (C) 2014-2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU Affero General Public License as published by the Free Software
      7   Foundation; either version 2.1, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 
     16   @author Christian Grothoff
     17   @author Özgür Kesim
     18 
     19 ====================
     20 Exchange RESTful API
     21 ====================
     22 
     23 The API specified here follows the :ref:`general conventions <http-common>`
     24 for all details not specified in the individual requests.
     25 The `glossary <https://docs.taler.net/taler-developer-manual.html#developer-glossary>`_
     26 defines all specific terms used in this section.
     27 
     28 
     29 ---------------
     30 Version History
     31 ---------------
     32 
     33 The current protocol version is **v34**.
     34 
     35 * The merchant is currently targeting **v34**.
     36 * The AML SPA is currently targeting **v31**.
     37 * The KYC SPA is currently targeting **v30**.
     38 
     39 **Version history:**
     40 
     41 * ``v29``: AML reporting on KYC auth transfers
     42 * ``v30``: various minor feature additions
     43 * ``v31``: improvements for AML reporting
     44 * ``v32``: support for extra_wire_subject_metadata
     45 * ``v33``: addition of accumulated_total_without_fee in ``/batch-deposit``
     46 * ``v34``: new offline signature; support for open_banking_gateway and
     47            wire_transfer_gateway per wire account in ``/keys``
     48 
     49 **Upcoming versions:**
     50 
     51 * ``vRECOUP``: improved recoup protocol
     52 * ``vATTEST``: KYC attestation support
     53 
     54 **Ideas for future version:**
     55 
     56 * ``vXXX``: marker for features not yet targeted for release
     57 
     58 
     59 
     60 .. include:: tos.rst
     61 
     62 .. _keys:
     63 
     64 ---------------------------
     65 Exchange status information
     66 ---------------------------
     67 
     68 This API is used by wallets and merchants to obtain global information about
     69 the exchange, such as online signing keys, available denominations and the fee
     70 structure.  This is typically the first call any exchange client makes, as it
     71 returns information required to process all of the other interactions with the
     72 exchange.  The returned information is secured by (1) signature(s) from the exchange,
     73 especially the long-term offline signing key of the exchange, which clients should
     74 cache; (2) signature(s) from auditors, and the auditor keys should be
     75 hard-coded into the wallet as they are the trust anchors for Taler; (3)
     76 possibly by using HTTPS.
     77 
     78 
     79 .. include:: exchange/get-seed.rst
     80 
     81 .. include:: exchange/get-config.rst
     82 
     83 .. include:: exchange/get-keys.rst
     84 
     85 
     86 ----------------------------------------------
     87 Management operations authorized by master key
     88 ----------------------------------------------
     89 
     90 .. include:: exchange/get-management-keys.rst
     91 
     92 .. include:: exchange/post-management-keys.rst
     93 
     94 .. include:: exchange/post-management-denominations-H_DENOM_PUB-revoke.rst
     95 
     96 .. include:: exchange/post-management-signkeys-EXCHANGE_PUB-revoke.rst
     97 
     98 .. include:: exchange/post-management-auditors.rst
     99 
    100 .. include:: exchange/post-management-auditors-AUDITOR_PUB-disable.rst
    101 
    102 .. include:: exchange/post-management-wire-fee.rst
    103 
    104 .. include:: exchange/post-management-global-fees.rst
    105 
    106 .. include:: exchange/post-management-wire.rst
    107 
    108 .. include:: exchange/post-management-wire-disable.rst
    109 
    110 .. include:: exchange/post-management-drain.rst
    111 
    112 .. include:: exchange/post-management-aml-officers.rst
    113 
    114 .. include:: exchange/post-management-partners.rst
    115 
    116 ---------------
    117 Auditor actions
    118 ---------------
    119 
    120 .. _auditor_action:
    121 
    122 This part of the API is for the use by auditors interacting with the exchange.
    123 
    124 
    125 .. include:: exchange/post-auditors-AUDITOR_PUB-H_DENOM_PUB.rst
    126 
    127 
    128 ----------------
    129 Blinding Prepare
    130 ----------------
    131 
    132 Certain denomination cipher types, such as Clause-Schnorr, require input values
    133 from the exchange-side as preparation for the blinding of the coins.  See the
    134 Bachelor thesis of Gian Demarmels and Lucien Heuzeveldt,
    135 `Adding Schnorr’s Blind Signature in Taler <https://www.taler.net/papers/cs-thesis.pdf>`_,
    136 for details.
    137 
    138 .. include:: exchange/post-blinding-prepare.rst
    139 
    140 
    141 
    142 .. _exchange-withdrawal:
    143 
    144 ----------
    145 Withdrawal
    146 ----------
    147 
    148 This API is used by the wallet to obtain digital coins.
    149 
    150 When transferring money to the exchange such as via SEPA transfers, the exchange creates
    151 a *reserve*, which keeps the money from the customer.  The customer must
    152 specify an EdDSA reserve public key as part of the transfer, and can then
    153 withdraw digital coins using the corresponding private key.  All incoming and
    154 outgoing transactions are recorded under the corresponding public key by the
    155 exchange.
    156 
    157 .. note::
    158 
    159    Eventually the exchange will need to advertise a policy for how long it will
    160    keep transaction histories for inactive or even fully drained reserves.  We
    161    will therefore need some additional handler similar to ``/keys`` to
    162    advertise those terms of service.
    163 
    164 
    165 .. include:: exchange/get-reserves-RESERVE_PUB.rst
    166 
    167 .. _withdraw:
    168 .. include:: exchange/post-withdraw.rst
    169 
    170 
    171 .. ts:def:: WithdrawRequest
    172 
    173   interface WithdrawRequest {
    174     // Cipher that is used for the rerserve's signatures.
    175     // For now, only ed25519 signatures are applicable,
    176     // but this might change in future versions.
    177     cipher: "ED25519";
    178 
    179     // The reserve's public key, for the the cipher ED25519,
    180     // to verify the signature ``reserve_sig``.
    181     reserve_pub: EddsaPublicKey;
    182 
    183     // Array of ``n`` hash codes of denomination public keys to order.
    184     // The sum of all denomination's values and fees MUST be
    185     // at most the balance of the reserve. The balance of
    186     // the reserve will be immediatley reduced by that amount.
    187     // If ``max_age`` is set, these denominations MUST support
    188     // age restriction as defined in the output to /keys.
    189     denoms_h: HashCode[];
    190 
    191     // If set, the maximum age to commit to. This implies:
    192     // 1.) it MUST be the same value as the maximum age
    193     //     of the reserve.
    194     // 2.) ``coin_evs`` MUST be an array of ``n*kappa``
    195     // 3.) the denominations in ``denoms_h`` MUST support
    196     //      age restriction.
    197     max_age?: Integer;
    198 
    199     // Master seed for the Clause-Schnorr R-value creation.
    200     // MUST match the /blinding-prepare request.
    201     // MUST NOT have been used in any prior withdraw request.
    202     // MUST be present if one of the fresh coin's
    203     // denomination is of type Clause-Schnorr.
    204     blinding_seed?: BlindingMasterSeed;
    205 
    206     // Array of blinded coin envelopes of type `CoinEnvelope`.
    207     // If ``max_age`` is not set, MUST be n entries.
    208     // If ``max_age`` is set, MUST be ``n*kappa`` entries,
    209     // arranged in [0..n)..[0..n), with the first n entries
    210     // belonging to kappa=0 etc.
    211     // In case of age restriction, the exchange will
    212     // respond with an index ``gamma``, which is the index
    213     // that shall remain undisclosed during the subsequent
    214     // reveal phase.
    215     // This hash value along with the reserve's public key
    216     // will also be used for recoup operations, if needed.
    217     coin_evs:  CoinEnvelope[];
    218 
    219     // Signature of `TALER_WithdrawRequestPS` created with
    220     // the `reserves's private key <reserve-priv>`.
    221     reserve_sig: EddsaSignature;
    222   }
    223 
    224 .. ts:def:: WithdrawResponse
    225 
    226   interface WithdrawResponse {
    227     // Array of blinded signatures over each ``coin_evs``,
    228     // in the same order as was given in the request.
    229     // The blinded signatures affirm the coin's validity
    230     // after unblinding.
    231     ev_sigs: BlindedDenominationSignature[];
    232 
    233   }
    234 
    235 
    236 .. ts:def:: AgeWithdrawResponse
    237 
    238   interface AgeWithdrawResponse {
    239     // index of the commitments that the client doesn't
    240     // have to disclose in the subsequent call to
    241     // ``/reveal-withdraw``.
    242     noreveal_index: Integer;
    243 
    244     // Signature of `TALER_WithdrawConfirmationPS` whereby
    245     // the exchange confirms the ``noreveal_index``.
    246     exchange_sig: EddsaSignature;
    247 
    248     // `Public EdDSA key <sign-key-pub>` of the exchange that was used to
    249     // generate the signature.  Should match one of the exchange's signing
    250     // keys from ``/keys``.  Again given explicitly as the client might
    251     // otherwise be confused by clock skew as to which signing key was used.
    252     exchange_pub: EddsaPublicKey;
    253 
    254   }
    255 
    256 .. ts:def:: DenominationGoneMessage
    257 
    258   interface DenominationGoneMessage {
    259 
    260     // Taler error code.  Note that beyond
    261     // expiration this message format is also
    262     // used if the key is not yet valid, or
    263     // has been revoked. May be one of
    264     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE``
    265     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED``
    266     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED``
    267     code: Integer;
    268 
    269     // Signature by the exchange over a
    270     // `TALER_DenominationExpiredAffirmationPS`.
    271     // Must have purpose ``TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED``.
    272     exchange_sig: EddsaSignature;
    273 
    274     // Public key of the exchange used to create
    275     // the 'exchange_sig.
    276     exchange_pub: EddsaPublicKey;
    277 
    278     // Hash of the denomination public key that is unknown.
    279     h_denom_pub: HashCode;
    280 
    281     // When was the signature created.
    282     timestamp: Timestamp;
    283 
    284     // What kind of operation was requested that now
    285     // failed?
    286     oper: string;
    287 
    288   }
    289 
    290 
    291 .. ts:def:: WithdrawError
    292 
    293   interface SingleWithdrawError {
    294     // Text describing the error.
    295     hint: string;
    296 
    297     // Detailed error code.
    298     code: Integer;
    299 
    300     // Amount left in the reserve.
    301     balance: Amount;
    302 
    303   }
    304 
    305 
    306 
    307 ------------------
    308 
    309 
    310 .. _reveal-withdraw:
    311 
    312 **Reveal-Withdraw**
    313 
    314 This endpoint is called by the client after a call to `withdraw`_,
    315 *if* the original request had ``max_age`` set and
    316 the response was of type `AgeWithdrawResponse`.
    317 Now the client has to disclose for each coin all but one of the κ secrets
    318 that went into creating the blinded coin's planchets,
    319 including the commitment to age restriction,
    320 and prove that the age restriction was set correctly.
    321 
    322 .. include:: exchange/post-reveal-withdraw.rst
    323 
    324 
    325 
    326 ----------
    327 Refreshing
    328 ----------
    329 
    330 Refreshing creates ``n`` new coins from ``m`` old coins, where the sum of
    331 denominations of the new coins must be smaller than the sum of the old coins'
    332 denominations plus melting (refresh) and withdrawal fees charged by the exchange.
    333 The refreshing API can be used by wallets to melt partially spent coins, making
    334 transactions with the freshly exchangeed coins unlinkabe to previous transactions
    335 by anyone except the wallet itself.
    336 
    337 Refreshing is a two step process, consisting of
    338 
    339 1. the **melting** of the old coin, together with ``kappa`` batches
    340    of blinded planchets candidates,
    341 2. the **reveal** of ``kappa-1`` secrets to prove the proper construction
    342    of the (revealed) batches of blinded planchets candidates.
    343 
    344 
    345 ^^^^
    346 Melt
    347 ^^^^
    348 
    349 .. _melt:
    350 .. include:: exchange/post-melt.rst
    351 
    352 ^^^^^^^^^^^
    353 Reveal-Melt
    354 ^^^^^^^^^^^
    355 
    356 This endpoint is called by the client after a call to `melt`_.
    357 Now the client has to disclose --for each coin--
    358 all but one of the κ secrets that went into creating the blinded coin's planchets,
    359 the transfer public keys (linking the ownership of the old and new coin),
    360 and the commitment to age restriction,
    361 as proof that the age restriction was set correctly (if applicable).
    362 
    363 .. include:: exchange/post-reveal-melt.rst
    364 
    365 
    366 .. _deposit-par:
    367 
    368 -------
    369 Deposit
    370 -------
    371 
    372 Deposit operations are requested f.e. by a merchant during a transaction or a
    373 bidder during an auction.
    374 
    375 For the deposit operation during purchase, the merchant has to obtain the
    376 deposit permission for a coin from their customer who owns the coin.  When
    377 depositing a coin, the merchant is credited an amount specified in the deposit
    378 permission, possibly a fraction of the total coin's value, minus the deposit
    379 fee as specified by the coin's denomination.
    380 
    381 For auctions, a bidder performs an deposit operation and provides all relevant
    382 information for the auction policy (such as timeout and public key as bidder)
    383 and can use the ``exchange_sig`` field from the `DepositSuccess` message as a
    384 proof to the seller for the escrow of sufficient fund.
    385 
    386 
    387 .. _deposit:
    388 
    389 .. include:: exchange/post-batch-deposit.rst
    390 
    391 
    392 
    393 ------
    394 Recoup
    395 ------
    396 
    397 The purpose of this API is to allow coins to be cashed back in,
    398 in certain exceptional situations.
    399 This API is only used if the exchange is either about to go out of
    400 business or has had its private signing keys compromised (so in
    401 either case, the protocol is only used in **abnormal**
    402 situations).  In the above cases, the exchange signals to the
    403 wallets that the emergency cash back protocol has been activated
    404 by putting the affected denomination keys into the cash-back
    405 part of the ``/keys`` response.  If and only if this has happened,
    406 coins that were signed with those denomination keys can be cashed
    407 in using this API.
    408 
    409 For a recoup, a coin has to provide the necessary information to
    410 identify the original transaction (either a withdraw or a refresh) it
    411 became minted, and proof ownership of the coin itself.
    412 
    413 
    414 .. include:: exchange/post-recoup-withdraw.rst
    415 
    416 
    417 .. include:: exchange/post-recoup-refresh.rst
    418 
    419 
    420 
    421 .. _exchange_refund:
    422 
    423 -------
    424 Refunds
    425 -------
    426 
    427 .. include:: exchange/post-coins-COIN_PUB-refund.rst
    428 
    429 
    430 .. _reserve-history:
    431 
    432 ---------------
    433 Reserve History
    434 ---------------
    435 
    436 .. include:: exchange/get-reserves-RESERVE_PUB-history.rst
    437 
    438 
    439 
    440 .. _coin-history:
    441 
    442 ------------
    443 Coin History
    444 ------------
    445 
    446 .. include:: exchange/get-coins-COIN_PUB-history.rst
    447 
    448 Obtain the transaction history of a coin.  Used only in special cases, like
    449 when the exchange claims a double-spending error and the wallet does not
    450 believe it. Usually, the wallet knows the transaction history of each coin
    451 and thus has no need to inquire.
    452 
    453 **Request:**
    454 
    455 The GET request should come with the following HTTP headers:
    456 
    457 *If-None-Match*:
    458   The client MAY provide an ``If-None-Match`` header with an
    459   Etag.  In that case, the server MUST additionally respond with an ``304``
    460   status code in case the coin history matches the provided Etag.
    461 
    462 *Taler-Coin-History-Signature*:
    463   The client MUST provide Base-32 encoded EdDSA signature over a
    464   ``TALER_SIGNATURE_COIN_HISTORY_REQUEST`` made with the respective
    465   ``$COIN_PRIV``, affirming desire to download the current coin
    466   transaction history.
    467 
    468 :query start=OFFSET: *Optional.* Only return coin history entries with
    469                      offsets above the given OFFSET. Allows clients to not
    470                      retrieve history entries they already have.
    471 
    472 **Response:**
    473 
    474 :http:statuscode:`200 OK`:
    475   The operation succeeded, the exchange confirms that no double-spending took
    476   place.  The response will include a `CoinHistoryResponse` object.
    477 :http:statuscode:`204 No content`:
    478   The reserve history is known, but at this point from the given starting point it is empty. Can only happen if OFFSET was positive.
    479 :http:statuscode:`304 Not modified`:
    480   The coin history has not changed since the previous query (detected via Etag
    481   in "If-none-match" header).
    482 :http:statuscode:`403 Forbidden`:
    483   The *TALER_SIGNATURE_COIN_HISTORY_REQUEST* is invalid.
    484   This response comes with a standard `ErrorDetail` response.
    485 :http:statuscode:`404 Not found`:
    486   The coin public key is not (yet) known to the exchange.
    487 
    488 **Details:**
    489 
    490 .. ts:def:: CoinHistoryResponse
    491 
    492   interface CoinHistoryResponse {
    493     // Current balance of the coin.
    494     balance: Amount;
    495 
    496     // Hash of the coin's denomination.
    497     h_denom_pub: HashCode;
    498 
    499     // Transaction history for the coin.
    500     history: CoinSpendHistoryItem[];
    501   }
    502 
    503 .. ts:def:: CoinSpendHistoryItem
    504 
    505   // Union discriminated by the "type" field.
    506   type CoinSpendHistoryItem =
    507     | CoinDepositTransaction
    508     | CoinMeltTransaction
    509     | CoinRefundTransaction
    510     | CoinRecoupWithdrawTransaction
    511     | CoinRecoupRefreshTransaction
    512     | CoinRecoupRefreshReceiverTransaction
    513     | CoinPurseDepositTransaction
    514     | CoinPurseRefundTransaction
    515     | CoinReserveOpenDepositTransaction;
    516 
    517 .. ts:def:: CoinDepositTransaction
    518 
    519   interface CoinDepositTransaction {
    520     type: "DEPOSIT";
    521 
    522     // Offset of this entry in the reserve history.
    523     // Useful to request incremental histories via
    524     // the "start" query parameter.
    525     history_offset: Integer;
    526 
    527     // The total amount of the coin's value absorbed (or restored in the
    528     // case of a refund) by this transaction.
    529     // The amount given includes
    530     // the deposit fee. The current coin value can thus be computed by
    531     // subtracting this amount.
    532     amount: Amount;
    533 
    534     // Deposit fee.
    535     deposit_fee: Amount;
    536 
    537     // Public key of the merchant.
    538     merchant_pub: EddsaPublicKey;
    539 
    540     // Date when the operation was made.
    541     timestamp: Timestamp;
    542 
    543     // Date until which the merchant can issue a refund to the customer via the
    544     // exchange, possibly zero if refunds are not allowed.
    545     refund_deadline?: Timestamp;
    546 
    547     // Hash over the proposal data of the contract that
    548     // is being paid.
    549     h_contract_terms: HashCode;
    550 
    551     // Hash of the bank account from where we received the funds.
    552     h_wire: HashCode;
    553 
    554     // Hash of the public denomination key used to sign the coin.
    555     // Needed because 'coin_sig' signs over this, and
    556     // that is important to fix the coin's denomination.
    557     h_denom_pub: HashCode;
    558 
    559     // Hash over the deposit policy extension. Optional.
    560     h_policy?: HashCode;
    561 
    562     // Hash over auxiliary wallet data provided by the wallet
    563     // to complete the contract. Optional.
    564     wallet_data_hash?: HashCode;
    565 
    566     // Hash over the age commitment of the coin. Optional.
    567     h_age_commitment?: HashCode;
    568 
    569     // Signature over `TALER_DepositRequestPS`, made by the customer with the
    570     // `coin's private key <coin-priv>`.
    571     coin_sig: EddsaSignature;
    572 
    573   }
    574 
    575 .. ts:def:: CoinMeltTransaction
    576 
    577   interface CoinMeltTransaction {
    578     type: "MELT";
    579 
    580     // Offset of this entry in the reserve history.
    581     // Useful to request incremental histories via
    582     // the "start" query parameter.
    583     history_offset: Integer;
    584 
    585     // The total amount of the coin's value absorbed by this transaction.
    586     // Note that for melt this means the amount given includes
    587     // the melt fee. The current coin value can thus be computed by
    588     // subtracting the amounts.
    589     amount: Amount;
    590 
    591     // Melt fee.
    592     melt_fee: Amount;
    593 
    594     // Commitment from the melt operation, see `TALER_RefreshCommitmentP`
    595     rc: HashCode;
    596 
    597     // Hash of the public denomination key used to sign the old coin.
    598     // Needed because 'coin_sig' signs over this, and
    599     // that is important to fix the coin's denomination.
    600     old_denom_pub_h: HashCode;
    601 
    602     // Hash over the age commitment of the coin. Optional.
    603     old_age_commitment_h?: AgeCommitmentHash;
    604 
    605     // @since **v32**
    606     // This value is opaque to the exchange.  It was provided by the client
    607     // as part of the original refresh request, and was therefore verified
    608     // with the confirm_sig below.
    609     // If the reveal step was not performed yet by the old coin owner,
    610     // they can use this value and the old coin's private key to derive
    611     // all indivual seeds for the n*κ coin candidates for the original
    612     // refresh request and replay it
    613     refresh_seed: HashCode;
    614 
    615     // @since **v32**
    616     // The kappa*n list of transfer public keys that were provided by the
    617     // old coin owner during the melt request.
    618     transfer_pubs: EddsaPublicKey[kappa][];
    619 
    620     // @since **v32**
    621     // The n denomination public keys for the fresh coins
    622     // that the coin owner had requested.
    623     denoms_h: HashCode[];
    624 
    625     // @since **v32**
    626     // The ``noreveal_index`` value that was returned by the exchange as response
    627     // to the melt request.
    628     noreveal_index: Integer;
    629 
    630     // @since **v32**
    631     // If the reveal step was successfully peformed by the coin owner,
    632     // this field contains the blind coin signatures that were returned
    633     // by the exchange for the chosen batch of coins.
    634     ev_sigs?: BlindedDenominationSignature[];
    635 
    636     // Master seed for the Clause-Schnorr R-value
    637     // Present if one of the fresh coin's
    638     // denominations is of type Clause-Schnorr.
    639     blinding_seed?: BlindingMasterSeed;
    640 
    641     // Signature by the coin over a
    642     // `TALER_RefreshMeltCoinAffirmationPS` of
    643     // purpose ``TALER_SIGNATURE_WALLET_COIN_MELT``.
    644     confirm_sig: EddsaSignature;
    645 
    646   }
    647 
    648 .. ts:def:: CoinRefundTransaction
    649 
    650   interface CoinRefundTransaction {
    651     type: "REFUND";
    652 
    653     // Offset of this entry in the reserve history.
    654     // Useful to request incremental histories via
    655     // the "start" query parameter.
    656     history_offset: Integer;
    657 
    658     // The total amount of the coin's value restored
    659     // by this transaction.
    660     // The amount given excludes the transaction fee.
    661     // The current coin value can thus be computed by
    662     // adding the amounts to the coin's denomination value.
    663     amount: Amount;
    664 
    665     // Refund fee.
    666     refund_fee: Amount;
    667 
    668     // Hash over the proposal data of the contract that
    669     // is being refunded.
    670     h_contract_terms: HashCode;
    671 
    672     // Public key of the merchant.
    673     merchant_pub: EddsaPublicKey;
    674 
    675     // Refund transaction ID.
    676     rtransaction_id: Integer;
    677 
    678     // `EdDSA Signature <eddsa-sig>` authorizing the REFUND over a
    679     // `TALER_MerchantRefundConfirmationPS` with
    680     // purpose ``TALER_SIGNATURE_MERCHANT_REFUND_OK``. Made with
    681     // the `public key of the merchant <merchant-pub>`.
    682     merchant_sig: EddsaSignature;
    683 
    684   }
    685 
    686 
    687 .. note::
    688 
    689    The `CoinRecoupWithdrawTransaction` interface defintion is WIP.
    690    It will be fully specified and implemented with **vRECOUP**.
    691 
    692 .. ts:def:: CoinRecoupWithdrawTransaction
    693 
    694   // This represents a transaction of a call to /recoup-withdraw
    695   // where the coin's residual value has been credited to the
    696   // original reserve, from which this coin was withdrawn.
    697   interface CoinRecoupWithdrawTransaction {
    698     type: "RECOUP-WITHDRAW";
    699 
    700     // Offset of this entry in the reserve history.
    701     // Useful to request incremental histories via
    702     // the "start" query parameter.
    703     history_offset: Integer;
    704 
    705     // The total amount of the coin's value absorbed
    706     // by this transaction.
    707     // The current coin value can thus be computed by
    708     // subtracting the amount from
    709     // the coin's denomination value.
    710     amount: Amount;
    711 
    712     // Signature by the exchange over a
    713     // `TALER_RecoupConfirmationPS`, must be
    714     // of purpose ``TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP``.
    715     exchange_sig: EddsaSignature;
    716 
    717     // Public key of the private key used to create 'exchange_sig'.
    718     exchange_pub: EddsaPublicKey;
    719 
    720     // Signature by the coin over a
    721     // `TALER_RecoupRequestPS` with purpose
    722     // ``TALER_SIGNATURE_WALLET_COIN_RECOUP``.
    723     coin_sig: EddsaSignature;
    724 
    725     // Hash of the public denomination key used to sign the coin.
    726     // Needed because 'coin_sig' signs over this, and
    727     // that is important to fix the coin's denomination.
    728     h_denom_pub: HashCode;
    729 
    730     // Coin blinding key that was used in the original withdraw request.
    731     coin_blind: DenominationBlindingKeyP;
    732 
    733     // The hash of the withdraw commitment of the original withdraw
    734     // request that this coin was part of
    735     h_commitment: HashCode;
    736 
    737     // Coin's index in the original withdraw request, starting at 0
    738     coin_index: Integer;
    739 
    740     // Reserve receiving the recoup.
    741     reserve_pub: EddsaPublicKey;
    742 
    743     // Date when the operation was made.
    744     timestamp: Timestamp;
    745 
    746   }
    747 
    748 
    749 .. note::
    750 
    751    The `CoinRecoupRefreshTransaction` interface defintion is WIP.
    752    It will be fully specified and implemented with **vRECOUP**.
    753 
    754 .. ts:def:: CoinRecoupRefreshTransaction
    755 
    756   // This represents a transaction of a call to /recoup-refresh
    757   // where this coin was _part_ of the batch of coins whose
    758   // residual values were credited to the original coin, from
    759   // which also this coin was refresh from.
    760   interface CoinRecoupRefreshTransaction {
    761     type: "RECOUP-REFRESH";
    762 
    763     // Offset of this entry in the reserve history.
    764     // Useful to request incremental histories via
    765     // the "start" query parameter.
    766     history_offset: Integer;
    767 
    768     // The total amount of the coin's value absorbed
    769     // by this transaction.
    770     // The current coin value can thus be computed by
    771     // subtracting this amounts from
    772     // the coin's denomination value.
    773     amount: Amount;
    774 
    775     // Signature by the exchange over a
    776     // `TALER_RecoupRefreshConfirmationPS`
    777     // of purpose ``TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH``.
    778     exchange_sig: EddsaSignature;
    779 
    780     // Public key used to sign 'exchange_sig'.
    781     exchange_pub: EddsaPublicKey;
    782 
    783     // The original coin, from which this coin was derived from
    784     // in a call to /refresh, and which was then credited with
    785     // the residual value of this coin in a call to /recoup-refresh.
    786     old_coin_pub: EddsaPublicKey;
    787 
    788     // Signature by the coin over a `TALER_RecoupRequestPS`
    789     // with purpose ``TALER_SIGNATURE_WALLET_COIN_RECOUP``.
    790     coin_sig: EddsaSignature;
    791 
    792     // Hash of the public denomination key used to sign the coin.
    793     // Needed because 'coin_sig' signs over this, and
    794     // that is important to fix the coin's denomination.
    795     h_denom_pub: HashCode;
    796 
    797     // Coin blinding key that was used in the original refresh request.
    798     coin_blind: DenominationBlindingKeyP;
    799 
    800     // The hash of the refresh commitment of the original refresh
    801     // request that this coin was derived from.
    802     h_commitment: HashCode;
    803 
    804     // Coin's index in the original refresh request, starting at 0
    805     coin_index: Integer;
    806 
    807     // Blinding factor of the revoked new coin.
    808     new_coin_blinding_secret: DenominationBlindingKeySecret;
    809 
    810     // Blinded public key of the revoked new coin.
    811     new_coin_ev: DenominationBlindingKeySecret;
    812 
    813     // Date when the operation was made.
    814     timestamp: Timestamp;
    815 
    816   }
    817 
    818 
    819 .. note::
    820 
    821    The `CoinRecoupRefreshReceiverTransaction` interface defintion is WIP.
    822    It will be fully specified and implemented with **vRECOUP**.
    823 
    824 .. ts:def:: CoinRecoupRefreshReceiverTransaction
    825 
    826   // This represents a transaction of a call to /recoup-refresh
    827   // where this coin was the _receiver_ of the residual values
    828   // from coins, that originated from a call to /refresh of this coin.
    829   interface CoinRecoupRefreshReceiverTransaction {
    830     type: "RECOUP-REFRESH-RECEIVER";
    831 
    832     // Offset of this entry in the reserve history.
    833     // Useful to request incremental histories via
    834     // the "start" query parameter.
    835     history_offset: Integer;
    836 
    837     // The total amount of the coin's value restored
    838     // by this transaction.
    839     // The current coin value can thus be computed by
    840     // adding the amount to the coin's denomination value.
    841     amount: Amount;
    842 
    843     // Date when the operation was made.
    844     timestamp: Timestamp;
    845 
    846     // Signature by the exchange over a
    847     // `TALER_RecoupRefreshConfirmationPS`
    848     // of purpose ``TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH``.
    849     exchange_sig: EddsaSignature;
    850 
    851     // Public key of the private key used to create 'exchange_sig'.
    852     exchange_pub: EddsaPublicKey;
    853 
    854   }
    855 
    856 .. ts:def:: CoinPurseDepositTransaction
    857 
    858   interface CoinPurseDepositTransaction {
    859     type: "PURSE-DEPOSIT";
    860 
    861     // Offset of this entry in the reserve history.
    862     // Useful to request incremental histories via
    863     // the "start" query parameter.
    864     history_offset: Integer;
    865 
    866     // The total amount of the coin's value absorbed
    867     // by this transaction.
    868     // Note that this means the amount given includes
    869     // the deposit fee. The current coin value can thus be computed by
    870     // subtracting the amount from
    871     // the coin's denomination value.
    872     amount: Amount;
    873 
    874     // Base URL of the exchange the purse lives at.
    875     exchange_base_url: string;
    876 
    877     // The hash of the age-commitment for the coin. Only present
    878     // if the denomination has support for age restriction.
    879     h_age_commitment?: AgeCommitmentHash;
    880 
    881     // Deposit fee.
    882     deposit_fee: Amount;
    883 
    884     // Public key of the purse.
    885     purse_pub: EddsaPublicKey;
    886 
    887     // True if the deposit was refunded for any reason.
    888     refunded: boolean;
    889 
    890     // Signature by the coin over a
    891     // `TALER_PurseDepositSignaturePS` of
    892     // purpose ``TALER_SIGNATURE_PURSE_DEPOSIT``.
    893     coin_sig: EddsaSignature;
    894 
    895     // Hash of the public denomination key used to sign the coin.
    896     // Needed because 'coin_sig' signs over this, and
    897     // that is important to fix the coin's denomination.
    898     h_denom_pub: HashCode;
    899 
    900   }
    901 
    902 .. ts:def:: CoinPurseRefundTransaction
    903 
    904   interface CoinPurseRefundTransaction {
    905     type: "PURSE-REFUND";
    906 
    907     // Offset of this entry in the reserve history.
    908     // Useful to request incremental histories via
    909     // the "start" query parameter.
    910     history_offset: Integer;
    911 
    912     // The total amount of the coin's value restored
    913     // by this transaction.
    914     // The amount given excludes the refund fee.
    915     // The current coin value can thus be computed by
    916     // adding the amount to the coin's denomination value.
    917     amount: Amount;
    918 
    919     // Refund fee (of the coin's denomination). The deposit
    920     // fee will be waived.
    921     refund_fee: Amount;
    922 
    923     // Signature by the exchange over a
    924     // ``TALER_CoinPurseRefundConfirmationPS``
    925     // of purpose ``TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND``.
    926     exchange_sig: EddsaSignature;
    927 
    928     // Public key used to sign 'exchange_sig'.
    929     exchange_pub: EddsaPublicKey;
    930 
    931     // Public key of the purse that expired.
    932     purse_pub: EddsaPublicKey;
    933 
    934   }
    935 
    936 .. ts:def:: CoinReserveOpenDepositTransaction
    937 
    938   interface CoinReserveOpenDepositTransaction {
    939     type: "RESERVE-OPEN-DEPOSIT";
    940 
    941     // Offset of this entry in the reserve history.
    942     // Useful to request incremental histories via
    943     // the "start" query parameter.
    944     history_offset: Integer;
    945 
    946     // The total amount of the coin's value absorbed
    947     // by this transaction.
    948     // Note that this means the amount given includes
    949     // the deposit fee.
    950     coin_contribution: Amount;
    951 
    952     // Signature of the reserve open operation being paid for.
    953     reserve_sig: EddsaSignature;
    954 
    955     // Signature by the coin over a
    956     // `TALER_ReserveOpenDepositSignaturePS` of
    957     // purpose ``TALER_SIGNATURE_RESERVE_OPEN_DEPOSIT``.
    958     coin_sig: EddsaSignature;
    959 
    960   }
    961 
    962 
    963 -----------------------
    964 Tracking wire transfers
    965 -----------------------
    966 
    967 This API is used by merchants that need to find out which wire
    968 transfers (from the exchange to the merchant) correspond to which deposit
    969 operations.  Typically, a merchant will receive a wire transfer with a
    970 **wire transfer identifier** and want to know the set of deposit
    971 operations that correspond to this wire transfer.  This is the
    972 preferred query that merchants should make for each wire transfer they
    973 receive.  If a merchant needs to investigate a specific deposit
    974 operation (i.e. because it seems that it was not paid), then the
    975 merchant can also request the wire transfer identifier for a deposit
    976 operation.
    977 
    978 Sufficient information is returned to verify that the coin signatures
    979 are correct. This also allows governments to use this API when doing
    980 a tax audit on merchants.
    981 
    982 Naturally, the returned information may be sensitive for the merchant.
    983 We do not require the merchant to sign the request, as the same requests
    984 may also be performed by the government auditing a merchant.
    985 However, wire transfer identifiers should have sufficient entropy to
    986 ensure that obtaining a successful reply by brute-force is not practical.
    987 Nevertheless, the merchant should protect the wire transfer identifiers
    988 from his bank statements against unauthorized access, lest his income
    989 situation is revealed to an adversary. (This is not a major issue, as
    990 an adversary that has access to the line-items of bank statements can
    991 typically also view the balance.)
    992 
    993 
    994 .. include:: exchange/get-transfers-WTID.rst
    995 
    996 .. include:: exchange/get-deposits-H_WIRE-MERCHANT_PUB-H_CONTRACT_TERMS-COIN_PUB.rst
    997 
    998 
    999 .. _exchange_w2w:
   1000 
   1001 --------------------------
   1002 Wallet-to-wallet transfers
   1003 --------------------------
   1004 
   1005 .. include:: exchange/get-purses-PURSE_PUB-merge.rst
   1006 
   1007 .. include:: exchange/post-purses-PURSE_PUB-create.rst
   1008 
   1009 .. include:: exchange/delete-purses-PURSE_PUB.rst
   1010 
   1011 .. include:: exchange/post-purses-PURSE_PUB-merge.rst
   1012 
   1013 .. include:: exchange/post-reserves-RESERVE_PUB-purse.rst
   1014 
   1015 .. include:: exchange/get-contracts-CONTRACT_PUB.rst
   1016 
   1017 .. include:: exchange/post-purses-PURSE_PUB-deposit.rst
   1018 
   1019 
   1020 .. _exchange_wads:
   1021 
   1022 ----
   1023 Wads
   1024 ----
   1025 
   1026   .. note::
   1027 
   1028      This is a draft API that is not yet implemented.
   1029 
   1030 
   1031 These endpoints are used to manage exchange-to-exchange payments in support of
   1032 wallet-to-wallet payments.  Only another exchange should access this endpoint.
   1033 
   1034 
   1035 .. include:: exchange/get-wads-WAD_ID.rst
   1036 
   1037 
   1038 ------------------
   1039 KYC status updates
   1040 ------------------
   1041 
   1042 This section describes endpoints used to set up, complete and
   1043 inquire about KYC operations performed by an exchange for
   1044 regulatory compliance.
   1045 
   1046 .. include:: exchange/post-kyc-wallet.rst
   1047 
   1048 .. include:: exchange/get-kyc-check-H_NORMALIZED_PAYTO.rst
   1049 
   1050 .. include:: exchange/get-kyc-spa-ACCESS_TOKEN.rst
   1051 
   1052 .. include:: exchange/get-kyc-info-ACCESS_TOKEN.rst
   1053 
   1054 .. include:: exchange/post-kyc-upload-ID.rst
   1055 
   1056 .. include:: exchange/post-kyc-start-ID.rst
   1057 
   1058 .. include:: exchange/get-kyc-proof-PROVIDER_NAME.rst
   1059 
   1060 .. include:: exchange/get-kyc-webhook-PROVIDER_NAME-star.rst
   1061 
   1062 
   1063 --------------
   1064 AML operations
   1065 --------------
   1066 
   1067 This API is only for designated AML officers. It is used
   1068 to allow exchange staff to monitor suspicious transactions
   1069 and freeze or unfreeze accounts suspected of money laundering.
   1070 
   1071 .. include:: exchange/get-aml-OFFICER_PUB-measures.rst
   1072 
   1073 .. include:: exchange/get-aml-OFFICER_PUB-kyc-statistics-NAMES.rst
   1074 
   1075 .. include:: exchange/get-aml-OFFICER_PUB-decisions.rst
   1076 
   1077 .. include:: exchange/get-aml-OFFICER_PUB-legitimizations.rst
   1078 
   1079 .. include:: exchange/get-aml-OFFICER_PUB-accounts.rst
   1080 
   1081 .. include:: exchange/get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.rst
   1082 
   1083 .. include:: exchange/post-aml-OFFICER_PUB-decision.rst
   1084 
   1085 .. include:: exchange/get-aml-OFFICER_PUB-transfers-credit.rst
   1086 
   1087 ---------------
   1088 Reserve control
   1089 ---------------
   1090 
   1091 This section describes the reserve control API which can be used to (1)
   1092 prevent a reserve from expiring, to (2) pay an annual fee to allow a number of
   1093 purses to be created for the respective reserve without paying a purse fee
   1094 each time, to (3) obtain KYC information associated with a reserve to prove
   1095 the identity of the person sending an invoice to the payer, and to (4) close a
   1096 reserve before it would naturally expire and possibly (5) wire the funds to a
   1097 designated account.
   1098 
   1099   .. note::
   1100 
   1101      This section is about a proposed API. It is not implemented. See also DD 31.
   1102 
   1103 .. include:: exchange/post-reserves-RESERVE_PUB-open.rst
   1104 
   1105 .. include:: exchange/get-reserves-RESERVE_PUB-attest.rst
   1106 
   1107 .. include:: exchange/post-reserves-RESERVE_PUB-attest.rst
   1108 
   1109 .. include:: exchange/post-reserves-RESERVE_PUB-close.rst
   1110 
   1111 .. _delete-reserve:
   1112 
   1113 .. include:: exchange/delete-reserves-RESERVE_PUB.rst