taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

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.)