041-wallet-balance-amount-definitions.rst (11919B)
1 DD 41: Wallet Balance and Amount Definitions 2 ############################################ 3 4 Summary 5 ======= 6 7 This design document discusses terminology and concepts used in the wallet 8 for balances and amounts. 9 10 Motivation 11 ========== 12 13 There are many different types of balances and amounts, and they need 14 to have a clear definition. 15 16 Furthermore, the user in some situations needs to know/decide whether 17 an amount that the user chooses includes fees or not. 18 19 20 Proposed Solution 21 ================= 22 23 Amounts 24 ------- 25 26 * ``effective``: An effective amount always represents the direct effect on the 27 wallet's balance of the same currency. 28 * ``raw``: The raw amount always refers to the amount with fees applied. 29 The exact interpretation of that depends on the transaction type. 30 * ``instructed``: An instructed amount always refers to the amount that 31 a user has explicitly specified as an input. It is not directly a property 32 of transactions, but might be added as metadata to transactions for 33 informational purposes. How the instructed amount is interpreted 34 differs based on the "instructed amount mode" that is specified 35 together with the amount. 36 * ``counterparty-effective``: An amount that **estimates** the effect 37 of the transaction of the balance (either wallet or bank account) of the other 38 party. This is usually a conservative estimate, i.e. when sending money, 39 this is the lower bound for the funds that the other party will obtain 40 *after* fees. 41 42 Instructed Amount Modes 43 ----------------------- 44 45 * ``raw-mode``: The instructed amount represents the raw amount. This is the default. 46 * ``effective-mode``: The instructed amount represents the effective amount, i.e. 47 the direct change to the balance. 48 * ``counterparty-effective-mode``: The instructed amount represents the effective 49 amount seen from the counterparty. In other words, it is the direct 50 difference to the counterparty's balance. 51 52 Balances 53 -------- 54 55 The following types of balances are defined: 56 57 - ``available``: Balance that the wallet believes will certainly be available 58 for spending, modulo any failures of the exchange or double spending issues. 59 This includes available coins *not* allocated to any 60 spending/refresh/... operation. Pending withdrawals are *not* counted 61 towards this balance, because they are not certain to succeed. 62 Pending refreshes *are* counted towards this balance. 63 This balance type is nice to show to the user, because it does not 64 temporarily decrease after payment when we are waiting for refreshes 65 66 - ``material``: Balance that the wallet believes it could spend *right now*, 67 without waiting for any operations to complete. 68 This balance type is important when showing "insufficient balance" error messages. 69 70 - ``age-acceptable``: Subset of the material balance that can be spent 71 with age restrictions applied. 72 73 - ``counterparty-acceptable``: Subset of the material balance that can be spent with a particular 74 merchant or peer-to-peer transfer. 75 76 - ``counterparty-depositable``: Subset of the receiver-acceptable balance that the counterpary 77 can accept via their supported wire methods. 78 79 - ``exchange-depositable``: Subset of the receiver-acceptable balance that the counterpary 80 can accept via their supported wire methods. 81 82 While not quite a balance, we also define the following balance-related term: 83 84 - ``max-merchant-effective-deposit-amount``: Estimated maximum amount that the 85 wallet could pay for, under the assumption that the merchant pays absolutely 86 no fees. 87 88 89 90 91 Raw Amount Definitions 92 ---------------------- 93 Raw amount is… 94 95 Manual Withdrawal 96 … the money that is wired from the user's bank account to the 97 exchange's bank account for the withdrawal. 98 99 Deposit 100 … the amount leaving the exchange account without the wire fees. 101 102 Peer Pull Credit 103 … the amount that is withdrawn from the purse (via merge reserve) that 104 the counterparty fills. 105 106 Peer Push Debit 107 … what the counterparty expects in the purse. 108 109 Peer Push Credit 110 … the purse_value in the exchange to be withdrawn. 111 112 Merchant Payment 113 … the amount the merchant should get if is not doing aggregated transaction. 114 Wire fees are ignored. 115 116 Peer Pull Debit 117 … the net value of the invoice without fees. 118 119 Refund 120 … the amount that the merchant refunded. 121 122 123 124 Details per Transaction Type 125 ---------------------------- 126 127 .. warning:: 128 129 This section is possibly incomplete / out of date. 130 131 Manual Withdrawal 132 ~~~~~~~~~~~~~~~~~ 133 134 .. code:: none 135 136 if instructed_amount mode = raw 137 raw_amount = instructed_amount 138 139 effective_amount = instructed_amount - coins.withdrawal_fee 140 141 if instructed_amount mode = effective 142 raw_amount = instructed_amount + coins.withdrawal_fee 143 144 effective_amount = instructed_amount 145 146 Deposit 147 ~~~~~~~ 148 149 .. code:: none 150 151 if instructed_amount mode = raw 152 raw_amount = instructed_amount 153 154 effective_amount = instructed_amount + coins.deposit_fee + coins.refresh_fee + wire.transfer_fee 155 156 if instructed_amount mode = effective 157 raw_amount = instructed_amount - coins.deposit_fee - coins.refresh_fee - wire.transfer_fee 158 159 effective_amount = instructed_amount 160 161 Peer Pull Credit 162 ~~~~~~~~~~~~~~~~ 163 164 .. code:: none 165 166 if instructed_amount mode = raw 167 raw_amount = instructed_amount 168 169 effective_amount = instructed_amount - coins.withdrawal_fee - purse_fee 170 171 if instructed_amount mode = effective 172 raw_amount = instructed_amount + coins.withdrawal_fee + purse_fee 173 174 effective_amount = instructed_amount 175 176 if instructed_amount mode = counterparty 177 raw_amount = instructed_amount - coins.counterparty_deposit_fee 178 179 effective_amount = instructed_amount - coins.counterparty_deposit_fee - coins.withdrawal_fee - purse_fee 180 181 counterparty_raw_amount = raw_amount 182 183 counterparty_effective_amount = raw_amount + coins.counterparty_deposit_fee 184 185 .. note:: 186 187 counterparty_effective_amount is an estimation since refresh fee is not included. 188 Refresh fee can't be calculated because depends on the coins available in the wallet 189 of the counterparty 190 191 .. note:: 192 coins.counterparty_deposit_fee is the minimum deposit_fee that can be calculated for the 193 given exchange. Counter-party may pay more if it have different preferences doing the coin 194 selection. 195 196 197 Peer Push Debit 198 ~~~~~~~~~~~~~~~ 199 200 .. code:: none 201 202 coins = select-coin-for-operation(debit, mode, instructed_amount) 203 204 if instructed_amount mode = raw 205 raw_amount = instructed_amount 206 207 effective_amount = instructed_amount + coins.deposit_fee + purse_fee 208 209 if instructed_amount mode = effective 210 raw_amount = instructed_amount - coins.deposit_fee - purse_fee 211 212 effective_amount = instructed_amount 213 214 if instructed_amount mode = counterparty 215 raw_amount = instructed_amount + coins.counterparty_withdraw_fee 216 217 effective_amount = instructed_amount - coins.counterparty_withdraw_fee - coins.withdrawal_fee - purse_fee 218 219 counterparty_raw_amount = raw_amount 220 221 counterparty_effective_amount = raw_amount - coins.counterparty_withdraw_fee 222 223 .. note:: 224 ``coins.counterparty_withdraw_fee`` is the minimum withdraw_fee that can be calculated for the 225 given exchange. Counter-party may pay more if it have different preferences doing the coin 226 selection. 227 228 229 .. note :: 230 how much wire_fee the merchant is willing to pay 231 232 merchant_wire_fee = min(wire.transfer_fee / contractTerms.amortization_factor, contractTerms.max_wire_fee) 233 234 merchant_deposit_fee = min(contractTerms.max_fee, contract_wire_fee) 235 236 237 Merchant Payment 238 ~~~~~~~~~~~~~~~~ 239 240 .. code:: none 241 242 243 instructed_amount = contractTerms.amount 244 245 coins = select-coin-for-operation(debit, mode, raw_amount) 246 247 raw_amount = instructed_amount - merchant_deposit_fee 248 249 effective_amount = instructed_amount + coins.deposit_fee + coins.refresh_fee + (wire.transfer_fee - merchant_wire_fee) 250 251 .. note:: 252 The current coin-selection algorithm the order_price is neither raw_amount nor effective_amount. 253 We can calculate the raw_amount of the payment as (contractTerms.amount - max_merchant_fee) and then this 254 operation becomes equivalent than a deposit (in terms of fee calculation). 255 256 Peer Push Credit 257 ~~~~~~~~~~~~~~~~ 258 259 260 ``instructed_amount`` = p2pContract.amount 261 262 ``coins`` = select-coin-for-operation(credit, mode, raw_amount) 263 264 ``raw_amount`` = instructed_amount 265 266 ``effective_amount`` = instructed_amount - coins.withdrawal_fee 267 268 .. note:: 269 In the case that the withdrawal_fee of the coin selection for the push-credit amount 270 is higher than the wire_fee of the exchange, can the wallet ask the exchange to make 271 a wire transfer of the purse instead of proceeding? 272 273 Peer Pull Debit 274 ~~~~~~~~~~~~~~~ 275 276 277 ``instructed_amount`` = p2pContract.amount 278 279 ``coins`` = select-coin-for-operation(debit, mode, raw_amount) 280 281 ``raw_amount`` = instructed_amount 282 283 ``effective_amount`` = instructed_amount + coins.deposit_fee + coins.refresh_fee + wire.transfer_fee 284 285 Refund 286 ~~~~~~ 287 288 289 ``instructed_amount`` = refund.amount 290 291 ``raw_amount`` = instructed_amount 292 293 ``effective_amount`` = instructed_amount - refund_fee - refresh_fee 294 295 .. note:: 296 There may be the case that the merchant should refund all the value of the purchase 297 and that may include paying for the refund_fee. 298 299 Is there a way that the merchant can initiate a refund of purchase + refund_fee so 300 the wallet will get the same effective_amount? 301 302 303 304 Illustrative Example 305 -------------------- 306 307 .. warning:: 308 309 This section is possibly incomplete / out of date. 310 311 To explain the differences between raw, effective and instructed amounts, consider the following scenario: Alice wants to send money 312 to Bob via a P2P push payment. 313 314 Example 1: 315 316 * Alice starts a withdrawal of ``KUDOS:10`` from her bank's web interface into her Taler 317 wallet. The instructed amount is ``KUDOS:10`` and (by default for bank-integrated withdrawals), 318 the mode is ``raw-mode``. After fees, ``KUDOS:9.8`` arrive in her Taler wallet. 319 320 Example 3: 321 322 * Alice wants to pay for a ``KUDOS:10`` monthly magazine subscription. Her Taler wallet is empty though. 323 * She starts withdrawal through her Android wallet app, where she selects ``KUDOS:10`` as the instructed 324 amount with ``mode=effective-mode``. This translates to ``amountEffective=KUDOS:10`` and ``amountRaw=KUDOS:10.10``. 325 * Alice is redirected to her banking app where she transfers ``KUDOS:10.10`` to the exchange. 326 * Her Taler wallet balance will be ``KUDOS:10.10`` after the withdrawal completes. 327 328 Note that on the amount she chooses and the fees / denom structure of the exchange, the ``amountEffective`` might be *higher* 329 than the instructed amount. 330 331 FIXME(dold): That flow does not work if withdrawal starts in the bank. Maybe there needs to be a mechanism 332 where the wallet tells the bank the adjusted amount that needs to be transferred? That would be a new 333 feature in the bank integration API. 334 335 Example 4: 336 337 * Alice has ``KUDOS:10`` in her wallet. 338 * Alice wants to initiate a peer-push payment with ``amountInstructed=KUDOS:8`` 339 and ``mode=effective-mode``. That means that after the payment, she expects 340 exactly ``KUDOS:2`` to remain in her wallet. 341 * Due to the fee configuration, her wallet computes ``amountRaw=KUDOS:7.5`` and ``amountEffective=KUDOS:7.8``. 342 The effective amount in this case does **not** equal the instructed amount, despite the ``mode=effective-mode``. 343 That's because there no amount that can be spend so that the spend amount with resulting refresh 344 fees equal ``KUDOS:8``. 345 * Alice confirms the peer-push payment initiation, and exactly ``KUDOS:7.5`` are credited 346 to the purse that her wallet creates. 347 * Bob merges the purse into his reserve. Bob's wallet automatically withdraws 348 from the reserve, and his wallet balance increases by ``KUDOS:7.1``, since 349 withdrawal fees are deducted. 350 351 352 Discussion / Q&A 353 ================ 354 355 (This should be filled in with results from discussions on mailing lists / personal communication.)