summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-04-06 13:38:42 -0300
committerSebastian <sebasjm@gmail.com>2023-04-06 13:38:42 -0300
commitb4e98ac71d3f8d31d00179ec736f3ad26b80272a (patch)
tree4035afb3f4e34066e13f1eab5d0adb9bcd25ad7d /design-documents
parent8582529fba0781c36b5f1b60acbadf1248e4026c (diff)
downloaddocs-b4e98ac71d3f8d31d00179ec736f3ad26b80272a.tar.gz
docs-b4e98ac71d3f8d31d00179ec736f3ad26b80272a.tar.bz2
docs-b4e98ac71d3f8d31d00179ec736f3ad26b80272a.zip
* added initial state description
* new description for aborted * new description delete action * added initial state in every tx type * added questions with (??) * removed common state when it doesn't add extra info
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/037-wallet-transactions-lifecycle.rst230
1 files changed, 143 insertions, 87 deletions
diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst
index b086787e..3cc807e4 100644
--- a/design-documents/037-wallet-transactions-lifecycle.rst
+++ b/design-documents/037-wallet-transactions-lifecycle.rst
@@ -18,11 +18,16 @@ Proposed Solution
Common States
-------------
-The following states apply to multiple different transactions. They can
-have transaction-specific sub-states, denoted by ``state(substate)``.
+The following states apply to multiple different transactions. Only pending
+and aborting have transaction-specific sub-states, denoted by ``state(substate)``.
+
+``initial``: The initial state is the result a user interaction. A transaction
+may have more than one initial state (if it is started in multiple ways) or none
+(if it's the result of another process)
``pending``: A pending transaction waits for some external event/service.
-The transaction stays pending until its change on the wallet's material balance is finished.
+The transaction stays pending until its change on the wallet's material balance
+is finished. Any pending state can be suspended and resumed.
There are some other distinctions for pending transactions:
@@ -42,15 +47,10 @@ never has a ``lastError`` but is considered successful.
complete the transaction, the wallet is taking active steps to abort it. The ``lastError``
indicates errors the wallet experienced while taking active steps to abort the transaction.
-.. attention::
- Should there be an abortReason for aborted transactions?
-
- sebasjm: yes, although it doesn't mean that the user need to add this information
- manually. The information we save in the abort operation can help the user to know
- how and when the operation was aborted.
-
``aborted``: Similar to a ``done`` transaction, but the transaction was successfully aborted
-instead of successfully finished.
+instead of successfully finished. It will have the information of when (timestamp) it was
+aborted and in which pending sub-state the abort action was initiated. Also, we can
+include more information information relevant to the transaction in `abortReason`
``suspended``: Similar to a ``aborted`` transaction, but the transaction was could be
resumed and may then still succeed.
@@ -71,7 +71,8 @@ Transitions are actions or other events.
completely deletes the transaction in the database. Depending on the type of
transaction, some of the other data *resulting* from the transaction might
still survive deletion. For example, deleting a withdrawal transaction does not
-delete already successfully withdrawn coins.
+delete already successfully withdrawn coins. Deleting is only safe (no money lost)
+on initial and final state (failed, aborted, done)
``[action:retry]``: Retrying a transaction *(1.)* stops ongoing long-polling
requests for the transaction *(2.)* resets the retry timeout *(3.)* re-runs the
@@ -82,7 +83,7 @@ states: ``pending(*)`` and ``aborting(*)``.
Should we show the retry timeout in the UI somewhere? Should we show it in dev mode?
- sebasjm: Since the wallet will retry anyway, maybe is better if we replace the "retry"
+ SEBASJM: Since the wallet will retry anyway, maybe is better if we replace the "retry"
button with a "try now" button and a side text "retrying in xxx seconds"
``[action:abort]``: Aborting a transaction either directly stops processing for the
@@ -146,7 +147,7 @@ rotations can be expected to be there to rotate the key, and not to adjust the w
And in the 1:1M case that the fee does *increase*, it's again unlikely to matter much to the
user. So special-casing this and testing this is IMO just not worth it.
-* ``pending(bank-register-reserve)``
+* ``initial(bank-register-reserve)``
Initial state for bank-integrated withdrawals. The wallet submits the reserve public key
and selected exchange to the bank (via the bank integration API).
@@ -160,9 +161,16 @@ user. So special-casing this and testing this is IMO just not worth it.
the user has to complete a 2FA step to confirm that the money is wired to the chosen
exchange.
+ (??) is this needed? let say that the money is wired but the signal
+ never of the bank confirmation reached the wallet, what should happen?
+
* ``[poll-success] => pending(exchange-wait-reserve)``
* ``[action:abort] => aborting(wallet-to-bank)``
+* ``initial(manual-withdraw)``
+
+ * ``[process-success] => pending(exchange-wait-reserve)``: reserve created
+
* ``pending(exchange-wait-reserve)``
Initial state for manual withdrawals.
@@ -232,7 +240,10 @@ and if that already failed should have update the balance with a transaction
history entry saying something like "coins expired, offline too long" or
something like that.
-* ``pending(download-proposal)``
+(??) If transaction can be aborted while in-progress then it should return
+instructedAmount, effectiveAmount and the affectedAmount (partially effective amount)
+
+* ``initial(download-proposal)``
Initial state. Download (claim) the proposal from the merchant.
@@ -243,6 +254,8 @@ something like that.
of transitioning the UI into a ``pending(repurchase-session-reset)``
on a different transaction (which before was in ``done``).
+ (??) should not reset another transaction?
+
* ``pending(proposed)``
Let the user accept (or refuse) the payment.
@@ -258,28 +271,23 @@ something like that.
* ``pending(submit-payment)``
+Submit coin by coin (or in bulk groups) until payment is complete.
+
* ``[action:abort] => aborting(refund)``
- * ``[processed-success(auto-refund-enabled)] => pending(paid-auto-refund-check)``
+ * ``[processed-success(auto-refund-enabled)] => pending(refundable)``
+ * ``[processed-success(auto-refund-disabled)] => done``
* ``[processed-error(expired)] => aborting(refresh)`` XXX: If the order is expired but the payment
succeeded partially before, do we still try an abort-refund? CG: YES, but of course
we probably should use the ``expired`` transition above a few seconds before the
offer *actually* expires to avoid this problem in 99.9% of real-world scenarios
("prevent last-second payments client-side")
-* ``pending(submit-payment-replay)``
+* ``pending(refundable)``
-* ``pending(paid-auto-refund-check)``
+The payment succeed but if auto-refund-check is active it will be checking for refunds
* ``[auto-refund-timeout] => done``
-* ``pending(paid-check-refund)``
-
-* ``done``
-
- * ``[action:check-refund] => pending(paid-check-refund)``
- * ``[action:pay-replay] => pending(submit-payment-replay)``
- * ``[action:delete] => deleted``
-
* ``aborting(refund)``
* ``[processed-success] => aborted(refunded)``
@@ -306,6 +314,14 @@ Transaction Type: Refund
A refund is a pseudo-transaction that is always associated with a merchant payment transaction.
+* ``initial``
+
+ The wallet has downloaded metadata for the refund from the merchant and
+ stored it in the database. The user needs to accept/refuse it.
+
+ * ``[processed-success] => pending``: the refund is accepted
+ * ``[processed-abort] => aborted`` : the refund is not accepted
+
* ``pending``
A refund is pending when the merchant is getting a non-permanent error from
@@ -314,21 +330,13 @@ A refund is a pseudo-transaction that is always associated with a merchant payme
* ``[processed-success] => done``
* ``[processed-error] => failed``
-* ``done``
-
* ``failed``
A failed refund can technically still transition to ``done``, because the wallet
doesn't query some refund resource, but the purchase for refunds. Thus, a previously
- failed refund can suddenly transition to ``done``.
-
- * ``[payment-refund-processed-success] => done``
-
-* ``*``
+ failed refund can suddenly transition to ``done``.
- Transitions from any state:
-
- * ``[action:delete] => deleted`` Deleting a refund has no effect on the wallet's balance.
+ (??) separate transient error vs permanent error ?
Transaction Type: Refresh
-------------------------
@@ -349,13 +357,17 @@ cannot give details).
* ``done``
+(??) should this be like ``pending(exchange-wait-reserve)`` from withdraw?
+(??) can refresh trigger kyc?
+
+
Transaction Type: Tip
---------------------
-* ``pending(initial)``
+* ``initial``
The wallet has downloaded metadata for the tip from the merchant and
- stored it in the databse. The user needs to accept/refuse it.
+ stored it in the database. The user needs to accept/refuse it.
* ``[tip-expired] => failed(expired)``
* ``[action:accept-tip] => pending(pickup)``
@@ -364,9 +376,14 @@ Transaction Type: Tip
* ``pending(pickup)``
* ``[tip-expired] => failed(expired)``
+ * ``[processed-kyc-required] => pending(kyc-required)``
* ``[processed-success] => done``
* ``[action:abort] => aborted``
+* ``pending(kyc-required)``
+
+ * ``[poll-success] => pending(pickup)``
+
Transaction Type: Deposit
-------------------------
@@ -379,36 +396,48 @@ _optional_ dialog ("Balance reduced by X as wallet state was not up-to-date
(did you restore from backup?). Consequently, the fees for this transactions
increased from Y to Z. [Abort] [Continue] + checkbox: [X] Do not ask again."
-* ``pending(initial)``
+* ``initial``
- The wallet deposits coins with the exchange.
+ Deposit is created, effective amount is removed from balance
- * ``[processed-success] => pending(track)``
- * ``[action:abort] => aborting(refund)``
+ * ``[processed-success] => pending(submit-deposit)``: reserve created
+ * ``[action:abort] => aborted``
-* ``pending(kyc-required)``
+* ``pending(submit-deposit)``
- The exchange requires KYC before it can proceed with the withdrawal. Note that
- we only find this out via the tracking API *after* the deposit has been
- successfully made.
+Submit coin by coin (or in bulk groups) until deposit is completed.
- * ``[poll-success] => pending(track)``
* ``[action:abort] => aborting(refund)``
+ * ``[processed-success] => pending(track)``
+ * ``[processed-error] => aborting(refresh)``
* ``pending(track)``
+All the coins were submitted, waiting to be wired.
+
* ``[poll-success] => done``
- * ``[processed-kyc-required] => pending(kyc-required)``
+ * ``[action:abort] => aborting(partially-wired)``
* ``aborting(refund)``
- * ``[processed-success] => aborting(refresh)``
- * ``[processed-error] => aborting(refresh)`` XXX Shouldn't this be some error state?
+Trying to get the deposited amount back from the exchange.
+
+ ``[processed-success] => aborting(refresh)``
+ ``[processed-error] => aborting(refresh)`` XXX Shouldn't this be some error state?
+(??) why it moves to the same state?
+
+* ``aborting(partially-wired)``
+
+Should cancel all pending wire transfer.
+
+ ``[processed-success] => aborting(refund)``
+ ``[processed-error] => aborting(refresh)`` XXX Shouldn't this be some error state?
+
* ``aborting(refresh)``
- * ``[processed-success] => aborted``
- * ``[processed-error] => failed``
+ ``[processed-success] => aborted``
+ ``[processed-error] => failed``
* ``done``
@@ -421,14 +450,13 @@ to another wallet.
States and transitions:
-* ``pending(initial)``
+* ``initial``
In this state, the user is not yet able to send the payment to somebody else.
* ``[action:abort] => aborted``: The payment is aborted early, before the wallet even had the chance to create a purse.
No fees are incurred.
- * ``[action:delete] => deleted``: No funds are lost.
- * ``[processsing-success] => pending(purse-created)``: The wallet was able to successfully create a purse.
+ * ``[processing-success] => pending(purse-created)``: The wallet was able to successfully create a purse.
* ``pending(purse-created)``
@@ -436,7 +464,7 @@ States and transitions:
* ``[action:abort] => aborting(delete-purse)``: The user aborts the P2P payment. The wallet tries to reclaim money in the purse.
* ``[purse-timeout] => aborting(refresh)``: The other party was too slow.
- * ``[poll-success] => done``: The other party has accepted the payment.
+ * ``[poll-success] => pending(refundable)``: The other party has accepted the payment.
* ``[poll-error] => aborting(refresh)``: The exchange claims that there is a permanent error regarding the purse.
* ``aborting(delete-purse)``
@@ -444,7 +472,6 @@ States and transitions:
* ``[processed-success] => aborting(refresh)``: The purse was deleted successfully, and refunded coins must be refreshed.
* ``[processed-failed(already-merged)] => done``: The other party claimed the funds faster that we were able to abort.
* ``[processed-failed(other)] => aborting(refresh)``: The exchange reports a permanent error. We still try to refresh.
-
* ``[action:abort-force] => failed``
* ``aborting(refresh)``
@@ -453,17 +480,15 @@ States and transitions:
* ``[processed-failed] => failed)``: Refresh group failed to complete with a permanent error.
* ``[action:abort-force] => failed``: XXX will this abort the refresh session or just orphan it?
-* ``done``
-
- * ``[action:delete]`` No money should be lost in this case.
+* ``pending(refundable)``
-* ``aborted``
+ * ``[auto-refund-timeout] => done``
- * ``[action:delete]`` No additional money is lost other than fees from aborting/refreshing.
+* ``aborting(refund)``
-* ``failed``
+ * ``[processed-success] => aborted(refunded)``
+ * ``[processed-failure] => aborting(refresh)``
- * ``[action:delete]``: Money will be lost.
Transaction Type: Peer Push Credit
@@ -474,24 +499,29 @@ a ``taler://pay-push`` URI.
States and transitions:
-* ``pending(initial)``
+* ``initial``
+
+Wallet read the taler:// URI and the transaction was initialized
* ``[processed-success] => pending(withdrawing)``: Merging the reserve was successful
-* ``pending(withdrawing)``
+* ``pending(withdrawing-coins)``
- * ``[processed-kyc-required] => kyc-required``
+ * ``[processed-kyc-required] => pending(kyc-required)``
-* ``kyc-required``
+* ``pending(kyc-required)``
- * ``[poll-success] => pending(withdrawing)``
+ * ``[poll-success] => pending(withdrawing-coins)``
* ``[action:abort] => aborted``: The user will lose the coins they were not able to withdraw yet, unless they
- resume the transaction again.
+ resume the transaction again. Exchange should return non-withdrawn coins discounting closing fee.
* ``aborted``
- * ``[action:resume] => pending(withdrawing)``
+ * ``[action:resume] => pending(withdrawing-coins)``
+(??) this is not possible since aborted is final
+
* ``[action:delete] => deleted``: The user will irrevocable lose coins that were not withdrawn from the reserve yet.
+(??) no, i think aborting a push-credit should return to the sender, like a refund
* ``done``
@@ -503,12 +533,19 @@ Transaction Type: Peer Pull Credit
----------------------------------
TODO: Also specify variant where account reserve needs to be created / funded first.
+?? which is this case?
+
+* ``initial``
-* ``pending(initial)``
+Wallet created the transaction
- In this state, the purse is created (already in a merged state, with the initiator
- providing the reserve).
+ * ``[action:success] => pending(purse-created)``
+* ``pending(purse-created)``
+
+ In this state, the purse is created (already in a merged state, with the initiator providing the reserve).
+
+ * ``[action:success] => pending(wait-deposit)``:
* ``[action:abort] => aborted``: At this stage, it's safe to just abort.
CG: is this not 'suspend' (safe to resume!). Also, deletion transitions are missing.
@@ -523,41 +560,60 @@ TODO: Also specify variant where account reserve needs to be created / funded fi
* ``pending(withdrawing)``
* ``[processed-success] => done``
+ * ``[processed-kyc-required] => pending(kyc-required)``
+
+* ``pending(kyc-required)``
+
+ * ``[poll-success] => pending(withdrawing)``
* ``aborting(delete-purse)``
* ``[processed-success] => aborted``
- * ``[processed-failed(merge)] => done``
+ * ``[processed-failed(was-merged)] => done``
* ``[processed-failed(expired)] => failed(expired)``
-* ``aborted``
-* ``done``
+Transaction Type: Peer Pull Debit
+---------------------------------
-* ``failed(expired)``
+* ``initial``
-
+Wallet read the taler:// URI
-Transaction Type: Peer Pull Debit
----------------------------------
+ * ``[action:success] => pending(invoice-downloaded)``
-* ``pending(initial)``
+
+* ``pending(invoice-downloaded)``
We've downloaded information about the pull payment and are waiting
for the user to confirm.
* ``[action:abort] => aborted``: Safe to abort!
- * ``[action:confirm-pay] => pending(deposit)``: Safe to abort!
+ * ``[action:confirm-pay] => pending(submit-payment)``
-* ``pending(deposit)``
+* ``pending(submit-payment)``
The user has confirmed the payment and the wallet tries to deposit
into the provided purse.
+ * ``[action:abort] => aborting(refund)``
+ * ``[processed-success(auto-refund-enabled)] => pending(refundable)``
+ * ``[processed-success(auto-refund-disabled)] => done``
+ * ``[processed-error(expired)] => aborting(refresh)``
* ``[processed-success] => done``
- * ``[action:abort] => aborting(refresh)``: Wallet tries to refresh coins
- that were not already deposited. XXX Do we really always refresh even if no deposit
- attempt has been made yet? CG: only every refresh those coins that are dirty.
+ * ``[action:abort] => aborting(refresh)``
+
+* ``pending(refundable)``
+
+The payment succeed but if auto-refund-check is active it will be checking for refunds
+
+ * ``[auto-refund-timeout] => done``
+
+* ``aborting(refund)``
+
+ * ``[processed-success] => aborted(refunded)``
+ * ``[processed-failure] => aborting(refresh)``
+
* ``aborting(refresh)``