taler-docs

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

api-exchange.rst (18670B)


      1 ..
      2   This file is part of GNU TALER.
      3   Copyright (C) 2014-2026 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 currently implemented protocol version is **v35**.
     34 
     35 * Wallet-core is currently targeting **vXX**.
     36 * The merchant is currently targeting **v34**.
     37 * The AML SPA is currently targeting **v31**.
     38 * The KYC SPA is currently targeting **v30**.
     39 
     40 **Version history:**
     41 
     42 * ``v29``: AML reporting on KYC auth transfers
     43 * ``v30``: various minor feature additions
     44 * ``v31``: improvements for AML reporting
     45 * ``v32``: support for extra_wire_subject_metadata
     46 * ``v33``: addition of accumulated_total_without_fee in ``/batch-deposit``
     47 * ``v34``: new offline signature; support for open_banking_gateway and
     48            prepared_transfer_url per wire account in ``/keys``
     49 * ``v35``: adds ``default_p2p_push_expiration`` to ``/keys``
     50 * ``v36``: adds ``kyc_swap_tos_acceptance`` to ``/keys``
     51 
     52 **Upcoming versions:**
     53 
     54 * ``vRECOUP``: improved recoup protocol
     55 * ``vATTEST``: KYC attestation support
     56 * ``vIMPORT``: external KYC/KYB data import
     57 
     58 **Ideas for future version:**
     59 
     60 * ``vXXX``: marker for features not yet targeted for release
     61 
     62 .. include:: tos.rst
     63 
     64 .. _keys:
     65 
     66 ---------------------------
     67 Exchange status information
     68 ---------------------------
     69 
     70 This API is used by wallets and merchants to obtain global information about
     71 the exchange, such as online signing keys, available denominations and the fee
     72 structure.  This is typically the first call any exchange client makes, as it
     73 returns information required to process all of the other interactions with the
     74 exchange.  The returned information is secured by (1) signature(s) from the exchange,
     75 especially the long-term offline signing key of the exchange, which clients should
     76 cache; (2) signature(s) from auditors, and the auditor keys should be
     77 hard-coded into the wallet as they are the trust anchors for Taler; (3)
     78 possibly by using HTTPS.
     79 
     80 
     81 .. include:: exchange/get-seed.rst
     82 
     83 .. include:: exchange/get-config.rst
     84 
     85 .. include:: exchange/get-keys.rst
     86 
     87 
     88 ----------------------------------------------
     89 Management operations authorized by master key
     90 ----------------------------------------------
     91 
     92 .. include:: exchange/get-management-keys.rst
     93 
     94 .. include:: exchange/post-management-keys.rst
     95 
     96 .. include:: exchange/post-management-denominations-H_DENOM_PUB-revoke.rst
     97 
     98 .. include:: exchange/post-management-signkeys-EXCHANGE_PUB-revoke.rst
     99 
    100 .. include:: exchange/post-management-auditors.rst
    101 
    102 .. include:: exchange/post-management-auditors-AUDITOR_PUB-disable.rst
    103 
    104 .. include:: exchange/post-management-wire-fee.rst
    105 
    106 .. include:: exchange/post-management-global-fees.rst
    107 
    108 .. include:: exchange/post-management-wire.rst
    109 
    110 .. include:: exchange/post-management-wire-disable.rst
    111 
    112 .. include:: exchange/post-management-drain.rst
    113 
    114 .. include:: exchange/post-management-aml-officers.rst
    115 
    116 .. include:: exchange/post-management-partners.rst
    117 
    118 ---------------
    119 Auditor actions
    120 ---------------
    121 
    122 .. _auditor_action:
    123 
    124 This part of the API is for the use by auditors interacting with the exchange.
    125 
    126 .. include:: exchange/post-auditors-AUDITOR_PUB-H_DENOM_PUB.rst
    127 
    128 
    129 ----------------
    130 Blinding Prepare
    131 ----------------
    132 
    133 Certain denomination cipher types, such as Clause-Schnorr, require input values
    134 from the exchange-side as preparation for the blinding of the coins.  See the
    135 Bachelor thesis of Gian Demarmels and Lucien Heuzeveldt,
    136 `Adding Schnorr’s Blind Signature in Taler <https://www.taler.net/papers/cs-thesis.pdf>`_,
    137 for details.
    138 
    139 .. include:: exchange/post-blinding-prepare.rst
    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 Refreshing
    327 ----------
    328 
    329 Refreshing exchanges one old coin against ``n`` new coins, where the sum of
    330 denominations of the new coins must be smaller than the old coin's
    331 denomination plus melting (refresh) and withdrawal fees charged by the exchange.
    332 The refreshing API can be used by wallets to melt partially spent coins, making
    333 transactions with the freshly exchangeed coins unlinkabe to previous transactions
    334 by anyone except the wallet itself.
    335 
    336 Refreshing is a two-step process, consisting of
    337 
    338 1. the **melting** of the old coin, together with ``kappa`` batches
    339    of blinded planchets candidates,
    340 2. the **reveal** of ``kappa-1`` secrets to prove the proper construction
    341    of the (revealed) batches of blinded planchets candidates.
    342 
    343 
    344 ^^^^
    345 Melt
    346 ^^^^
    347 
    348 .. _melt:
    349 .. include:: exchange/post-melt.rst
    350 
    351 ^^^^^^^^^^^
    352 Reveal-Melt
    353 ^^^^^^^^^^^
    354 
    355 This endpoint is called by the client after a call to `melt`_.
    356 Now the client has to disclose --for each coin--
    357 all but one of the κ secrets that went into creating the blinded coin's planchets,
    358 the transfer public keys (linking the ownership of the old and new coin),
    359 and the commitment to age restriction,
    360 as proof that the age restriction was set correctly (if applicable).
    361 
    362 .. include:: exchange/post-reveal-melt.rst
    363 
    364 
    365 .. _deposit-par:
    366 
    367 -------
    368 Deposit
    369 -------
    370 
    371 Deposit operations are requested f.e. by a merchant during a transaction or a
    372 bidder during an auction.
    373 
    374 For the deposit operation during purchase, the merchant has to obtain the
    375 deposit permission for a coin from their customer who owns the coin.  When
    376 depositing a coin, the merchant is credited an amount specified in the deposit
    377 permission, possibly a fraction of the total coin's value, minus the deposit
    378 fee as specified by the coin's denomination.
    379 
    380 For auctions, a bidder performs an deposit operation and provides all relevant
    381 information for the auction policy (such as timeout and public key as bidder)
    382 and can use the ``exchange_sig`` field from the `DepositSuccessResponse`
    383 message as a proof to the seller for the escrow of sufficient fund.
    384 
    385 
    386 .. _deposit:
    387 
    388 .. include:: exchange/post-batch-deposit.rst
    389 
    390 
    391 ------
    392 Recoup
    393 ------
    394 
    395 The purpose of this API is to allow coins to be cashed back in,
    396 in certain exceptional situations.
    397 This API is only used if the exchange is either about to go out of
    398 business or has had its private signing keys compromised (so in
    399 either case, the protocol is only used in **abnormal**
    400 situations).  In the above cases, the exchange signals to the
    401 wallets that the emergency cash back protocol has been activated
    402 by putting the affected denomination keys into the cash-back
    403 part of the ``/keys`` response.  If and only if this has happened,
    404 coins that were signed with those denomination keys can be cashed
    405 in using this API.
    406 
    407 For a recoup, a coin has to provide the necessary information to
    408 identify the original transaction (either a withdraw or a refresh) it
    409 became minted, and proof ownership of the coin itself.
    410 
    411 
    412 .. include:: exchange/post-recoup-withdraw.rst
    413 
    414 .. include:: exchange/post-recoup-refresh.rst
    415 
    416 
    417 .. _exchange_refund:
    418 
    419 -------
    420 Refunds
    421 -------
    422 
    423 .. include:: exchange/post-coins-COIN_PUB-refund.rst
    424 
    425 .. _reserve-history:
    426 
    427 ---------------
    428 Reserve History
    429 ---------------
    430 
    431 .. include:: exchange/get-reserves-RESERVE_PUB-history.rst
    432 
    433 
    434 .. _coin-history:
    435 
    436 ------------
    437 Coin History
    438 ------------
    439 
    440 .. include:: exchange/get-coins-COIN_PUB-history.rst
    441 
    442 -----------------------
    443 Tracking wire transfers
    444 -----------------------
    445 
    446 This API is used by merchants that need to find out which wire
    447 transfers (from the exchange to the merchant) correspond to which deposit
    448 operations.  Typically, a merchant will receive a wire transfer with a
    449 **wire transfer identifier** and want to know the set of deposit
    450 operations that correspond to this wire transfer.  This is the
    451 preferred query that merchants should make for each wire transfer they
    452 receive.  If a merchant needs to investigate a specific deposit
    453 operation (i.e. because it seems that it was not paid), then the
    454 merchant can also request the wire transfer identifier for a deposit
    455 operation.
    456 
    457 Sufficient information is returned to verify that the coin signatures
    458 are correct. This also allows governments to use this API when doing
    459 a tax audit on merchants.
    460 
    461 Naturally, the returned information may be sensitive for the merchant.
    462 We do not require the merchant to sign the request, as the same requests
    463 may also be performed by the government auditing a merchant.
    464 However, wire transfer identifiers should have sufficient entropy to
    465 ensure that obtaining a successful reply by brute-force is not practical.
    466 Nevertheless, the merchant should protect the wire transfer identifiers
    467 from his bank statements against unauthorized access, lest his income
    468 situation is revealed to an adversary. (This is not a major issue, as
    469 an adversary that has access to the line-items of bank statements can
    470 typically also view the balance.)
    471 
    472 
    473 .. include:: exchange/get-transfers-WTID.rst
    474 
    475 .. include:: exchange/get-deposits-H_WIRE-MERCHANT_PUB-H_CONTRACT_TERMS-COIN_PUB.rst
    476 
    477 
    478 .. _exchange_w2w:
    479 
    480 --------------------------
    481 Wallet-to-wallet transfers
    482 --------------------------
    483 
    484 .. include:: exchange/get-purses-PURSE_PUB-merge.rst
    485 
    486 .. include:: exchange/post-purses-PURSE_PUB-create.rst
    487 
    488 .. include:: exchange/delete-purses-PURSE_PUB.rst
    489 
    490 .. include:: exchange/post-purses-PURSE_PUB-merge.rst
    491 
    492 .. include:: exchange/post-reserves-RESERVE_PUB-purse.rst
    493 
    494 .. include:: exchange/get-contracts-CONTRACT_PUB.rst
    495 
    496 .. include:: exchange/post-purses-PURSE_PUB-deposit.rst
    497 
    498 
    499 .. _exchange_wads:
    500 
    501 ----
    502 Wads
    503 ----
    504 
    505   .. note::
    506 
    507      This is a draft API that is not yet implemented.
    508 
    509 
    510 These endpoints are used to manage exchange-to-exchange payments in support of
    511 wallet-to-wallet payments.  Only another exchange should access this endpoint.
    512 
    513 
    514 .. include:: exchange/get-wads-WAD_ID.rst
    515 
    516 
    517 ------------------
    518 KYC status updates
    519 ------------------
    520 
    521 This section describes endpoints used to set up, complete and
    522 inquire about KYC operations performed by an exchange for
    523 regulatory compliance.
    524 
    525 .. include:: exchange/post-kyc-wallet.rst
    526 
    527 .. include:: exchange/get-kyc-check-H_NORMALIZED_PAYTO.rst
    528 
    529 .. include:: exchange/get-kyc-spa-ACCESS_TOKEN.rst
    530 
    531 .. include:: exchange/get-kyc-info-ACCESS_TOKEN.rst
    532 
    533 .. include:: exchange/post-kyc-upload-ID.rst
    534 
    535 .. include:: exchange/post-kyc-start-ID.rst
    536 
    537 .. include:: exchange/post-kyc-import-EXTERN_PUB.rst
    538 
    539 .. include:: exchange/post-kyc-bulk-EXTERN_PUB.rst
    540 
    541 .. include:: exchange/get-kyc-proof-PROVIDER_NAME.rst
    542 
    543 .. include:: exchange/get-kyc-webhook-PROVIDER_NAME-star.rst
    544 
    545 
    546 --------------
    547 AML operations
    548 --------------
    549 
    550 This API is only for designated AML officers. It is used
    551 to allow exchange staff to monitor suspicious transactions
    552 and freeze or unfreeze accounts suspected of money laundering.
    553 
    554 .. include:: exchange/get-aml-OFFICER_PUB-measures.rst
    555 
    556 .. include:: exchange/get-aml-OFFICER_PUB-kyc-statistics-NAMES.rst
    557 
    558 .. include:: exchange/get-aml-OFFICER_PUB-decisions.rst
    559 
    560 .. include:: exchange/get-aml-OFFICER_PUB-legitimizations.rst
    561 
    562 .. include:: exchange/get-aml-OFFICER_PUB-accounts.rst
    563 
    564 .. include:: exchange/get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.rst
    565 
    566 .. include:: exchange/post-aml-OFFICER_PUB-decision.rst
    567 
    568 .. include:: exchange/get-aml-OFFICER_PUB-transfers-credit.rst
    569 
    570 ---------------
    571 Reserve control
    572 ---------------
    573 
    574 This section describes the reserve control API which can be used to (1)
    575 prevent a reserve from expiring, to (2) pay an annual fee to allow a number of
    576 purses to be created for the respective reserve without paying a purse fee
    577 each time, to (3) obtain KYC information associated with a reserve to prove
    578 the identity of the person sending an invoice to the payer, and to (4) close a
    579 reserve before it would naturally expire and possibly (5) wire the funds to a
    580 designated account.
    581 
    582   .. note::
    583 
    584      This section is about a proposed API. It is not implemented. See also DD 31.
    585 
    586 .. include:: exchange/post-reserves-RESERVE_PUB-open.rst
    587 
    588 .. include:: exchange/get-reserves-RESERVE_PUB-attest.rst
    589 
    590 .. include:: exchange/post-reserves-RESERVE_PUB-attest.rst
    591 
    592 .. include:: exchange/post-reserves-RESERVE_PUB-close.rst
    593 
    594 .. _delete-reserve:
    595 
    596 .. include:: exchange/delete-reserves-RESERVE_PUB.rst