summaryrefslogtreecommitdiff
path: root/design-documents/031-invoicing.rst
blob: 0fcc88fd0fada3f7e25892e0770069f56294ba8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
DD 31: Invoicing
################

Summary
=======

This document proposes new endpoints to support invoicing.


Motivation
==========

We want to support a limited number of PULL payment requests where a purse is
created for a reserve without immediately requiring a purse fee. However, we
must prevent users from excessively creating purses (and uploading contracts)
as we do not want the exchange to be abused as a storage layer.  Furthermore,
it would be good if the user sending a PULL payment request was properly
identified to the payer.

This design addresses bugs #7269 and #7274.


Requirements
============

  * Effectively limit the number of open purses created by each individual
    (or require purse fees if limit is exceeded).

  * Ensure user has done KYC before doing a merge.
    (Assuming the exchange does KYC at all.)

  * Use information from KYC process to help payer identify payee.

  * Reasonable UX and overall design impact.

  * Wallets may want to pay for the reserve with coins
    (reserve fresh, not created via bank transfer).

Unclear in the current proposal are:

  * Here (and in other places!), the payment of the KYC
    fee remains, eh, obscure. This should probably be
    part of the KYC endpoints, and not for each
    KYC-trigger.

  * Proposed table structure does not properly capture
    if user paid extra for more purses (I could open
    for 3 years, then pay for 5x purses in year 1, but
    should not automatically get 5x purses in years 2/3).


Proposed Solution
=================

Allow users to tie their identity to a reserve "on demand" and when doing so
charge the ``account_fee``, bump the number of open purses threshold in the
``reserves`` table and stop auto-closing of the reserve. This will ensure that
the users can withdraw the reserve balance into their wallet even after a
longer time period. This helps if the invoice is paid after a significant
delay. Introduce a way to force an immediate closure of a reserve, allowing
P2P reserve from invoices to be send to a bank account (this allows a wallet
to be used for convenient invoicing and not strictly require the wallet to
receive the funds).

The solution needs three new tables for:

  * account creation data:

    - serial
    - timestamp
    - signature affirming desire to create account
    - KYC requirement row

  * account creation payment data:

    - serial (for replication)
    - coin signature (affirming payment)
    - amount contributed
    - account creation link (serial row ID)

  * reserve closure request data:

    - serial (for replication)
    - timestamp
    - reserve signature
    - target account payto:// URI


Specifically, the solution involves three new endpoints:

Opening reserves
----------------

  * This new endpoint ``/reserve/$RID/open`` allows the user to
    pay (for a year) to create a fixed number of purses and
    to keep the reserve ``open`` (preventing auto-close); the
    endpoint typically triggers a first (balance-independent)
    KYC process (451) for a new KYC operation ``invoicing``
    (unless KYC is off).

  * Upon completion of the ``invoicing`` KYC, the wallet
    must again try to ``/open``. If successful, the wallet
    may be asked to pay the annual fee (402).  However,
    usually the wallet should be aware of the fee, and already
    have included a suitable deposit in the POST to the endpoint.

  * Once the annual fee is paid, the now open
    reserve is set to a non-zero counter of allowed concurrently
    open purses, and the expiration time of the reserve is bumped
    to the end of the time period for which the fee was paid.

Reserve Attestation
-------------------

  * This new endpoint ``/reserve/$RID/attest`` allows the user to
    obtain exchange-signed KYC information about themselves.
    This will basically be a list of (GANA standardized) attributes
    and exchange signatures. The user can then choose which of
    these attributes to include when invoicing.  The available
    set of attributes may differ depending on the KYC providers
    configured and the attributes returned by the KYC logic.
    We may choose to not use any fancy cryptography here, and
    simply sign the different attributes individually. However,
    we should always sign over the ``$RID`` to ensure that the
    resulting signatures are meaningful.

  * When receiving an invoice (PULL payment request), we may want to
    mandate a certain minimal set of attributes that *should* always
    be included, and if that is absent warn the receiver that the
    sender of the invoice did not properly identify themselves.

  * By making this a new endpoint, the client can re-request
    the signatures on-demand. This is useful if we use the
    EdDSA online signatures of the exchange, which likely expire
    long before the user changes their attributes.


Closing reserves
----------------

  * This new endpoint ``/reserve/$RID/close`` allows the user to
    force-close a reserve that has not yet expired. This is useful
    in case invoices have been paid into the reserve and the
    user wants to get their money out.  The ``close`` endpoint
    must be provided with an appropriate payto://-URI as
    reserves that were filled by P2P merge operations may not
    already have an associated bank account (empty ``reserves_in``
    table).


Alternatives
============

We could require the target account to be already specified on ``open``.
However, that prevents people from invoicing that have no account (or we'd
have to allow ``payto://void/``, which then prevents people from closing later
if they got a bank account at a later stage).

We could allow an amount to be specified on ``close`` to partially wire the
funds in a reserve. However, reserves are not supposed to be used as bank
accounts (either to wallet *or* exceptionally to bank account, please!), and
this would conflict with the current implementation of the
**taler-exchange-closer**. So no amount is likely better for minimal
regulatory and implementation trouble.

Closing a reserve could also prevent the future use of the reserve for
invoicing.  Right now, the specification allows this to continue, effectively
allowing users to repeatedly close an account to drain its funds to a bank
account instead of into a wallet.

We could mandate a fixed set of attributes. However, it is unclear whether all
exchanges will always have KYC providers enabled that offer any particular set
of attributes. It is conceivable that some exchanges may not run with any kind
of KYC, or just with phone-number validation, while others may require
government IDs but not phone numbers. So we can easily end up with completely
disjunct sets of attributes across operators.

We could not warn users if *insufficient* attributes were provided in an
invoice. However, that seems dangerous, especially as fake invoices are a
common attacker trick.

We could use attribute-based credentials (ABC) for the attestations. Benefits
and (complexity) drawbacks of such a change should be discussed with Martin.


Drawbacks
=========

Quite a bit of work to implement.


Discussion / Q&A
================

(This should be filled in with results from discussions on mailing lists / personal communication.)