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