taler-docs

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

api-exchange.rst (19107B)


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