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