|author||Christian Grothoff <firstname.lastname@example.org>||2021-04-20 01:12:47 +0200|
|committer||Christian Grothoff <email@example.com>||2021-04-20 01:12:47 +0200|
more thoughts, incomplete
1 files 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 df0fc51..35b8126 100644
@@ -72,6 +72,7 @@ New Terminology
* 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!
@@ -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,
+* 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
+ 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
+ payment request, possibly together with a plaintext
+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.
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
link that she can share with Bob. Bob receives the link and opens it with