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