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