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