Status-react: Add option for user to cancel a pending transaction.

Created on 23 Sep 2020  路  11Comments  路  Source: status-im/status-react

Feature Issue

In the Wallet History screen, add a button that lets a user cancel a pending transaction. This feature should be implemented at the same time as related feature #11214

User Story

As a user, I want to be able to cancel a pending transaction, so that A) if I've spotted an error with the transaction before it's included in a block I can cancel it and B) if the transaction is stuck and I want to cancel it instead of increasing it's gas.

Description

See design below. Note that this screen is from the forthcoming wallet design refresh, the only UI change required by this issue is the addition of the 'Cancel' button underneath the pending transaction list item. Requires #11214 to be implemented first, as this issue adds a 'pending' state to transactions in the history screen.

cancel transaction

Acceptance Criteria

Test case

  1. After making a token transfer from their wallet, the user is redirected to the History screen
  2. On the History screen the user can see that their transaction is pending because the list item representing the transaction has a 'pending' icon (as opposed to the 'sent' and 'received' arrow icons).
  3. User taps the 'Cancel' button.
  4. The transaction is canceled and the list item representing this transaction is removed from the list of transactions in the history screen.

Notes

  • This requires signing a transaction without using the user password, if that's not feasible at the moment for technical reason (i.e we don't store the user key in memory), having a sign dialog is fine, though not desirable. UPDATE: Judging by the code, the key is not stored in memory at any point https://github.com/status-im/status-go/blob/200273aa0ead9eef16bb5054d60a9edf73192f98/account/accounts.go#L120 , but whoever picks up this task please make sure that is the case.
  • For anyone picking this up, leave a comment on whether you feel you can do the keycard work as well, otherwise we'll have it out of scope.
feature

Most helpful comment

Rational for not asking the user for password when the user wishes to cancel a pending transaction is as follows:

A) cancelling a transaction is not a very destructive action, worst that can happen is a user accidentally cancels a transaction. If this happens the user just needs to create a new transaction, not the worst thing in the world.

B) but let's say the user has just noticed that something is wrong with the transaction e.g. they added an extra zero to the number of tokens they were meaning to send, or they accidentally entered the wrong address, etc... These are all very bad, very destructive things, and the user will be in a panic to cancel the transaction before it goes through. Asking for a password at the moment the user realizes they need to cancel the transaction could be very stressful for the user.

Note the above is just from a UX point of view.

All 11 comments

@rajeevgopalakrishna @0kok0 @corpetty could you please have a look at this and give your opinion?
This will require signing a transaction for the user without requiring their password, same behavior as metamask.
@johnlea-quiup can give a good rationale on why that's desirable from a UX point of view.

Rational for not asking the user for password when the user wishes to cancel a pending transaction is as follows:

A) cancelling a transaction is not a very destructive action, worst that can happen is a user accidentally cancels a transaction. If this happens the user just needs to create a new transaction, not the worst thing in the world.

B) but let's say the user has just noticed that something is wrong with the transaction e.g. they added an extra zero to the number of tokens they were meaning to send, or they accidentally entered the wrong address, etc... These are all very bad, very destructive things, and the user will be in a panic to cancel the transaction before it goes through. Asking for a password at the moment the user realizes they need to cancel the transaction could be very stressful for the user.

Note the above is just from a UX point of view.

This is a prerequisite for #11214, as if the transaction is sent already, only way "canceling" or "editing" it is to sent another one with higher Gas (which also means the user looses Gas when canceling the transaction).

Re: skip the password prompt; we could cache the signing key for some time, which is required to edit a transaction that was already _sent_. @hesterbruikman suggested to schedule transactions, which I think is more reliable than sending competing transactions. Security wise, we could get away here with asking the user to enter the password, right before the transaction is finally and definitely sent. @cammellos what is the status when a transaction is pending? Is it in the mempool of the app or infura node?

The core point however is if we want to cache the signing key in memory. I'd say no, especially not by default. But we could ask the user if they want to, but we have a sane default here. If something, I would go for a local scheduling queue where the user drafts a transaction and signs it right before it is sent. We can always weaken the security model later on.

@hesterbruikman suggested to schedule transactions, which I think is more reliable than sending competing transactions.

I am not quite sure that's a feasible option I believe once you sign a transaction it will be immediately broadcasted to the transaction pool, and only by sending a competing transaction you can cancel it. (We could discuss scheduling transactions but that's a different feature).

Judging by the code, the key is not stored in memory at any point https://github.com/status-im/status-go/blob/200273aa0ead9eef16bb5054d60a9edf73192f98/account/accounts.go#L120 , but whoever picks up this task please make sure that is the case.

So first cut we will have to show the password prompt to the user.
As discussed with @johnlea-quiup this is not desirable UX, but we can go with this implementation for now and defer the decision to later on whether we want/how to improve this.

@cammellos I've been thinking about this some more, and in the future when we introduce biometric authentication as an option for signing, the experience of requiring the user to sign to cancel a transaction will be absolutely fine. Of course in this future scenairo keycard users will still have to tap their keycard, and biometric authentication will only work for users who have phones with biometric authentication methods (both less than ideal).

But at least for users of biometric authentication asking a user to sign to cancel a transaction should be a smooth painfree experience, and in this case we probably don't need to add an additional delay.

+1 on keeping the key out of memory, also in status-react. @cammellos my question referred to the transaction though, if it is buffered in status-go/infura's mempool where we can remove it before it is broadcasted? I guess infura doesn't expose that logic but could we do it in status-go to cancel a transaction without pw prompt?

@0kok0 the transaction is never buffered in status-go, on Infura likely is the same, the transaction is immediately broadcasted to the network, so the only way to cancel it is to override the nonce.

I see, so I can't think of a way to cancel it securely without password prompt

@0kok0 thanks for investigating! In the future biometric signing will remove the signing pain for users with biometric hardware who don't use keycard. Keycard is a bit more hassle, but tapping a card and entering a pin is still less friction than entering a strong (hopefully long and random) password. This won't help users of phones without a biometric authentication mechanism, but Android phones started getting biometric authentication in 2011 and these days $150 USD phones include biometric authentication (see Moto E) so phones with biometric authentication should cover most folks even in developing countries soon.

@johnlea-quiup the way how pending tx can be canceled is sending a new tx with the same nonce, usually its 0ETH to yourself, but this tx will cost some money for the gas. and there are still option on how fast you want to cancel it, not sure if we should have the option to change gas price, but probably we should inform user that we're sending 0ETH to himself

image

Was this page helpful?
0 / 5 - 0 ratings