taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

013-peer-to-peer-payments.rst (54011B)


      1 .. _dd-13:
      2 
      3 DD 13: Wallet-to-Wallet Payments
      4 ################################
      5 
      6 :Design status: Accepted
      7 :Implementation status: Implemented
      8 :DD shepherd: TBD
      9 :Historical contributors: Florian Dold, Christian Grothoff, Sebastian
     10 :First published: 2021-01-18
     11 :Last substantive change: 2022-06-03
     12 :Implementation evidence: exchange (2022-03-20, 2022-03-24), taler-typescript-core (2022-07-12, 2022-08-23)
     13 :Normative references: :doc:`../core/api-exchange`, :doc:`../wallet/wallet-core`, :doc:`037-wallet-transactions-lifecycle`
     14 
     15 Summary
     16 =======
     17 
     18 .. note::
     19 
     20    This document includes historical protocol sketches followed by later
     21    refinements.  The current exchange and wallet APIs are authoritative.
     22 
     23 This design document proposes an extension of the Taler protocol that allows
     24 payments from wallet-to-wallet without a merchant.
     25 
     26 
     27 Motivation
     28 ==========
     29 
     30 To be usable as an electronic payment system with cash-like properties,
     31 customers should be able to transfer money between themselves without
     32 needing to setup anything beyond their wallet(s).
     33 
     34 This will be used for payments via e-mail and other messaging apps, as well as
     35 possibly for transfers via NFC/QR code between mobile phones.
     36 
     37 Invoice Flow User Experience
     38 ----------------------------
     39 
     40 .. graphviz::
     41 
     42    digraph invoice {
     43      ranksep="0.5"
     44      { rank = same; "inbox"; "begin"; }
     45      { rank = same; "sending"; "receiving2"; }
     46      { rank = same; "receiving"; "paying"; }
     47      { rank = same; "mid"; "midbox"; }
     48      { rank = same; "body"; "amount"; }
     49      begin [label="Payer Inbox",shape=box];
     50      body [label="compose\nE-mail message"];
     51      amount [label="specify\ninvoice details"];
     52      receiving [label="receiving...",shape=diamond];
     53      sending [label="transmitting...",shape=diamond];
     54      mid [label="Payee Inbox",shape=box];
     55      notified [label="Notification:\npayment received"];
     56      end [label="Payee Inbox",shape=box];
     57      begin -> body [label="(1) new"];
     58      body -> amount [label="(2) attach invoice"];
     59      amount -> body [label="(3) Ok"];
     60      body -> sending [label="(4) send"];
     61      sending -> mid [style=dashed];
     62      mid -> receiving [style=dashed];
     63      receiving -> notified [style=dashed];
     64      notified -> end [label="(9) Acknowledge"];
     65      inbox [label="Payer Inbox",shape=box];
     66      receiving2 [label="receiving...",shape=diamond];
     67      midbox [label="Payer Inbox",shape=box];
     68      open [label="message with\nattached invoice"];
     69      confirm [label="review invoice"];
     70      paying [label="paying...", shape=diamond];
     71      paid [label="message with\npaid invoice"];
     72      finbox [label="Payer Inbox",shape=box];
     73      inbox -> receiving2 [style=dashed];
     74      receiving2 -> sending [label="Internet\n(pEp)",style=dashed,dir=back];
     75      receiving2 -> midbox [style=dashed];
     76      midbox -> open [label="(5) select message"];
     77      open -> confirm [label="(6) view invoice"];
     78      confirm -> paying [label="(7) pay"];
     79      paying -> paid [style=dashed];
     80      paid -> finbox [label="(8) back"];
     81      paying -> receiving [style=dashed, label="Internet\n(Taler)"];
     82    }
     83 
     84 Donation Flow User Experience
     85 -----------------------------
     86 
     87 .. graphviz::
     88 
     89    digraph donation {
     90      ranksep="0.5"
     91      { rank = same; "inbox"; "begin"; }
     92      { rank = same; "sending"; "receiving2"; }
     93      { rank = same; "body"; "amount"; }
     94      { rank = same; "mid"; "midbox"; }
     95      { rank = same; "accepting"; "timeout"; "receiving"; }
     96      begin [label="Donor Inbox",shape=box];
     97      body [label="compose\nE-mail message"];
     98      amount [label="specify\npayment details"];
     99      receiving [label="receiving...",shape=diamond];
    100      timeout [label="timeout...",shape=diamond];
    101      sending [label="transmitting...",shape=diamond];
    102      mid [label="Donor Inbox",shape=box];
    103      notified [label="Notification:\npayment confirmed"];
    104      notified2 [label="Notification:\npayment refunded"];
    105      end [label="Donor Inbox",shape=box];
    106      begin -> body [label="(1) new"];
    107      body -> amount [label="(2) attach payment"];
    108      amount -> body [label="(3) Ok"];
    109      body -> sending [label="(4) send"];
    110      sending -> mid [style=dashed];
    111      mid -> receiving [style=dashed];
    112      receiving -> notified [style=dashed];
    113      mid -> timeout [style=dashed];
    114      timeout -> notified2 [style=dashed];
    115      notified -> end [label="(9a) Acknowledge"];
    116      notified2 -> end [label="(9b) Acknowledge"];
    117      inbox [label="Recipient Inbox",shape=box];
    118      receiving2 [label="receiving...",shape=diamond];
    119      midbox [label="Recipient Inbox",shape=box];
    120      open [label="message with\nattached payment"];
    121      confirm [label="accept payment?"];
    122      accepting [label="accepting...", shape=diamond];
    123      paid [label="message with\naccepted payment"];
    124      finbox [label="Recipient Inbox",shape=box];
    125      inbox -> receiving2 [style=dashed];
    126      receiving2 -> sending [label="Internet\n(pEp)",style=dashed,dir=back];
    127      receiving2 -> midbox [style=dashed];
    128      midbox -> open [label="(5) select message"];
    129      open -> confirm [label="(6) review payment details"];
    130      confirm -> accepting [label="(7) yes"];
    131      accepting -> paid [style=dashed];
    132      paid -> finbox [label="(8) back"];
    133      accepting -> receiving [style=dashed, label="Internet\n(Taler)"];
    134    }
    135 
    136 Requirements
    137 ============
    138 
    139 * The protocol must permit transacting arbitrary amounts in any currency,
    140   as long as the exchanges involved support the necessary purse and partner
    141   operations.
    142 * The control data for wallet-to-wallet payments should be small
    143   enough to fit into a QR code or short message (so ideally less than 64 bytes).
    144 * No other direct communication channel between payer and payee should
    145   be required.
    146 * The wallet-to-wallet payment must be possible without trusting the other
    147   party beyond the point where the money has been received by the payee.  Thus,
    148   sharing of coin private keys is not sufficient, we need transactional semantics
    149   resulting in exclusive control over the funds by the recipient.
    150 * The wallet-to-wallet payment protocol must not allow users to circumvent income
    151   transparency.  That is, each wallet-to-wallet transaction must be visible
    152   on a KYCed transaction ledger (such as a bank account).
    153 * The money received via a wallet-to-wallet payment must be usable for
    154   further Taler payments with minimal delay (after KYC).
    155 * It must still be possible to associate payments with a contract that is
    156   effectively (alas not necessarily directly) signed by both parties:
    157   the payer with the coin private keys, and the payee with their KYC'ed
    158   account private key.
    159 * The contract must be able to satisfy laws like the German TSE law,
    160   which implies that the payer must be able to obtain a payment receipt.
    161 * Two payment scenarios must be possible: (1) one where the payee first
    162   transmits a proposal to the payer (request-to-pay) that the payer
    163   accepts by making the payment, and (2) completely uni-directional
    164   payments where the payer includes a proposal with the payment and the
    165   payee accepts the proposal by taking the offered payment.
    166 * If the payment fails (i.e. the receiver refuses to accept the money
    167   or the message is lost), the payer must automatically recover the
    168   funds (minus applicable fees) without the need for further communication.
    169 * If funds flow back to the payer due to an aborted payment, it must be
    170   provable for the payer that these funds were not income but merely an aborted
    171   transaction.  Furthermore, in this case, no KYC should be required from the
    172   payer.
    173 * If a payment would partially succeed, i.e. because the payer inadvertently
    174   used some double-spent coins and some valid coins, this must fail before the
    175   uni-directional communication and be correctable payer-side.  In other words,
    176   the actual payment must be atomic.
    177 * The usual properties of Taler (everything auditable, unlinkability,
    178   high-performance in terms of CPU, bandwidth, latency, storage
    179   requirements, and the ability to levy fees on every operation that
    180   is costly for the exchange) need to be preserved.
    181 * The system must handle the case where a customer no longer intends to
    182   use the KYCed account (due to disuse, death, or key compromise).
    183 
    184 
    185 
    186 New Terminology
    187 ===============
    188 
    189 * An ``account`` is a non-expiring reserve for which entity knowing the
    190   reserve private key has completed a KYC procedure sufficient to enable
    191   receiving income under that address.
    192 * A ``purse`` is a public-private key pair where the public key is
    193   an exchange address from which any owners of an account
    194   can ``merge`` the amount left at a ``purse`` into their
    195   account balance assuming they know the purse private key.
    196 * A ``wad`` is an exchange-to-exchange wire transfer that wires money
    197   into a group of accounts at the target exchange.
    198 
    199 
    200 Proposed Solution
    201 =================
    202 
    203 Principles
    204 ----------
    205 
    206 * Purses are ephemeral and only serve for one transaction.
    207 * The purse's transaction amount is fixed when the purse is created, and
    208   specified together with the maximum deposit fee acceptable to the payee.
    209   Deposit fees exceeding this limit must be paid by the payer.
    210 * Each purse is associated with a contract terms hash and an expiration date.
    211 * The contract is optionally stored encrypted at the exchange.
    212   The contract must be encrypted to the purse private key.
    213   An additional ephemeral public key (for DH encryption) should be
    214   part of the POSTed payload.
    215 * The exchange deletes the encrypted contract at this expiration date.
    216 * The exchange may limit the encrypted contract size and storage duration.
    217 * Either payer or payee can create the purse and associate it with the contract.
    218 * By merging the purse into the account, the payee accepts the contract.
    219 * By paying the purse to the designated amount, the payer accepts the contract.
    220 * Until the purse is fully paid, the payer can abort the payment.
    221 * The exchange may charge a **purse fee** for managing the purse, but we
    222   want most scenarios to not require it to be effectively charged.
    223 * By associating a purse with an account upon creation, the purse fee can be
    224   made optional for account holders as long as the number of purses created
    225   per account is below a configurable threshold.
    226 * By charging the purse fee only in case the payee did **not** merge the
    227   purse into their account, the purse fee can be limited for payers to
    228   the case where they are receiving a refund --- and here it could be
    229   then entirely avoided if the refund fee is non-zero.
    230 
    231 
    232 W2W Payment Metadata
    233 --------------------
    234 
    235 The standard Taler Customer-to-Merchant payments always use a contract terms
    236 JSON object to record the modalities of the payment and the resulting
    237 obligations of a successful payment.
    238 
    239 The contract terms concept does not directly carry over to W2W payments,
    240 because:
    241 
    242 * Either party may initiate the payment.
    243 * The payee does not have a merchant public key, and
    244   at the time of payment initiation, the payee account might not yet
    245   be known.
    246 * There is no nonce that the customer generates and uses to prove that they
    247   uniquely "own" the contract terms.
    248 * There is no negotiation of trusted auditors / exchanges possible.
    249 
    250 As a result, some of the existing fields of the contract terms no longer apply
    251 to wallet-to-wallet payments.
    252 
    253 Contract metadata for W2W payments can be exchanged in three ways:
    254 
    255 1. Inline, as part of the payment request / payment offer.  In this case,
    256    both parties are already aware of the contract's contents and
    257    the exchange's contract exchange facility is simply not used.
    258 2. The payee can create a **purse** and immediately associate it with
    259    an **account** by sending a signed **merge** request together with
    260    the (encrypted) contract.
    261 
    262    a. The purse creation request created by the payee must include a
    263       signature with the account private key of the payee signing the purse
    264       public key and the hash of the contract, thereby affirming that
    265       the contract was pre-approved by the account owner.
    266    b. The exchange may wave the purse fee for a certain number of
    267       active purses per account. Additional purses can be purchased
    268       by paying the **purse fee**.
    269 3. The payer can store a contract with the exchange by POSTing
    270    an encrypted contract to the exchange as part of creating a **purse**.
    271 
    272    a. The exchange charges the **purse fee** to payers for purses that
    273       are refunded after not being **merged**.
    274    b. When paying into a purse, the coin signature includes the purse
    275       public key, the contract hash and the desired expiration date
    276       (how long a merge is allowed).
    277    c. Payment offers are not allowed if the amount transacted is below
    278       the purse fee.
    279    d. The exchange auto-refunds coins in **purses** with deposits
    280       matching expired contracts.
    281 
    282       .. note::
    283 
    284          While the **refund fee** amount can be reused, these types of refunds
    285          are not approved by a merchant's signature. Thus, we will need
    286          a new message type in the coin history to represent these events.
    287 
    288 
    289 Account creation
    290 ----------------
    291 
    292 An account is simply a reserve that has been subjected to
    293 KYC. A reserve that has seen a purse merged into it must
    294 be upgraded to an account before further withdraw (or close)
    295 operations are allowed.  The usual closure deadline for a
    296 reserve is extended to the KYC deadline.
    297 
    298 1. The payee generates a reserve key, which also yields a
    299    ``payto://taler/$EXCHANGE_BASE_URL/$RESERVE_PUB``
    300    target address (for which the payee knows the corresponding
    301    reserve private key).
    302 2. When withdrawing from a reserve that has experienced
    303    merge operations and thus must be an account, the exchange
    304    first checks if the customer has satisfied the KYC requirements.
    305    If not, the customer is redirected to a Web page where they
    306    can perform the necessary KYC operation.
    307 3. For this, the exchange wire gateway is extended with a request to
    308    check the KYC status of a customer based on an ``RESERVE_PUB``.
    309    Possible replies are ``in-progress`` and ``succeeded``.
    310    An ``in-progress`` status should be accompanied with
    311    information how the customer may complete the KYC check.
    312 4. A new exchange endpoint ``/reserves/$RESERVE_PUB/kyc``
    313    allows wallets to request a KYC for a
    314    ``$RESERVE_PUB``.  Such a request may include the requirement to pay
    315    a **KYC fee**.
    316    The KYC fee may be charged to the reserve (a sufficient
    317    balance can be provided by the wallet by creating a purse
    318    and merging the purse with the reserve, if needed),
    319    or could be waved if the reserve was established via a wire transfer
    320    from a partner bank where KYC is free.  For this, the Wire
    321    gateway API is extended with a flag that informs the exchange
    322    that the incoming wire transfer implies a free KYC check.
    323 5. If the account owner fails to perform the KYC check, all funds
    324    in a reserve remain inaccessible.  After a configurable duration,
    325    the funds may be considered forfeit and become the property of
    326    the exchange where the reserve is located.
    327 6. The exchange may charge an annual **account fee**, and can
    328    close accounts where the account balance is insufficient to
    329    cover the account fee.
    330 
    331 
    332 Withdrawing from accounts
    333 -------------------------
    334 
    335 1. When requesting an account's history (which can get quite long),
    336    the exchange only returns the last 3 months of data.  Requesting
    337    the full history requires paying an **account history fee**
    338    (which is not done via a 402, but simply charged to the account
    339    when requested; full account histories for accounts with an
    340    insufficient balance cannot be requested -- except of course
    341    the wallet could simply top up the account balance first, see below).
    342 2. If the exchange has **merged** a **purse** into an account, or
    343    received an inbound wire transfer from a **wad** matching the
    344    account (see below), it adds the respective amount(s) to the
    345    account's balance, allowing the KYC'ed customer to withdraw the funds,
    346    similar to withdrawals from a reserve.
    347 3. The account history endpoint should also allow long-polling.
    348    Note that long-polling should be limited to short durations,
    349    as inbound transfers via ``taler-exchange-wirewatch`` cannot cause the long
    350    polling to be resumed, only transfers within the same exchange can benefit
    351    from long-polling acceleration.
    352 
    353 
    354 Account deletion
    355 ----------------
    356 
    357 1. A reserve owner can delete a reserve by signing a deletion message
    358    with the reserve private key.
    359 2. This basically resets the KYC data at the exchange, preventing
    360    further use of the account. This is helpful in case a user is
    361    concerned about having
    362    accidentally disclosed the reserve private key to a third party.
    363 3. If funds remain in the reserve, the exchange will close the
    364    reserve and wire the funds to the associated bank account.
    365    If no bank account is associated with the reserve,
    366    an error message is generated instead.  The
    367    user can pass an extra override parameter to delete reserves
    368    even if they still contain funds.
    369 4. A related endpoint should exist for the exchange operator, possibly
    370    using messages signed with a new exchange management key.
    371    This could be useful in case customers die or are otherwise
    372    in need for manual intervention that requires an account to
    373    be deleted. In this case,
    374    remaining funds in the account should be wired to a bank account
    375    designated in the message with the management signature. The audit
    376    report should contain a special note for all of these types of
    377    account deletions.
    378 
    379 
    380 
    381 Payment offers
    382 --------------
    383 
    384 In this protocol variant, the payer is initiating the process.
    385 
    386 1. The payer creates a **purse** by computing a public-private key pair.
    387 2. The payer POSTs to the ``/purses/$PURSE_PUB/create`` endpoint to create the
    388    purse, deposit coins and optionally upload the encrypted contract terms.
    389    The deposit signatures should use ``payto://taler/$PURSE_PUB``
    390    as the target address and signing over the ``$CONTRACT_HASH`` as
    391    usual in deposit operations. Note that the lack of a hostname
    392    indicates that the target address is a local purse.
    393 3. The payer shares the contract private key and the base URL
    394    of the exchange where the purse was created with the payee.
    395    This is represented by a
    396    ``taler://pay-push/$BASE_URL/$CONTRACT_PRIV`` URI in the implemented
    397    protocol.
    398    The chapter on ``Refinements`` below clarifies why this
    399    step is not quite OK and was modified when implementing the   design.
    400 4. The payee uses ``/contracts/$CONTRACT_PUB`` to retrieve the encrypted
    401    contract and ``/purses/$PURSE_PUB/deposit`` to retrieve the purse status,
    402    including its balance.
    403 5. The payee's wallet must ensure that either:
    404 
    405    a. The purse has an attached encrypted contract terms, the contract
    406       terms can be decrypted and are valid, and their hash matches the contract
    407       terms hash of the purse.
    408    b. The wallet received detached contract terms, and their hash matches
    409       contract terms of the purse.
    410 
    411    If neither case applies, the payee's wallet must reject the payment.
    412 6. The payee can then POST to ``/purses/$PURSE_PUB/merge`` a
    413    request signed by the merge private key to **merge** the
    414    funds into an account.  A second signature must be provided
    415    by the account private key, signing the ``$CONTRACT_HASH`` thereby
    416    affirming that the payee accepted the contract.
    417    The account is of the form ``payto://taler/$EXCHANGE_BASE_URL/$ACCOUNT_PUB``.
    418 7. Processing continues depending on the location of the account:
    419 
    420    a. If the ``$EXCHANGE_BASE_URL`` matches the local exchange, then
    421       the exchange processes the **merge** request akin to the logic
    422       for payments into known accounts, as detailed above.
    423    b. If the ``$EXCHANGE_BASE_URL`` does not match the local exchange,
    424       a **wad fee** is charged, and the remaining amount is placed into a **wad**
    425       to inform the target exchange, as detailed below.  Wad fees may be covered
    426       by the merchant, just like deposit fees, depending on the contract.
    427 8. The exchange confirms the merge (per response to the **merge** request).
    428    This allows the payee software to instantly
    429    affirm to the users that the transaction is final (even if it may not
    430    be instantly available to the payee if the payee did not complete the
    431    KYC process for the account).
    432 9. The payer uses the GET ``/purses/$PURSE_PUB/merge`` endpoint
    433    to obtain the receipt from the payee (in the form of the
    434    **merge** signature).  Query parameters are used to avoid
    435    downloading the (already known) encrypted contract and the
    436    deposit operations.  Long-polling must also be possible for
    437    this request.
    438 
    439 
    440 
    441 Payment requests
    442 ----------------
    443 
    444 1. The payee creates a **purse** by computing a public-private key pair.
    445 2. The payee POSTs to the ``/reserves/$RESERVE_PUB/purse`` endpoint to
    446    create the purse, upload the encrypted contract, associate it with the
    447    payee's account and signal its agreement to the contract.  The request
    448    includes signatures made with the purse, merge and account private keys.
    449 3. The payee provides a
    450    ``taler://pay-pull/$BASE_URL/$CONTRACT_PRIV`` URI to the payer.
    451 4. The payer computes the corresponding public keys and uses
    452    ``/contracts/$CONTRACT_PUB`` to retrieve the encrypted contract and
    453    ``/purses/$PURSE_PUB/merge`` to retrieve the merge status, which signifies
    454    that the payee would agree to the contract.
    455 5. The payer software decrypts the encrypted contract using the purse private
    456    key and the payer accepts the contract in the user interface.
    457 6. Processing continues depending on the source of the coins:
    458 
    459    a. If the payer's coins originate from the same exchange, the
    460       payer software POSTs to the ``/purses/$PURSE_PUB/deposit`` endpoint to
    461       deposit coins into the purse. The deposit signatures should use
    462       ``payto://taler/$PURSE_PUB``
    463       as the target address and signing over the ``$CONTRACT_HASH`` as
    464       usual in deposit operations. Note that the lack of a hostname
    465       indicates that the target address is a local purse.
    466    b. If the payer's coins originate from another exchange, the
    467       payer software deposits the coins at the originating exchange
    468       using the traditional ``/deposit`` endpoint and a target account of the form
    469       ``payto://taler/$EXCHANGE_BASE_URL/$ACCOUNT_PUB``.  In this case,
    470       the remote exchange charges a **wad fee** and places the remaining
    471       amount into a **wad** to inform the target exchange, as detailed below.
    472 7. The exchange confirms the deposit. This allows the payer software to instantly
    473    affirm to the users that the transaction is final, or to abort or try again
    474    in case of errors.
    475 8. The payee uses the GET ``/purses/$PURSE_PUB/deposit`` endpoint (possibly with long-polling)
    476    to be notified about the successful deposit and subsequent completion of the
    477    **merge** request.
    478 
    479 
    480 Payment into accounts at remote exchanges
    481 -----------------------------------------
    482 
    483 In case the coins and the accounts in the transaction flows above are at
    484 different exchanges, an aggregated exchange-to-exchange payment (short
    485 **wad**) is used.
    486 
    487 1. Exchanges specify a new **wad fee** that they charge for exchange-to-exchange
    488    payments.  They also specify their wad policy, that is how often they
    489    perform exchange-to-exchange transfers.
    490 
    491    .. note::
    492 
    493       We may want to consider allowing for different wad-speed levels, where
    494       express payments (without aggregation) are allowed in return for higher
    495       wad fees.
    496 
    497 2. The payer's exchange creates a **wad** by grouping all wad requests
    498    to the same target exchange. It executes
    499    the transaction when either the **wad threshold** (maximum number
    500    of transactons aggregated per wad) or the **wad delay** (maximum
    501    delay for transfers) has been reached.
    502 3. If the (aggregated) wire transfer fails (say the
    503    ``/wire`` endpoint of the payee exchange does not
    504    resolve to a valid bank account), the
    505    originating exchange automatically creates a full refund for
    506    all involved coins (**refund fees** apply).
    507 
    508    .. note::
    509 
    510       While the **refund fee** amount can be reused, these types of refunds
    511       are not approved by a merchant's signature. Thus, we will need
    512       a new message type in the coin history to represent these events.
    513 
    514 4. The payee's exchange observes the wire transfer with a wire transfer
    515    subject with the originating exchange base URL and a ``$WATID``,
    516    and uses a GET ``/wad/$WATID`` request to obtain
    517    details about the target accounts.
    518 5. When the payer's exchange is requested to provide information about
    519    aggregated transfers under the ``$WATID``, it provides a signed list of
    520    account public keys and associated amounts that must add up to an
    521    amount below the total amount transferred. If they do not, the
    522    payee's exchange does not credit any of the accounts and instead
    523    preserves the bogus reply (to justify its inaction with its own
    524    auditor) and reports the issue to the auditor of the payer's exchange
    525    (keeping the received funds for future manual resolution).
    526 6. ``taler-exchange-wirewatch`` and the Taler wire gateway API will
    527    need to be extended to allow passing inbound wire transfers with ``$WATID``
    528    and exchange base URL to the exchange. Furthermore, another tool
    529    is needed to lookup the **wad** data at remote exchanges.
    530 7. If the payee trusts the originating exchange, it may consider the
    531    transaction ``final`` once the originating exchange has affirmed the
    532    deposit (assuming the payer has a way to submit the evidence of that
    533    payment, which may not apply in uni-directional scenarios).
    534    Otherwise, the payee may simply only trust its own exchange,
    535    resulting in the transfer only being considered final after the
    536    receiving exchange has confirmed that the **wad** has arrived.
    537 
    538 
    539 Examples
    540 ---------
    541 
    542 Cross-exchange W2W payment request:
    543 
    544 * Bob borrowed 15 EUR from Alice to buy a train ticket.  A few days later,
    545   Alice wants her money back.  She creates a request for payment in her wallet.
    546   The wallet creates a purse for 15 EUR at the only exchange that Alice is currently
    547   using.  The wallet shows her a
    548   ``taler://pay-pull/{EXCHANGE_URL}/{CONTRACT_PRIV}``
    549   link that she can share with Bob.  Bob receives the link and opens it with
    550   his Taler wallet.  Bob is using a different EUR exchange than Alice.  Bob's
    551   wallet makes a ``/deposit`` request to his own exchange.  Shortly after, Alice's
    552   exchange receives the wad from Bob's exchange, and credits the money into
    553   Alice's purse.
    554 
    555   * Q: How does Bob find out if Alice's exchange supports a wad transfer from
    556     Bob's exchange? A: This needs to be part of the wad policy.
    557   * Q: How does Bob get a "receipt" to prove that he paid Alice?
    558     A: He has Alice's account public key and the associated signature
    559     chain leading to her payment request. If he paid someone else by accident,
    560     the KYC of Alice's exchange could be used to find out who received the funds.
    561 
    562 Cross-exchange W2W payment offer:
    563 
    564 * Carol wants to send some money to Dave as a birthday gift.  Carol knows that
    565   Dave is using Taler, but she does not know which exchange he is using.  She
    566   opens her Taler wallet and initiates a P2P payment.  She sends the resulting
    567   ``taler://pay-push/{EXCHANGE_URL}/{CONTRACT_PRIV}`` in an e-mail to Dave.
    568   Dave opens the link in the e-mail with his Taler wallet.
    569   Since Dave is using a different exchange than Carol, Dave's wallet
    570   issues a **merge** request to Carol's exchange pointing Carol's exchange
    571   to Dave's account at his exchange.  Shortly after,
    572   Dave's exchange receives a **wad** from Carol's exchange,
    573   and credits Dave's account with the money.
    574 
    575 
    576 State machine for Purses
    577 ------------------------
    578 
    579 .. code-block:: none
    580 
    581    // The "OPEN-ACCOUNT" start state implies that the purse is associated
    582    // with an account and a merge request for that account.
    583    -> OPEN-ACCOUNT
    584 
    585    // "Partial" means that it is filled with a fraction of the coins
    586    // indicated in the creation request.
    587    OPEN-ACCOUNT -> PARTIAL
    588 
    589    // The purse was filled with as many coins
    590    // as indicated in the creation request, resulting in the transaction to complete.
    591    OPEN-ACCOUNT -> ACCEPTED
    592 
    593    // The offer expired before any payment was received.
    594    OPEN-ACCOUNT -> CLOSED
    595 
    596    // The purse was filled with as many coins
    597    // as indicated in the creation request, resulting in the transaction to complete.
    598    PARTIAL -> ACCEPTED
    599 
    600    // During an abort, already deposited coins are being taken out of the purse.
    601    PARTIAL -> OPEN-ACCOUNT
    602 
    603    // All coins put into the purse are refunded because the
    604    // payer never completed the purchase before the timeout.
    605    PARTIAL -> CLOSED
    606 
    607    // The "OPEN-DEPOSIT" start state implies that the purse is filled with
    608    // deposited coins.
    609    -> OPEN-DEPOSIT
    610 
    611    // Paid and merged with an account (locally or via a wad)
    612    OPEN-DEPOSIT -> ACCEPTED
    613 
    614    // The offer expired without a merge request.
    615    OPEN-DEPOSIT -> CLOSED
    616 
    617 
    618 Additional considerations
    619 -------------------------
    620 
    621 * Creation of additional accounts per customer can
    622   be discouraged by asking for higher fees.
    623 * The global transaction volume of one customer can be easily
    624   determined by authorities, which can then trigger further audits
    625   of the customer
    626 * As a technically expensive but more water-tight measure, normal
    627   withdrawals from reserves could be disallowed.  Instead,
    628   a modified refresh protocol could ensure that whoever has knowledge
    629   of the account private key can also learn the private keys
    630   of coins withdrawn from that account, thereby removing
    631   Taler's "one-hop withdrawal loophole".
    632 
    633 
    634 Exchange database schema changes
    635 --------------------------------
    636 
    637 We need to exchange the existing reserves table to include bits for KYC-needed
    638 and KYC-passed. Also, we need to store the payto://-URI of the bank account.
    639 
    640 Finally, we may need to keep some link to the KYC data, even though the
    641 exchange technically does not need it, but likely there might be regulatory
    642 reasons to have that association for legal inquiries. (However, it would
    643 also be possible to keep that link only in the external KYC service's
    644 database.)
    645 
    646 .. sourcecode:: sql
    647 
    648   -- Everything in one big transaction
    649   BEGIN;
    650   -- Check patch versioning is in place.
    651   SELECT _v.register_patch('exchange-TBD', NULL, NULL);
    652   --
    653   CREATE TABLE IF NOT EXISTS partners
    654   (partner_serial_id BIGSERIAL UNIQUE
    655   ,partner_master_pub BYTEA NOT NULL CHECK(LENGTH(partner_master_pub)=32)
    656   ,start_date INT8 NOT NULL
    657   ,end_date INT8 NOT NULL
    658   ,wad_frequency INT8 NOT NULL
    659   ,wad_fee_val INT8 NOT NULL
    660   ,wad_fee_frac INT4 NOT NULL
    661   ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64))
    662   ,partner_base_url TEXT NOT NULL
    663   );
    664   COMMENT ON TABLE partners
    665     IS 'exchanges we do wad transfers to';
    666   COMMENT ON COLUMN partners.partner_master_pub
    667     IS 'offline master public key of the partner';
    668   COMMENT ON COLUMN partners.start_date
    669     IS 'starting date of the partnership';
    670   COMMENT ON COLUMN partners.end_date
    671     IS 'end date of the partnership';
    672   COMMENT ON COLUMN partners.wad_frequency
    673     IS 'how often do we promise to do wad transfers';
    674   COMMENT ON COLUMN partners.wad_fee_val
    675     IS 'how high is the fee for a wallet to be added to a wad to this partner';
    676   COMMENT ON COLUMN partners.partner_base_url
    677     IS 'base URL of the REST API for this partner';
    678   COMMENT ON COLUMN partners.master_sig
    679     IS 'signature of our master public key affirming the partnership, of purpose TALER_SIGNATURE_MASTER_PARTNER_DETAILS';
    680   --
    681   ALTER TABLE reserves
    682     ADD COLUMN kyc_needed BOOLEAN NOT NULL DEFAULT (false)
    683     ADD COLUMN kyc_passed BOOLEAN NOT NULL DEFAULT (false)
    684     ADD COLUMN payto_uri TEXT DEFAULT (NULL)
    685     ADD COLUMN kyc_link TEXT DEFAULT (NULL);
    686   COMMENT ON COLUMN reserves.kyc_needed
    687     IS 'set to true once a reserve was merged with a purse';
    688   COMMENT ON COLUMN reserves.kyc_passed
    689     IS 'set to true once the user performed the KYC check';
    690   COMMENT ON COLUMN reserves.payto_uri
    691     IS 'bank account details to use in case reserve is closed';
    692   COMMENT ON COLUMN reserves.kyc_link
    693     IS 'optional link to KYC data';
    694   --
    695   CREATE TABLE IF NOT EXISTS kyc_requests
    696   (kyc_request_serial_id BIGSERIAL UNIQUE
    697   ,reserve_uuid INT8 NOT NULL REFERENCES reserves (reserve_uuid) ON DELETE CASCADE
    698   ,kyc_date INT8 NOT NULL
    699   ,kyc_retry INT8 NOT NULL
    700   ,kyc_fee_val INT8 NOT NULL
    701   ,kyc_fee_frac INT4 NOT NULL
    702   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    703   ,kyc_id TEXT NOT NULL
    704   ,PRIMARY KEY (reserve_uuid, kyc_date)
    705   );
    706   COMMENT ON TABLE kyc_requests
    707     IS 'KYC processes initiated by the owner of a reserve';
    708   COMMENT ON COLUMN kyc_requests.reserve_uuid
    709     IS 'Reserve for which the KYC request was triggered.';
    710   COMMENT ON COLUMN kyc_requests.reserve_sig
    711     IS 'Signature affirming the KYC request';
    712   COMMENT ON COLUMN kyc_requests.kyc_fee_val
    713     IS 'Amount paid by the reserve for the KYC process.';
    714   COMMENT ON COLUMN kyc_requests.kyc_date
    715     IS 'When was the KYC process originally initiated.';
    716   COMMENT ON COLUMN kyc_requests.kyc_retry
    717     IS 'Timestamp when we should next query the KYC backend for the KYC status. The maximum possible numeric value indicates that we do not need to ever check the status of this KYC process again.';
    718   COMMENT ON COLUMN kyc_requests.kyc_id
    719     IS 'ID of the KYC process, used to compute the URL returned to the client as well as for the exchange to check if the KYC has completed. Format depends on the KYC process of the bank.';
    720   --
    721   CREATE TABLE IF NOT EXISTS mergers
    722   (merge_request_serial_id BIGSERIAL UNIQUE
    723   ,reserve_uuid BYTEA NOT NULL REFERENCES reserves (reserve_uuid) ON DELETE CASCADE
    724   ,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE,
    725   ,reserve_pub BYTEA NOT NULL CHECK (LENGTH(reserve_pub)=32),
    726   ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32),
    727   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    728   ,purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64))
    729   ,merge_timestamp INT8 NOT NULL
    730   ,purse_expiration INT8 NOT NULL
    731   ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64))
    732   ,purse_val INT8 NOT NULL
    733   ,purse_frac INT4 NOT NULL
    734   ,PRIMARY KEY (purse_pub)
    735   );
    736   COMMENT ON TABLE mergers
    737     IS 'Merge requests where a purse- and account-owner requested merging the purse into the account';
    738   COMMENT ON COLUMN mergers.reserve_uuid
    739     IS 'identifies the reserve';
    740   COMMENT ON COLUMN mergers.partner_serial_id
    741     IS 'identifies the partner exchange, NULL in case the target reserve lives at this exchange';
    742   COMMENT ON COLUMN mergers.reserve_pub
    743     IS 'public key of the target reserve';
    744   COMMENT ON COLUMN mergers.purse_pub
    745     IS 'public key of the purse';
    746   COMMENT ON COLUMN mergers.reserve_sig
    747     IS 'signature by the reserve private key affirming the merge';
    748   COMMENT ON COLUMN mergers.purse_sig
    749     IS 'signature by the purse private key affirming the merge';
    750   COMMENT ON COLUMN mergers.merge_timestamp
    751     IS 'when was the merge message signed';
    752   COMMENT ON COLUMN mergers.purse_expiration
    753     IS 'when is the purse set to expire';
    754   COMMENT ON COLUMN mergers.h_contract_terms
    755     IS 'hash of the contract terms both sides are to agree upon';
    756   COMMENT ON COLUMN mergers.purse_val
    757     IS 'amount to be transferred from the purse to the reserve (excludes deposit fees)';
    758   CREATE INDEX IF NOT EXISTS mergers_reserve_uuid
    759     ON mergers (reserve_uuid);
    760   COMMENT ON INDEX mergers_reserve_uuid
    761     IS 'needed in reserve history computation';
    762   --
    763   CREATE TABLE IF NOT EXISTS contracts
    764   (contract_serial_id BIGSERIAL UNIQUE
    765   ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32),
    766   ,pub_ckey BYTEA NOT NULL CHECK (LENGTH(pub_ckey)=32)),
    767   ,e_contract BYTEA NOT NULL,
    768   ,PRIMARY KEY (purse_pub)
    769   );
    770   COMMENT ON TABLE contracts
    771     IS 'encrypted contracts associated with purses';
    772   COMMENT ON COLUMN contracts.purse_pub
    773     IS 'public key of the purse that the contract is associated with';
    774   COMMENT ON COLUMN contracts.pub_ckey
    775     IS 'Public ECDH key used to encrypt the contract, to be used with the purse private key for decryption';
    776   COMMENT ON COLUMN contracts.e_contract
    777     IS 'AES-GCM encrypted contract terms (contains gzip compressed JSON after decryption)';
    778   --
    779   CREATE TABLE IF NOT EXISTS history_requests
    780   (reserve_uuid INT8 NOT NULL REFERENCES reserves(reserve_uuid) ON DELETE CASCADE,
    781   ,request_timestamp INT8 NOT NULL
    782   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    783   ,history_fee_val INT8 NOT NULL
    784   ,history_fee_frac INT4 NOT NULL
    785   ,PRIMARY KEY (reserve_uuid,request_timestamp)
    786   );
    787   COMMENT ON TABLE history_requests
    788     IS 'Paid history requests issued by a client against a reserve';
    789   COMMENT ON COLUMN history_requests.request_timestamp
    790     IS 'When was the history request made';
    791   COMMENT ON COLUMN history_requests.reserve_sig
    792     IS 'Signature approving payment for the history request';
    793   COMMENT ON COLUMN history_requests.history_fee_val
    794     IS 'History fee approved by the signature';
    795   --
    796   CREATE TABLE IF NOT EXISTS close_requests
    797   (reserve_uuid INT8 NOT NULL REFERENCES reserves(reserve_uuid) ON DELETE CASCADE,
    798   ,close_timestamp INT8 NOT NULL
    799   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    800   ,close_val INT8 NOT NULL
    801   ,close_frac INT4 NOT NULL
    802   ,PRIMARY KEY (reserve_uuid,close_timestamp)
    803   );
    804   COMMENT ON TABLE close_requests
    805     IS 'Explicit requests by a reserve owner to close a reserve immediately';
    806   COMMENT ON COLUMN close_requests.close_timestamp
    807     IS 'When the request was created by the client';
    808   COMMENT ON COLUMN close_requests.reserve_sig
    809     IS 'Signature affirming that the reserve is to be closed';
    810   COMMENT ON COLUMN close_requests.close_val
    811     IS 'Balance of the reserve at the time of closing, to be wired to the associated bank account (minus the closing fee)';
    812 
    813   --
    814   CREATE TABLE IF NOT EXISTS purse_requests
    815   (purse_deposit_serial_id BIGSERIAL UNIQUE
    816   ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32),
    817   ,purse_expiration INT8 NOT NULL
    818   ,h_contract_terms BYTEA NOT NULL CHECK (LENGTH(h_contract_terms)=64)
    819   ,amount_with_fee_val INT8 NOT NULL
    820   ,amount_with_fee_frac INT4 NOT NULL
    821   ,purse_sig BYTEA NOT NULL CHECK(LENGTH(purse_sig)=64)
    822   ,PRIMARY KEY (purse_pub,coin_pub)
    823   );
    824   COMMENT ON TABLE purse_requests
    825     IS 'Requests establishing purses, associating them with a contract but without a target reserve';
    826   COMMENT ON COLUMN purse_requests.purse_pub
    827     IS 'Public key of the purse';
    828   COMMENT ON COLUMN purse_requests.purse_expiration
    829     IS 'When the purse is set to expire';
    830   COMMENT ON COLUMN purse_requests.h_contract_terms
    831     IS 'Hash of the contract the parties are to agree to';
    832   COMMENT ON COLUMN purse_requests.amount_with_fee_val
    833     IS 'Total amount expected to be in the purse';
    834   COMMENT ON COLUMN purse_requests.purse_sig
    835     IS 'Signature of the purse affirming the purse parameters, of type TALER_SIGNATURE_PURSE_REQUEST';
    836   --
    837   CREATE TABLE IF NOT EXISTS purse_deposits
    838   (purse_deposit_serial_id BIGSERIAL UNIQUE
    839   ,purse_pub BYTEA NOT NULL CHECK (LENGTH(purse_pub)=32),
    840   ,coin_pub BYTEA NOT NULL REFERENCES known_coins (coin_pub) ON DELETE CASCADE
    841   ,amount_with_fee_val INT8 NOT NULL
    842   ,amount_with_fee_frac INT4 NOT NULL
    843   ,coin_sig BYTEA NOT NULL CHECK(LENGTH(coin_sig)=64)
    844   ,PRIMARY KEY (purse_pub,coin_pub)
    845   );
    846   COMMENT ON TABLE purse_deposits
    847     IS 'Requests depositing coins into a purse';
    848   COMMENT ON COLUMN purse_deposits.purse_pub
    849     IS 'Public key of the purse';
    850   COMMENT ON COLUMN purse_deposits.coin_pub
    851     IS 'Public key of the coin being deposited';
    852   COMMENT ON COLUMN purse_deposits.amount_with_fee_val
    853     IS 'Total amount being deposited';
    854   COMMENT ON COLUMN purse_deposits.coin_sig
    855     IS 'Signature of the coin affirming the deposit into the purse, of type TALER_SIGNATURE_PURSE_DEPOSIT';
    856   --
    857   CREATE TABLE IF NOT EXISTS wads_out
    858   (wad_out_serial_id BIGSERIAL UNIQUE
    859   ,wad_id BYTEA PRIMARY KEY CHECK (LENGTH(wad_id)=24)
    860   ,partner_serial_id INT8 NOT NULL REFERENCES partners(partner_serial_id) ON DELETE CASCADE,
    861   ,amount_val INT8 NOT NULL
    862   ,amount_frac INT4 NOT NULL
    863   ,execution_time INT8 NOT NULL
    864   ,UNIQUE (exchange_url, execution_time)
    865   );
    866   COMMENT ON TABLE wads_out
    867     IS 'Wire transfers made to another exchange to transfer purse funds';
    868   COMMENT ON COLUMN wads_out.wad_id
    869     IS 'Unique identifier of the wad, part of the wire transfer subject';
    870   COMMENT ON COLUMN wads_out.partner_serial_id
    871     IS 'target exchange of the wad';
    872   COMMENT ON COLUMN wads_out.amount_val
    873     IS 'Amount that was wired';
    874   COMMENT ON COLUMN wads_out.execution_time
    875     IS 'Time when the wire transfer was scheduled';
    876   --
    877   CREATE TABLE IF NOT EXISTS wad_out_entries
    878   (wad_out_entry_serial_id BIGSERIAL UNIQUE
    879   ,wad_out_serial_id INT8 REFERENCES wads_out (wad_out_serial_id) ON DELETE CASCADE
    880   ,reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)
    881   ,purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32)
    882   ,h_contract BYTEA NOT NULL CHECK(LENGTH(h_contract)=64)
    883   ,purse_expiration INT8 NOT NULL
    884   ,merge_timestamp INT8 NOT NULL
    885   ,amount_with_fee_val INT8 NOT NULL
    886   ,amount_with_fee_frac INT4 NOT NULL
    887   ,wad_fee_val INT8 NOT NULL
    888   ,wad_fee_frac INT4 NOT NULL
    889   ,deposit_fees_val INT8 NOT NULL
    890   ,deposit_fees_frac INT4 NOT NULL
    891   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    892   ,purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64))
    893   );
    894   CREATE INDEX IF NOT EXISTS wad_out_entries_index_by_wad
    895     ON wad_out_entries (wad_out_serial_id);
    896   COMMENT ON TABLE wad_out_entries
    897     IS 'Purses combined into a wad';
    898   COMMENT ON COLUMN wad_out_entries.wad_out_serial_id
    899     IS 'Wad the purse was part of';
    900   COMMENT ON COLUMN wad_out_entries.reserve_pub
    901     IS 'Target reserve for the purse';
    902   COMMENT ON COLUMN wad_out_entries.purse_pub
    903     IS 'Public key of the purse';
    904   COMMENT ON COLUMN wad_out_entries.h_contract
    905     IS 'Hash of the contract associated with the purse';
    906   COMMENT ON COLUMN wad_out_entries.purse_expiration
    907     IS 'Time when the purse expires';
    908   COMMENT ON COLUMN wad_out_entries.merge_timestamp
    909     IS 'Time when the merge was approved';
    910   COMMENT ON COLUMN wad_out_entries.amount_with_fee_val
    911     IS 'Total amount in the purse';
    912   COMMENT ON COLUMN wad_out_entries.wad_fee_val
    913     IS 'Wat fee charged to the purse';
    914   COMMENT ON COLUMN wad_out_entries.deposit_fees_val
    915     IS 'Total deposit fees charged to the purse';
    916   COMMENT ON COLUMN wad_out_entries.reserve_sig
    917     IS 'Signature by the receiving reserve, of purpose TALER_SIGNATURE_ACCOUNT_MERGE';
    918   COMMENT ON COLUMN wad_out_entries.purse_sig
    919     IS 'Signature by the purse of purpose TALER_SIGNATURE_PURSE_MERGE';
    920   --
    921   CREATE TABLE IF NOT EXISTS wads_in
    922   (wad_in_serial_id BIGSERIAL UNIQUE
    923   ,wad_id BYTEA PRIMARY KEY CHECK (LENGTH(wad_id)=24)
    924   ,origin_exchange_url TEXT NOT NULL
    925   ,amount_val INT8 NOT NULL
    926   ,amount_frac INT4 NOT NULL
    927   ,arrival_time INT8 NOT NULL
    928   ,UNIQUE (wad_id, origin_exchange_url)
    929   );
    930   COMMENT ON TABLE wads_in_entries
    931     IS 'Incoming exchange-to-exchange wad wire transfers';
    932   COMMENT ON COLUMN wads_in.wad_id
    933     IS 'Unique identifier of the wad, part of the wire transfer subject';
    934   COMMENT ON COLUMN wads_in.origin_exchange_url
    935     IS 'Base URL of the originating URL, also part of the wire transfer subject';
    936   COMMENT ON COLUMN wads_in.amount_val
    937     IS 'Actual amount that was received by our exchange';
    938   COMMENT ON COLUMN wads_in.arrival_time
    939     IS 'Time when the wad was received';
    940   --
    941   CREATE TABLE IF NOT EXISTS wad_in_entries
    942   (wad_in_entry_serial_id BIGSERIAL UNIQUE
    943   ,wad_in_serial_id INT8 REFERENCES wads_in (wad_serial_id) ON DELETE CASCADE
    944   ,reserve_pub BYTEA NOT NULL CHECK(LENGTH(reserve_pub)=32)
    945   ,purse_pub BYTEA PRIMARY KEY CHECK(LENGTH(purse_pub)=32)
    946   ,h_contract BYTEA NOT NULL CHECK(LENGTH(h_contract)=64)
    947   ,purse_expiration INT8 NOT NULL
    948   ,merge_timestamp INT8 NOT NULL
    949   ,amount_with_fee_val INT8 NOT NULL
    950   ,amount_with_fee_frac INT4 NOT NULL
    951   ,wad_fee_val INT8 NOT NULL
    952   ,wad_fee_frac INT4 NOT NULL
    953   ,deposit_fees_val INT8 NOT NULL
    954   ,deposit_fees_frac INT4 NOT NULL
    955   ,reserve_sig BYTEA NOT NULL CHECK (LENGTH(reserve_sig)=64))
    956   ,purse_sig BYTEA NOT NULL CHECK (LENGTH(purse_sig)=64))
    957   );
    958   COMMENT ON TABLE wad_in_entries
    959     IS 'list of purses aggregated in a wad according to the sending exchange';
    960   COMMENT ON COLUMN wad_in_entries.wad_in_serial_id
    961     IS 'wad for which the given purse was included in the aggregation';
    962   COMMENT ON COLUMN wad_in_entries.reserve_pub
    963     IS 'target account of the purse (must be at the local exchange)';
    964   COMMENT ON COLUMN wad_in_entries.purse_pub
    965     IS 'public key of the purse that was merged';
    966   COMMENT ON COLUMN wad_in_entries.h_contract
    967     IS 'hash of the contract terms of the purse';
    968   COMMENT ON COLUMN wad_in_entries.purse_expiration
    969     IS 'Time when the purse was set to expire';
    970   COMMENT ON COLUMN wad_in_entries.merge_timestamp
    971     IS 'Time when the merge was approved';
    972   COMMENT ON COLUMN wad_in_entries.amount_with_fee_val
    973     IS 'Total amount in the purse';
    974   COMMENT ON COLUMN wad_in_entries.wad_fee_val
    975     IS 'Total wad fees paid by the purse';
    976   COMMENT ON COLUMN wad_in_entries.deposit_fees_val
    977     IS 'Total deposit fees paid when depositing coins into the purse';
    978   COMMENT ON COLUMN wad_in_entries.reserve_sig
    979     IS 'Signature by the receiving reserve, of purpose TALER_SIGNATURE_ACCOUNT_MERGE';
    980   COMMENT ON COLUMN wad_in_entries.purse_sig
    981     IS 'Signature by the purse of purpose TALER_SIGNATURE_PURSE_MERGE';
    982   CREATE INDEX IF NOT EXISTS wad_in_entries_wad_in_serial
    983     ON wad_in_entries (wad_in_serial_id);
    984   CREATE INDEX IF NOT EXISTS wad_in_entries_reserve_pub
    985     ON wad_in_entries (reserve_pub);
    986   COMMENT ON INDEX wad_in_entries_wad_in_serial
    987     IS 'needed to lookup all transfers associated with a wad';
    988   COMMENT ON INDEX wad_in_entries_reserve_pub
    989     IS 'needed to compute reserve history';
    990   --
    991   CREATE TABLE IF NOT EXISTS p2pfees
    992   (p2pfees_serial_id BIGSERIAL UNIQUE
    993   ,start_date INT8 NOT NULL
    994   ,end_date INT8 NOT NULL
    995   ,kyc_timeout INT8 NOT NULL
    996   ,purse_timeout INT8 NOT NULL
    997   ,history_retention INT8 NOT NULL
    998   ,purse_account_limit INT NOT NULL
    999   ,kyc_fee_val INT8 NOT NULL
   1000   ,kyc_fee_frac INT4 NOT NULL
   1001   ,history_fee_val INT8 NOT NULL
   1002   ,history_fee_frac INT4 NOT NULL
   1003   ,account_fee_val INT8 NOT NULL
   1004   ,account_fee_frac INT4 NOT NULL
   1005   ,purse_fee_val INT8 NOT NULL
   1006   ,purse_fee_frac INT4 NOT NULL
   1007   ,master_sig BYTEA NOT NULL CHECK (LENGTH(master_sig)=64))
   1008   );
   1009   --
   1010   CREATE TABLE IF NOT EXISTS partner_accounts
   1011   (payto_uri VARCHAR PRIMARY KEY
   1012   ,partner_serial_id INT8 REFERENCES partners(partner_serial_id) ON DELETE CASCADE,
   1013   ,partner_master_sig BYTEA CHECK (LENGTH(partner_master_sig)=64)
   1014   ,last_seen INT8 NOT NULL
   1015   );
   1016   CREATE INDEX IF NOT EXISTS partner_accounts_index_by_partner_and_time
   1017     ON partner_accounts (partner_serial_id,last_seen);
   1018   COMMENT ON TABLE partner_accounts
   1019     IS 'Table with bank accounts of the partner exchange. Entries never expire as we need to remember the signature for the auditor.';
   1020   COMMENT ON COLUMN wire_accounts.payto_uri
   1021     IS 'payto URI (RFC 8905) with the bank account of the partner exchange.';
   1022   COMMENT ON COLUMN wire_accounts.partner_master_sig
   1023     IS 'Signature of purpose TALER_SIGNATURE_MASTER_WIRE_DETAILS by the partner master public key';
   1024   COMMENT ON COLUMN wire_accounts.last_seen
   1025     IS 'Last time we saw this account as being active at the partner exchange. Used to select the most recent entry, and to detect when we should check again.';
   1026   -- Complete transaction
   1027   COMMIT;
   1028 
   1029 
   1030 
   1031 Alternatives
   1032 ============
   1033 
   1034 * The payer could directly give deposit permissions to the payee.
   1035   This has two problems:
   1036 
   1037   1. The payer does not know the wire details of the payee.
   1038      Thus we would need to introduce some "wildcard deposit permission",
   1039      where the exchange allows any wire details on ``/deposit``.
   1040   2. The payment information would be rather large, making it difficult
   1041      to transfer via a QR code or short text message.
   1042 
   1043 * Account history exceeding a configurable time limit (like 6 years)
   1044   could be subject to garbage collection. However, doing so may be difficult to
   1045   square with onboarding new auditors in the presence of existing
   1046   accounts, as the auditors could then not reconstruct the account
   1047   balances from cryptographic proofs.
   1048 
   1049 * Accounts without KYC check could be eventually closed. However,
   1050   even if the coins used to fill the account are refunded, it
   1051   would be difficult to inform the originating wallet that the
   1052   coins have received a refund. This applies even more strongly
   1053   in case of accounts filled via wads, where in theory the
   1054   originating exchange may not even be in business anymore.
   1055   Thus, it is cleaner and simpler to declare such funds forfeit.
   1056 
   1057 
   1058 Drawbacks
   1059 =========
   1060 
   1061 The overall changes required are not small:
   1062 
   1063 * New **KYC fee**, **wad fee** and **account history fee**
   1064   required in ``/keys`` endpoint (similar to closing and wire fees),
   1065   requires some work across toolchain (offline signature, etc.)
   1066 * New ``taler`` wire method needs special case to possibly bypass
   1067   (same exchange scenario, with long-poll trigger) the usual aggregation logic.
   1068 * New exchange table(s) required to store inbound amounts by account.
   1069   Likely two tables, one for local exchange p2p and one for remote exchange p2p
   1070   payments.
   1071 * New exchange table for purses required (for remote p2p payments).
   1072 * New exchange logic required to make ``transfers`` requests for purses
   1073   (another separate process).
   1074 * New ``/account/$ACCOUNT_PUB/kyc`` endpoint required.
   1075 * New ``/purses/$PURSE_PUB/merge`` endpoint required.
   1076 * Additional tables to be verified by the auditor.
   1077 * ``taler-exchange-wirewatch`` needs to support receiving purses closures
   1078   and exchange-to-exchange wire transfers with WTIDs.
   1079 
   1080 Aside from implementation complexity, the solution has the following drawbacks:
   1081 
   1082 * If a W2W payment failed (say the receiver lost the account private key),
   1083   the customer's money can be forfeit.  Alas, this should be very, very rare
   1084   as the wallet software can trivially ensure that a backup was made of the
   1085   account private key before initiating the KYC process.
   1086 
   1087 
   1088 Refinements
   1089 ===========
   1090 
   1091 In the original design, a payer making a payment offer sends the purse private
   1092 key to the payee, so that the payee can sign the merge request with it.  This
   1093 creates a security issue, as theoretically the payee could sign a different
   1094 contract with the purse private key, and conspire with the exchange to replace
   1095 the original contract.  In this case, the payer would be making a payment to
   1096 the "wrong" contract, and have no proof of the exchange and payee conspiring
   1097 against it.
   1098 
   1099 A simple fix seems possible: instead of having simply one public-private key
   1100 pair for a purse, we have a PayerContractKey and a PurseMergeKey pair. The payer
   1101 would pay into a purse identified by the PayerContractKey and associate a
   1102 PurseMergeKey with the purse. The payer can then safely share the
   1103 PayeeMergeKey with the payee, as it is ONLY useful for the merge and not to
   1104 sign the contract.  Payments would be made into a purse identified by the
   1105 PurseContractKey.
   1106 
   1107 When payments flow in the other direction, the split of the keys seems
   1108 unnecessary (as only a public key is transmitted anyway. However, schema-wise,
   1109 signing the contract with the PurseContractKey and the merge with the
   1110 PurseMergeKey would still work.  Only the public PurseContractKey would need
   1111 to be sent to the payer.
   1112 
   1113 
   1114 
   1115 Q / A
   1116 =====
   1117 
   1118 * Q: Why are direct payments into accounts allowed?
   1119 
   1120   * A: Direct payments into accounts may be used by the customer
   1121     to fund the expenses for using the account.  They should not
   1122     be used for payments between customers, as contract terms for
   1123     the ``/deposit`` of coins cannot be negotiated.  Furthermore,
   1124     the sender of the payment cannot be sure that the account of
   1125     the sender is still valid.
   1126 
   1127 * Q: Who "owns" a purse?  The payer or payee?
   1128 
   1129   * Both.  Ownership is shared.  Either the payer issues
   1130     a refund on the purse, or the payee claims it by merging
   1131     it with one of their accounts.
   1132 
   1133 * Q: Are purses created with a pre-determined "capacity"?
   1134 
   1135   * A: Yes.  Otherwise there would be weird failure modes when the payee
   1136     merges the purse before the payer fully deposited into it.
   1137 
   1138 * Q: Are account public keys considered private or public data?
   1139 
   1140   * A: Public.  The payer needs a signature from the payee affirming
   1141     that they accepted the contract, and this requires a key that
   1142     is linked to the KYC process to be meaningful.  However, the
   1143     software should NOT permit direct payments into foreign accounts
   1144     because it would be too easy to accidentally send payments that
   1145     nobody can receive, because the account public key is wrong/lost.
   1146 
   1147 * Q: Why do traditional merchant payments not use purses?
   1148 
   1149   * Refunds are not possible with purses after they are closed.
   1150   * The customer cannot prove that they own the contract terms
   1151     (Contract terms claiming requires interactivity that is not
   1152     possible in all W2W scenarios.) Thus, while payers can prove
   1153     that they paid, the payee may claim someone else also
   1154     bought the same product. A secure channel must thus be used to
   1155     exchange the purchase offer.
   1156 
   1157 * Q: What determines when a wad transfer can happen between two exchanges?
   1158 
   1159   * Exchanges explicitly state which other exchanges they are willing
   1160     to do wad transfers with (and how often, at what cost). This may involve
   1161     abstract policies like sharing an auditor, using the same currency and the
   1162     same (banking) protocol, or other constraints (like a specific list of
   1163     exchanges).
   1164 
   1165 * Q: What happens if the owner of a reserve never drains it?
   1166 
   1167   * Reserves are eventually closed. If the reserve is associated
   1168     with a bank account, the remaining funds are sent to that bank
   1169     account. If the reserve was created via a merge, and the owner
   1170     failed to associate a bank account with it (say because the
   1171     KYC step never happened), then the reserve balance is forfeit
   1172     to the exchange upon expiration.