taler-docs

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

api-exchange.rst (19496B)


      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 3.0, 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 **v41**.
     34 
     35 * Wallet-core is currently targeting **vXX**.
     36 * The merchant is currently targeting **v34**.
     37 * The AML SPA is currently targeting **v41**.
     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 :http:post:`/batch-deposit </batch-deposit>`
     47 * ``v34``: new offline signature; support for open_banking_gateway and
     48            prepared_transfer_url per wire account in :http:get:`/keys </keys>`
     49 * ``v35``: adds ``default_p2p_push_expiration`` to :http:get:`/keys </keys>`
     50 * ``v36``: adds ``kyc_swap_tos_acceptance`` to :http:get:`/keys </keys>`
     51 * ``v37``: adds :http:get:`/aml/$OFFICER_PUB/wallet-credit </aml/$OFFICER_PUB/wallet-credit>` endpoint
     52 * ``v38``: adds ``build_version`` to :http:get:`/config </config>`
     53 * ``v39``: adds ``exchange_payto_uri`` to
     54            :http:get:`/transfers/$WTID </transfers/$WTID>`
     55 * ``v40``: adds :http:get:`/aml/$OFFICER_PUB </aml/$OFFICER_PUB>` to report
     56            the authenticated AML officer's name and access level
     57 * ``v41``: adds :http:post:`/aml/$OFFICER_PUB/render-form </aml/$OFFICER_PUB/render-form>`
     58            to preview filled AML/KYC forms as PDF
     59 
     60 **Upcoming versions:**
     61 
     62 * ``vIMPORT``: external KYC/KYB data import
     63 * ``vRECOUP``: improved recoup protocol
     64 * ``vATTEST``: KYC attestation support
     65 
     66 **Ideas for future version:**
     67 
     68 * ``vXXX``: marker for features not yet targeted for release
     69 
     70 .. include:: tos.rst
     71 
     72 .. _keys:
     73 
     74 ---------------------------
     75 Exchange status information
     76 ---------------------------
     77 
     78 This API is used by wallets and merchants to obtain global information about
     79 the exchange, such as online signing keys, available denominations and the fee
     80 structure.  This is typically the first call any exchange client makes, as it
     81 returns information required to process all of the other interactions with the
     82 exchange.  The returned information is secured by (1) signature(s) from the exchange,
     83 especially the long-term offline signing key of the exchange, which clients should
     84 cache; (2) signature(s) from auditors, and the auditor keys should be
     85 hard-coded into the wallet as they are the trust anchors for Taler; (3)
     86 possibly by using HTTPS.
     87 
     88 
     89 .. include:: exchange/get-seed.rst
     90 
     91 .. include:: exchange/get-config.rst
     92 
     93 .. include:: exchange/get-keys.rst
     94 
     95 
     96 ----------------------------------------------
     97 Management operations authorized by master key
     98 ----------------------------------------------
     99 
    100 .. include:: exchange/get-management-keys.rst
    101 
    102 .. include:: exchange/post-management-keys.rst
    103 
    104 .. include:: exchange/post-management-denominations-H_DENOM_PUB-revoke.rst
    105 
    106 .. include:: exchange/post-management-signkeys-EXCHANGE_PUB-revoke.rst
    107 
    108 .. include:: exchange/post-management-auditors.rst
    109 
    110 .. include:: exchange/post-management-auditors-AUDITOR_PUB-disable.rst
    111 
    112 .. include:: exchange/post-management-wire-fee.rst
    113 
    114 .. include:: exchange/post-management-global-fees.rst
    115 
    116 .. include:: exchange/post-management-wire.rst
    117 
    118 .. include:: exchange/post-management-wire-disable.rst
    119 
    120 .. include:: exchange/post-management-drain.rst
    121 
    122 .. include:: exchange/post-management-aml-officers.rst
    123 
    124 .. include:: exchange/post-management-partners.rst
    125 
    126 ---------------
    127 Auditor actions
    128 ---------------
    129 
    130 .. _auditor_action:
    131 
    132 This part of the API is for the use by auditors interacting with the exchange.
    133 
    134 .. include:: exchange/post-auditors-AUDITOR_PUB-H_DENOM_PUB.rst
    135 
    136 
    137 ----------------
    138 Blinding Prepare
    139 ----------------
    140 
    141 Certain denomination cipher types, such as Clause-Schnorr, require input values
    142 from the exchange-side as preparation for the blinding of the coins.  See the
    143 Bachelor thesis of Gian Demarmels and Lucien Heuzeveldt,
    144 `Adding Schnorr’s Blind Signature in Taler <https://www.taler.net/papers/cs-thesis.pdf>`_,
    145 for details.
    146 
    147 .. include:: exchange/post-blinding-prepare.rst
    148 
    149 
    150 .. _exchange-withdrawal:
    151 
    152 ----------
    153 Withdrawal
    154 ----------
    155 
    156 This API is used by the wallet to obtain digital coins.
    157 
    158 When transferring money to the exchange such as via SEPA transfers, the exchange creates
    159 a *reserve*, which keeps the money from the customer.  The customer must
    160 specify an EdDSA reserve public key as part of the transfer, and can then
    161 withdraw digital coins using the corresponding private key.  All incoming and
    162 outgoing transactions are recorded under the corresponding public key by the
    163 exchange.
    164 
    165 .. note::
    166 
    167    Eventually the exchange will need to advertise a policy for how long it will
    168    keep transaction histories for inactive or even fully drained reserves.  We
    169    will therefore need some additional handler similar to :http:get:`/keys </keys>` to
    170    advertise those terms of service.
    171 
    172 
    173 .. include:: exchange/get-reserves-RESERVE_PUB.rst
    174 
    175 .. _withdraw:
    176 .. include:: exchange/post-withdraw.rst
    177 
    178 
    179 .. ts:def:: WithdrawRequest
    180 
    181   interface WithdrawRequest {
    182     // Cipher that is used for the rerserve's signatures.
    183     // For now, only ed25519 signatures are applicable,
    184     // but this might change in future versions.
    185     cipher: "ED25519";
    186 
    187     // The reserve's public key, for the the cipher ED25519,
    188     // to verify the signature ``reserve_sig``.
    189     reserve_pub: EddsaPublicKey;
    190 
    191     // Array of ``n`` hash codes of denomination public keys to order.
    192     // The sum of all denomination's values and fees MUST be
    193     // at most the balance of the reserve. The balance of
    194     // the reserve will be immediatley reduced by that amount.
    195     // If ``max_age`` is set, these denominations MUST support
    196     // age restriction as defined in the output to /keys.
    197     denoms_h: HashCode[];
    198 
    199     // If set, the maximum age to commit to. This implies:
    200     // 1.) it MUST be the same value as the maximum age
    201     //     of the reserve.
    202     // 2.) ``coin_evs`` MUST be an array of ``n*kappa``
    203     // 3.) the denominations in ``denoms_h`` MUST support
    204     //      age restriction.
    205     max_age?: Integer;
    206 
    207     // Master seed for the Clause-Schnorr R-value creation.
    208     // MUST match the /blinding-prepare request.
    209     // MUST NOT have been used in any prior withdraw request.
    210     // MUST be present if one of the fresh coin's
    211     // denomination is of type Clause-Schnorr.
    212     blinding_seed?: BlindingMasterSeed;
    213 
    214     // Array of blinded coin envelopes of type `CoinEnvelope`.
    215     // If ``max_age`` is not set, MUST be n entries.
    216     // If ``max_age`` is set, MUST be ``n*kappa`` entries,
    217     // arranged in [0..n)..[0..n), with the first n entries
    218     // belonging to kappa=0 etc.
    219     // In case of age restriction, the exchange will
    220     // respond with an index ``gamma``, which is the index
    221     // that shall remain undisclosed during the subsequent
    222     // reveal phase.
    223     // This hash value along with the reserve's public key
    224     // will also be used for recoup operations, if needed.
    225     coin_evs:  CoinEnvelope[];
    226 
    227     // Signature of `TALER_WithdrawRequestPS` created with
    228     // the `reserves's private key <reserve-priv>`.
    229     reserve_sig: EddsaSignature;
    230   }
    231 
    232 .. ts:def:: WithdrawResponse
    233 
    234   interface WithdrawResponse {
    235     // Array of blinded signatures over each ``coin_evs``,
    236     // in the same order as was given in the request.
    237     // The blinded signatures affirm the coin's validity
    238     // after unblinding.
    239     ev_sigs: BlindedDenominationSignature[];
    240 
    241   }
    242 
    243 
    244 .. ts:def:: AgeWithdrawResponse
    245 
    246   interface AgeWithdrawResponse {
    247     // index of the commitments that the client doesn't
    248     // have to disclose in the subsequent call to
    249     // ``/reveal-withdraw``.
    250     noreveal_index: Integer;
    251 
    252     // Signature of `TALER_WithdrawConfirmationPS` whereby
    253     // the exchange confirms the ``noreveal_index``.
    254     exchange_sig: EddsaSignature;
    255 
    256     // `Public EdDSA key <sign-key-pub>` of the exchange that was used to
    257     // generate the signature.  Should match one of the exchange's signing
    258     // keys from ``/keys``.  Again given explicitly as the client might
    259     // otherwise be confused by clock skew as to which signing key was used.
    260     exchange_pub: EddsaPublicKey;
    261 
    262   }
    263 
    264 .. ts:def:: DenominationGoneMessage
    265 
    266   interface DenominationGoneMessage {
    267 
    268     // Taler error code.  Note that beyond
    269     // expiration this message format is also
    270     // used if the key is not yet valid, or
    271     // has been revoked. May be one of
    272     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_VALIDITY_IN_FUTURE``
    273     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_EXPIRED``
    274     // - ``TALER_EC_EXCHANGE_GENERIC_DENOMINATION_REVOKED``
    275     code: Integer;
    276 
    277     // Signature by the exchange over a
    278     // `TALER_DenominationExpiredAffirmationPS`.
    279     // Must have purpose ``TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED``.
    280     exchange_sig: EddsaSignature;
    281 
    282     // Public key of the exchange used to create
    283     // the 'exchange_sig.
    284     exchange_pub: EddsaPublicKey;
    285 
    286     // Hash of the denomination public key that is unknown.
    287     h_denom_pub: HashCode;
    288 
    289     // When was the signature created.
    290     timestamp: Timestamp;
    291 
    292     // What kind of operation was requested that now
    293     // failed?
    294     oper: string;
    295 
    296   }
    297 
    298 
    299 .. ts:def:: WithdrawError
    300 
    301   interface SingleWithdrawError {
    302     // Text describing the error.
    303     hint: string;
    304 
    305     // Detailed error code.
    306     code: Integer;
    307 
    308     // Amount left in the reserve.
    309     balance: Amount;
    310 
    311   }
    312 
    313 
    314 
    315 ------------------
    316 
    317 
    318 .. _reveal-withdraw:
    319 
    320 **Reveal-Withdraw**
    321 
    322 This endpoint is called by the client after a call to `withdraw`_,
    323 *if* the original request had ``max_age`` set and
    324 the response was of type `AgeWithdrawResponse`.
    325 Now the client has to disclose for each coin all but one of the κ secrets
    326 that went into creating the blinded coin's planchets,
    327 including the commitment to age restriction,
    328 and prove that the age restriction was set correctly.
    329 
    330 .. include:: exchange/post-reveal-withdraw.rst
    331 
    332 
    333 ----------
    334 Refreshing
    335 ----------
    336 
    337 Refreshing exchanges one old coin against ``n`` new coins, where the sum of
    338 denominations of the new coins must be smaller than the old coin's
    339 denomination plus melting (refresh) and withdrawal fees charged by the exchange.
    340 The refreshing API can be used by wallets to melt partially spent coins, making
    341 transactions with the freshly exchanged coins unlinkable to previous transactions
    342 by anyone except the wallet itself.
    343 
    344 Refreshing is a two-step process, consisting of
    345 
    346 1. the **melting** of the old coin, together with ``kappa`` batches
    347    of blinded planchets candidates,
    348 2. the **reveal** of ``kappa-1`` secrets to prove the proper construction
    349    of the (revealed) batches of blinded planchets candidates.
    350 
    351 
    352 ^^^^
    353 Melt
    354 ^^^^
    355 
    356 .. _melt:
    357 .. include:: exchange/post-melt.rst
    358 
    359 ^^^^^^^^^^^
    360 Reveal-Melt
    361 ^^^^^^^^^^^
    362 
    363 This endpoint is called by the client after a call to `melt`_.
    364 Now the client has to disclose --for each coin--
    365 all but one of the κ secrets that went into creating the blinded coin's planchets,
    366 the transfer public keys (linking the ownership of the old and new coin),
    367 and the commitment to age restriction,
    368 as proof that the age restriction was set correctly (if applicable).
    369 
    370 .. include:: exchange/post-reveal-melt.rst
    371 
    372 
    373 .. _deposit-par:
    374 
    375 -------
    376 Deposit
    377 -------
    378 
    379 Deposit operations are requested f.e. by a merchant during a transaction or a
    380 bidder during an auction.
    381 
    382 For the deposit operation during purchase, the merchant has to obtain the
    383 deposit permission for a coin from their customer who owns the coin.  When
    384 depositing a coin, the merchant is credited an amount specified in the deposit
    385 permission, possibly a fraction of the total coin's value, minus the deposit
    386 fee as specified by the coin's denomination.
    387 
    388 For auctions, a bidder performs a deposit operation and provides all relevant
    389 information for the auction policy (such as timeout and public key as bidder)
    390 and can use the ``exchange_sig`` field from the `DepositSuccessResponse`
    391 message as a proof to the seller for the escrow of sufficient fund.
    392 
    393 
    394 .. _deposit:
    395 
    396 .. include:: exchange/post-batch-deposit.rst
    397 
    398 
    399 ------
    400 Recoup
    401 ------
    402 
    403 The purpose of this API is to allow coins to be cashed back in,
    404 in certain exceptional situations.
    405 This API is only used if the exchange is either about to go out of
    406 business or has had its private signing keys compromised (so in
    407 either case, the protocol is only used in **abnormal**
    408 situations).  In the above cases, the exchange signals to the
    409 wallets that the emergency cash back protocol has been activated
    410 by putting the affected denomination keys into the cash-back
    411 part of the :http:get:`/keys </keys>` response.  If and only if this has happened,
    412 coins that were signed with those denomination keys can be cashed
    413 in using this API.
    414 
    415 For a recoup, a coin has to provide the necessary information to
    416 identify the original transaction (either a withdraw or a refresh) it
    417 became minted, and prove ownership of the coin itself.
    418 
    419 
    420 .. include:: exchange/post-recoup-withdraw.rst
    421 
    422 .. include:: exchange/post-recoup-refresh.rst
    423 
    424 
    425 .. _exchange_refund:
    426 
    427 -------
    428 Refunds
    429 -------
    430 
    431 .. include:: exchange/post-coins-COIN_PUB-refund.rst
    432 
    433 .. _reserve-history:
    434 
    435 ---------------
    436 Reserve History
    437 ---------------
    438 
    439 .. include:: exchange/get-reserves-RESERVE_PUB-history.rst
    440 
    441 
    442 .. _coin-history:
    443 
    444 ------------
    445 Coin History
    446 ------------
    447 
    448 .. include:: exchange/get-coins-COIN_PUB-history.rst
    449 
    450 -----------------------
    451 Tracking wire transfers
    452 -----------------------
    453 
    454 This API is used by merchants that need to find out which wire
    455 transfers (from the exchange to the merchant) correspond to which deposit
    456 operations.  Typically, a merchant will receive a wire transfer with a
    457 **wire transfer identifier** and want to know the set of deposit
    458 operations that correspond to this wire transfer.  This is the
    459 preferred query that merchants should make for each wire transfer they
    460 receive.  If a merchant needs to investigate a specific deposit
    461 operation (i.e. because it seems that it was not paid), then the
    462 merchant can also request the wire transfer identifier for a deposit
    463 operation.
    464 
    465 Sufficient information is returned to verify that the coin signatures
    466 are correct. This also allows governments to use this API when doing
    467 a tax audit on merchants.
    468 
    469 Naturally, the returned information may be sensitive for the merchant.
    470 We do not require the merchant to sign the request, as the same requests
    471 may also be performed by the government auditing a merchant.
    472 However, wire transfer identifiers should have sufficient entropy to
    473 ensure that obtaining a successful reply by brute-force is not practical.
    474 Nevertheless, the merchant should protect the wire transfer identifiers
    475 from his bank statements against unauthorized access, lest his income
    476 situation is revealed to an adversary. (This is not a major issue, as
    477 an adversary that has access to the line-items of bank statements can
    478 typically also view the balance.)
    479 
    480 
    481 .. include:: exchange/get-transfers-WTID.rst
    482 
    483 .. include:: exchange/get-deposits-H_WIRE-MERCHANT_PUB-H_CONTRACT_TERMS-COIN_PUB.rst
    484 
    485 
    486 .. _exchange_w2w:
    487 
    488 --------------------------
    489 Wallet-to-wallet transfers
    490 --------------------------
    491 
    492 .. include:: exchange/get-purses-PURSE_PUB-merge.rst
    493 
    494 .. include:: exchange/post-purses-PURSE_PUB-create.rst
    495 
    496 .. include:: exchange/delete-purses-PURSE_PUB.rst
    497 
    498 .. include:: exchange/post-purses-PURSE_PUB-merge.rst
    499 
    500 .. include:: exchange/post-reserves-RESERVE_PUB-purse.rst
    501 
    502 .. include:: exchange/get-contracts-CONTRACT_PUB.rst
    503 
    504 .. include:: exchange/post-purses-PURSE_PUB-deposit.rst
    505 
    506 
    507 .. _exchange_wads:
    508 
    509 ----
    510 Wads
    511 ----
    512 
    513   .. note::
    514 
    515      This is a draft API that is not yet implemented.
    516 
    517 
    518 These endpoints are used to manage exchange-to-exchange payments in support of
    519 wallet-to-wallet payments.  Only another exchange should access this endpoint.
    520 
    521 
    522 .. include:: exchange/get-wads-WAD_ID.rst
    523 
    524 
    525 ------------------
    526 KYC status updates
    527 ------------------
    528 
    529 This section describes endpoints used to set up, complete and
    530 inquire about KYC operations performed by an exchange for
    531 regulatory compliance.
    532 
    533 .. include:: exchange/post-kyc-wallet.rst
    534 
    535 .. include:: exchange/get-kyc-check-H_NORMALIZED_PAYTO.rst
    536 
    537 .. include:: exchange/get-kyc-spa-ACCESS_TOKEN.rst
    538 
    539 .. include:: exchange/get-kyc-info-ACCESS_TOKEN.rst
    540 
    541 .. include:: exchange/post-kyc-upload-ID.rst
    542 
    543 .. include:: exchange/post-kyc-start-ID.rst
    544 
    545 .. include:: exchange/post-kyc-import-EXTERN_PUB.rst
    546 
    547 .. include:: exchange/post-kyc-bulk-EXTERN_PUB.rst
    548 
    549 .. include:: exchange/get-kyc-proof-PROVIDER_NAME.rst
    550 
    551 .. include:: exchange/get-kyc-webhook-PROVIDER_NAME-star.rst
    552 
    553 
    554 --------------
    555 AML operations
    556 --------------
    557 
    558 This API is only for designated AML officers. It is used
    559 to allow exchange staff to monitor suspicious transactions
    560 and freeze or unfreeze accounts suspected of money laundering.
    561 
    562 .. include:: exchange/get-aml-OFFICER_PUB.rst
    563 
    564 .. include:: exchange/get-aml-OFFICER_PUB-measures.rst
    565 
    566 .. include:: exchange/get-aml-OFFICER_PUB-kyc-statistics-NAMES.rst
    567 
    568 .. include:: exchange/get-aml-OFFICER_PUB-decisions.rst
    569 
    570 .. include:: exchange/get-aml-OFFICER_PUB-legitimizations.rst
    571 
    572 .. include:: exchange/get-aml-OFFICER_PUB-accounts.rst
    573 
    574 .. include:: exchange/get-aml-OFFICER_PUB-attributes-H_NORMALIZED_PAYTO.rst
    575 
    576 .. include:: exchange/post-aml-OFFICER_PUB-render-form.rst
    577 
    578 .. include:: exchange/post-aml-OFFICER_PUB-decision.rst
    579 
    580 .. include:: exchange/get-aml-OFFICER_PUB-transfers-credit.rst
    581 
    582 .. include:: exchange/get-aml-OFFICER_PUB-wallet-credit.rst
    583 
    584 ---------------
    585 Reserve control
    586 ---------------
    587 
    588 This section describes the reserve control API which can be used to (1)
    589 prevent a reserve from expiring, to (2) pay an annual fee to allow a number of
    590 purses to be created for the respective reserve without paying a purse fee
    591 each time, to (3) obtain KYC information associated with a reserve to prove
    592 the identity of the person sending an invoice to the payer, and to (4) close a
    593 reserve before it would naturally expire and possibly (5) wire the funds to a
    594 designated account.
    595 
    596   .. note::
    597 
    598      This section is about a proposed API. It is not implemented. See also DD 31.
    599 
    600 .. include:: exchange/post-reserves-RESERVE_PUB-open.rst
    601 
    602 .. include:: exchange/get-reserves-RESERVE_PUB-attest.rst
    603 
    604 .. include:: exchange/post-reserves-RESERVE_PUB-attest.rst
    605 
    606 .. include:: exchange/post-reserves-RESERVE_PUB-close.rst
    607 
    608 .. _delete-reserve:
    609 
    610 .. include:: exchange/delete-reserves-RESERVE_PUB.rst