taler-docs

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

api-exchange.rst (18792B)


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