From 0616bd661ed6f62cf3c95f3779fe06451a88ffa9 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 20 Apr 2021 01:12:47 +0200 Subject: more thoughts, incomplete --- design-documents/013-peer-to-peer-payments.rst | 137 +++++++++++++++++-------- 1 file changed, 95 insertions(+), 42 deletions(-) diff --git a/design-documents/013-peer-to-peer-payments.rst b/design-documents/013-peer-to-peer-payments.rst index df0fc51b..35b81267 100644 --- a/design-documents/013-peer-to-peer-payments.rst +++ b/design-documents/013-peer-to-peer-payments.rst @@ -72,6 +72,7 @@ New Terminology private key. * A ``wad`` is an exchange-to-exchange wire transfer that wires money into a group of accounts at the target exchange. +* FIXME: below we now have **pouch** and **purse**. Same? Different? Confusing! Proposed Solution @@ -114,7 +115,6 @@ Account creation and withdrawal when requested; full account histories for accounts with an insufficient balance cannot be requested -- except of course the wallet could simply top up the account balance first, see below). - 7. If the exchange has received a **deposit** or **merge** into an account, or received an inbound wire transfer from a **wad** matching the account (see below), it adds the respective amount(s) @@ -147,6 +147,59 @@ Account deletion report should contain a special note for all of these account deletions. +C2C Payment Metadata +-------------------- + +The standard Taler Customer-to-Merchant payments always use a contract terms +JSON object to record the modalities of the payment and the resulting +obligations of a successful payment. + +The contract terms concept does not directly carry over to C2C payments, +because: + +* Either party may initiate the payment. +* The payee does not have a merchant public key, and + at the time of payment initiation, the payee account might not yet + be known. +* There is no nonce that the customer generates and uses to prove that they + uniquely "own" the contract terms. +* There is no negotiation of trusted auditors / exchanges possible. + +Metadata for C2C payments can be exchanged in two ways: + +1. Inline, as part of the payment request / payment offer. In this case, + both parties are already aware of the contract's contents and + the exchange's contract exchange facility is simply not used. +2. The payer can store a contract with the exchange by POSTing + an encrypted contract to the exchange at ``/contracts``. + a. The contract must be encrypted to a purse or account private key. + The corresponding public key(s) should be part of the encrypted + payload. + b. The exchange may charge a **contract fee** for + storing the contract. Note that a purse may theoretically receive + multiple inbound payments, so the contract storage facility is + provided independently of a purse or account. + c. The fee for contract storage is taken from coins attached to the + contract storage request, independent of whether payer or + payee is making a request for contract storage. The coin signature + includes the contract hash and the desired expiration date. + d. The exchange may limit the contract size and storage duration. + e. Encrypted contracts created by the payee must include a signature + with the account private key of the payee, thereby affirming that + the contract was pre-approved by the account owner. + f. The uploaded information must include an expiration date for + the offer, after which the associated transaction expires if + it has not concluded. + g. The exchange deletes encrypted contract at this expiration + date, and auto-refunds coins in **purses** with deposits + matching expired contracts. + + .. note:: + + While the **refund fee** amount can be reused, these types of refunds + are not approved by a merchant's signature. Thus, we will need + a new message type in the coin history to represent these events. + Payment into an unknown account ------------------------------- @@ -163,27 +216,52 @@ Payment into an unknown account 4. The payee uses the new ``/purse/$PURSE_PUB`` endpoint to retrieve the purse history, which includes all deposits and withdrawals involving the purse. -5. The payee can then POST to ``/purse/$PURSE_PUB/merge`` a +5. *Optional*: Deposits with a non-zero contract hash + have an underlying contract, which the payee fetches using + a new ``/contracts/$CONTRACT_HASH`` endpoint and then + decrypts (if they do not have the contract already). The + contract terms are shown to the user to have the user agree + to the contract before proceeding with the next step. +6. The payee can then POST to ``/purse/$PURSE_PUB/merge`` a request signed by the purse's private key to **merge** the - funds into an account. The signature is only over a salted - hash of the account public key, thus avoiding disclosure of - the account public key in the purse history. The exchange - processes the merge request akin to the logic for payments + funds into an account. The signature is over a salted + hash of the account public key and the list of deposit + identifiers of deposits to be merged. This avoids disclosure of + the account public key in the purse history. +7. The exchange processes the merge request akin to the logic for payments into known accounts, as detailed below, except that no **deposit fees** are charged at this time. The exchange confirms the merge, allowing the payee to instantly affirm to the user that the amount is inbound (even if it may not - be instantly available). + be instantly available if the user did not complete the + KYC process for the account). Payment directly into a known account at the same exchange ---------------------------------------------------------- -1. If the payer knows the payee's account and uses the same exchange, +FIXME: do we really want to support payments directly into **accounts**? +That exposes the long-term account-pub of the payer. Maybe we +need to mandate the use of a **pouch** or **purse** (which term???). + +1. The payee receives a + ``payto://taler/{EXCHANGE_URL}/{ACCOUNT_PUB}[#CONTRACT_HASH]?`` + payment request, possibly together with a plaintext + contract. +2. *Optional*: If the contract hash is provided but the + contract is unknown, the payee retrieves the contract + and account signature from the exchange before making + the payment. +3. Then, if the payer uses the same exchange, they may perform an ordinary ``/deposit`` operation, paying the usual **deposit fee**. -2. The exchange detects the use of the ``taler`` wire method, and - directly credits the target account. +4. The exchange detects the use of the ``taler`` wire method, and + directly credits the target account (without charging a + **wire fee**). +5. The account owner notices the incoming transaction into + the account and withdraws the funds (once the KYC requirements + have been met). + Payment into known account at a remote exchange @@ -195,7 +273,8 @@ Payment into known account at a remote exchange the base URL of the target exchange, and the target account, paying a **deposit fee** and a new **wad fee**. The **wad fees** can be used to cover the cost of the exchange-to-exchange wire transfer. -2. The payer's exchange creates a **wad** grouping all wad requests, executing +2. The payer's exchange creates a **wad** by grouping all wad requests + to the same target exchange. It executes the transaction when either the **wad threshold** (maximum number of transactons aggregated per wad) or the **wad delay** (maximum delay for transfers) has been reached. @@ -226,46 +305,20 @@ Payment into known account at a remote exchange need to be extended to allow passing inbound wire transfers with WTID and exchange base URL to the exchange. Furthermore, another tool is needed to lookup the **wad** data at remote exchanges. +7. If a **wad** contains a deposit with a contract hash, the receiving + exchange must take note and setup a permanent redirect for requests + about that contract hash to the original exchange. -C2C Payment Metadata --------------------- - -The standard Taler Customer-to-Merchant payments always use a contract terms -JSON object to record the modalities of the payment and the resulting -obligations of a successful payment. - -The contract terms concept does not directly carry over to -C2C payments, because: - -* Either party may initiate the payment -* The payee does not have a merchant public key, and - at the time of payment initiation, the payee account might not yet - be known. -* There is no nonce that the customer generates and uses to prove that they - uniquely "own" the contract terms. -* There is no negotiation of trusted auditors / exchanges possible or necessary. - -Metadata for C2C payments can be exchanged in two ways: - -1. Inline, as part of the payment request / payment offer. -2. As an annotation on the purse, encrypted with the purse's public key. The - exchange may charge for storing the annotation. - In case of a "payment request purse", the fee should be - taken from an account provided by the payee (which may even - offer a limited number of free P2P payment initiations per time period). - In case of a "payment offer purse", the fee should be taken from the - coins deposited into the purse. - Examples --------- Cross-exchange C2C payment request: -* Bob borrowed 15 Eur from Alice to buy a train ticket. A few days later, +* Bob borrowed 15 EUR from Alice to buy a train ticket. A few days later, Alice wants her money back. She creates a request for payment in her wallet. - The wallet creates a pouch for 15 Eur at the only exchange that Alice is currently + The wallet creates a pouch for 15 EUR at the only exchange that Alice is currently using. The wallet shows her a ``taler://payment-request/{EXCHANGE_URL}/{POUCH_PRIV}?i=Please+pay+me+Bob`` link that she can share with Bob. Bob receives the link and opens it with -- cgit v1.2.3