031-invoicing.rst (7702B)
1 DD 31: Invoicing 2 ################ 3 4 :Design status: Accepted 5 :Implementation status: Implemented 6 :DD shepherd: TBD 7 :Historical contributors: Christian Grothoff 8 :First published: 2022-08-20 9 :Last substantive change: 2024-02-08 10 :Implementation evidence: exchange (2022-09-18, 2022-09-27, 2022-10-09) 11 :Normative references: :doc:`../core/api-exchange` 12 13 .. note:: 14 15 The current exchange API is authoritative for the implemented reserve 16 open, attestation and close operations. 17 18 Summary 19 ======= 20 21 This document proposes new endpoints to support invoicing. 22 23 24 Motivation 25 ========== 26 27 We want to support a limited number of PULL payment requests where a purse is 28 created for a reserve without immediately requiring a purse fee. However, we 29 must prevent users from excessively creating purses (and uploading contracts) 30 as we do not want the exchange to be abused as a storage layer. Furthermore, 31 it would be good if the user sending a PULL payment request was properly 32 identified to the payer. 33 34 This design addresses bugs #7269 and #7274. 35 36 37 Requirements 38 ============ 39 40 * Effectively limit the number of open purses created by each individual 41 (or require purse fees if limit is exceeded). 42 43 * Ensure user has done KYC before doing a merge. 44 (Assuming the exchange does KYC at all.) 45 46 * Use information from KYC process to help payer identify payee. 47 48 * Reasonable UX and overall design impact. 49 50 * Wallets may want to pay for the reserve with coins 51 (reserve fresh, not created via bank transfer). 52 53 Unclear in the current proposal are: 54 55 * Here (and in other places!), the payment of the KYC 56 fee remains, eh, obscure. This should probably be 57 part of the KYC endpoints, and not for each 58 KYC-trigger. 59 60 * Proposed table structure does not properly capture 61 if user paid extra for more purses (I could open 62 for 3 years, then pay for 5x purses in year 1, but 63 should not automatically get 5x purses in years 2/3). 64 65 66 Proposed Solution 67 ================= 68 69 Allow users to tie their identity to a reserve "on demand" and when doing so 70 charge the ``account_fee``, bump the number of open purses threshold in the 71 ``reserves`` table and stop auto-closing of the reserve. This will ensure that 72 the users can withdraw the reserve balance into their wallet even after a 73 longer time period. This helps if the invoice is paid after a significant 74 delay. Introduce a way to force an immediate closure of a reserve, allowing 75 P2P reserve from invoices to be send to a bank account (this allows a wallet 76 to be used for convenient invoicing and not strictly require the wallet to 77 receive the funds). 78 79 The solution needs three new tables for: 80 81 * account creation data: 82 83 - serial 84 - timestamp 85 - signature affirming desire to create account 86 - KYC requirement row 87 88 * account creation payment data: 89 90 - serial (for replication) 91 - coin signature (affirming payment) 92 - amount contributed 93 - account creation link (serial row ID) 94 95 * reserve closure request data: 96 97 - serial (for replication) 98 - timestamp 99 - reserve signature 100 - target account payto:// URI 101 102 103 Specifically, the solution involves three new endpoints: 104 105 Opening reserves 106 ---------------- 107 108 * This new endpoint ``/reserves/$RID/open`` allows the user to 109 pay (for a year) to create a fixed number of purses and 110 to keep the reserve ``open`` (preventing auto-close); the 111 endpoint typically triggers a first (balance-independent) 112 KYC process (451) for a new KYC operation ``invoicing`` 113 (unless KYC is off). 114 115 * Upon completion of the ``invoicing`` KYC, the wallet 116 must again try to ``/open``. If successful, the wallet 117 may be asked to pay the annual fee (402). However, 118 usually the wallet should be aware of the fee, and already 119 have included a suitable deposit in the POST to the endpoint. 120 121 * Once the annual fee is paid, the now open 122 reserve is set to a non-zero counter of allowed concurrently 123 open purses, and the expiration time of the reserve is bumped 124 to the end of the time period for which the fee was paid. 125 126 Reserve Attestation 127 ------------------- 128 129 * This new endpoint ``/reserves/$RID/attest`` allows the user to 130 obtain exchange-signed KYC information about themselves. 131 This will basically be a list of (GANA standardized) attributes 132 and exchange signatures. The user can then choose which of 133 these attributes to include when invoicing. The available 134 set of attributes may differ depending on the KYC providers 135 configured and the attributes returned by the KYC logic. 136 We may choose to not use any fancy cryptography here, and 137 simply sign the different attributes individually. However, 138 we should always sign over the ``$RID`` to ensure that the 139 resulting signatures are meaningful. 140 141 * When receiving an invoice (PULL payment request), we may want to 142 mandate a certain minimal set of attributes that *should* always 143 be included, and if that is absent warn the receiver that the 144 sender of the invoice did not properly identify themselves. 145 146 * By making this a new endpoint, the client can re-request 147 the signatures on-demand. This is useful if we use the 148 EdDSA online signatures of the exchange, which likely expire 149 long before the user changes their attributes. 150 151 152 Closing reserves 153 ---------------- 154 155 * This new endpoint ``/reserves/$RID/close`` allows the user to 156 force-close a reserve that has not yet expired. This is useful 157 in case invoices have been paid into the reserve and the 158 user wants to get their money out. The ``close`` endpoint 159 must be provided with an appropriate payto://-URI as 160 reserves that were filled by P2P merge operations may not 161 already have an associated bank account (empty ``reserves_in`` 162 table). 163 164 165 Alternatives 166 ============ 167 168 We could require the target account to be already specified on ``open``. 169 However, that prevents people from invoicing that have no account (or we'd 170 have to allow ``payto://void/``, which then prevents people from closing later 171 if they got a bank account at a later stage). 172 173 We could allow an amount to be specified on ``close`` to partially wire the 174 funds in a reserve. However, reserves are not supposed to be used as bank 175 accounts (either to wallet *or* exceptionally to bank account, please!), and 176 this would conflict with the current implementation of the 177 **taler-exchange-closer**. So no amount is likely better for minimal 178 regulatory and implementation trouble. 179 180 Closing a reserve could also prevent the future use of the reserve for 181 invoicing. Right now, the specification allows this to continue, effectively 182 allowing users to repeatedly close an account to drain its funds to a bank 183 account instead of into a wallet. 184 185 We could mandate a fixed set of attributes. However, it is unclear whether all 186 exchanges will always have KYC providers enabled that offer any particular set 187 of attributes. It is conceivable that some exchanges may not run with any kind 188 of KYC, or just with phone-number validation, while others may require 189 government IDs but not phone numbers. So we can easily end up with completely 190 disjunct sets of attributes across operators. 191 192 We could not warn users if *insufficient* attributes were provided in an 193 invoice. However, that seems dangerous, especially as fake invoices are a 194 common attacker trick. 195 196 We could use attribute-based credentials (ABC) for the attestations. Benefits 197 and (complexity) drawbacks of such a change should be discussed with Martin. 198 199 200 Drawbacks 201 ========= 202 203 Quite a bit of work to implement. 204 205 206 Discussion / Q&A 207 ================ 208 209 (This should be filled in with results from discussions on mailing lists / personal communication.)