Fujicracy / fuji-v2

Cross-chain money market aggregator
https://fuji-v2-frontend.vercel.app
15 stars 10 forks source link

Transaction flow notifications #423

Closed brozorec closed 1 year ago

brozorec commented 1 year ago

Context

It's a good practice to keep the user updated with all the stages of their transaction. Usually, this can be achieved with a 3rd party package such as "web3-onboard". However, our users are supposed to execute many cross-chain transactions, and this package is unsuitable for tracking such transactions. That's why we need to write our own implementation of cross-chain tx status notifications.

We have to first differentiate the two types of transactions, our users can make: a single-chain tx and a cross-chain tx. (Here, we also have to mention the permit signing which is not a tx per-se but requires interaction with the user's wallet.)

The user in both cases submits a transaction on only one chain. The transaction is sent to the mempool and subsequently validated and included in a block. In the case of a single-chain tx, once the tx is confirmed, the lifecycle of the transaction ends there. However, in the case of a cross-chain tx, the tx confirmation makes only for the half of the picture. This is where the bridge (Connext) comes into play. In order to understand in-depth how Connext works, you can read more here.

For the sake of this ticket, let's assume that Connext takes the result of the transaction and relays it to the destination chain. On the destination chain, a new tx is going to be executed and it will result in the desired by the user output. For example, the user has some WETH on Optimsim and want to take out an USDC loan on Arbitrum. They will execute a tx on Optimism in which they will deposit the WETH in the Connext smart contract on Optimism. Together with the funds, the tx will contain some calldata with the logic to be executed on the destination chain. Connext will take the deposited WETH and the calldata and will relay (bridge) them to the destination chain where the calldata will be executed. Ofc, the whole process is abstracted away from the user and they only need to be notified about the high-level steps of it.

TODOs

  1. Before submitting a tx, we have to call injectedProvider.estimateGas() link because we want to add some gasLimit buffer (while testing we had some failing transactions with "out-of-gas" error). This call can fail for different reasons so we have to make sure to catch the error and display an error message. The thrown error usually is difficult to read, but you can find here some hints on how to extract the error reason. We'd also like to log this to sentry and debug how the user got there.
  2. For both, a single-chain tx and a cross-chain tx, we submit it through await injectedProvider.sendTransaction() link with 20% more gasLimit. We'd also want to catch if any errors.
  3. The above call should return an ehter.js "TransactionResponse". This still doesn't mean that the tx was confirmed, we need to "wait" for the receipt link. Based on the receipt "status", we may conclude if the tx was successfully included in a block or it failed. With this step ends a single-chain tx.
  4. If we have a cross-chain tx (check chainId of the START and the END steps), we need to check the status of the tx on the destination chain by calling sdk.getConnextTxDetails(). This call will return the status of the destination tx just for the given moment. That's why, we have to poll it every 5 seconds while the returned status is PENDING or UNKNOWN.

Here are the messages we want to display for the different types of transactions corresponding to the different statuses: UI-transaction-flow

Needs more info

We have designs for some of them that are proposed to be displayed in a modal like here or here. We also have the transaction modal where we can see the tx statuses, both for a single-chain and a cross-chain tx. I remember we said at the beginning that we display the modal but if the user closes it, we display a notification. Do we still stick with this idea? How do we articulate between notifications and modals? @Markoyw we need your help

Markoyw commented 1 year ago

Hey @brozorec

Agree. Recap:

In terms of definition, I'm thinking it could define as:

  1. Modal pop-up: Action required + Feedback immediately
  2. Notification toast: Feedback when the modal pop-up is closed or unavailable

Would like to get your feedback - as I'm still not 100% convinced of this approach. Going to do further research and get back

ferostabio commented 1 year ago

Thanks for the feedback @Markoyw !

I agree 100% with the definition. If the user needs to take action + feedback immediately, modal. Otherwise, the toast notification. Now, for the transaction modal, I would try showing both actually.

Not showing something twice is a sacred rule for me, but for a tx, given how important it is, I would do it -and truth be told, it wouldn't be exactly the same data twice. We would update the modal to reflect the latest info and we would show a toast notification explicitly informing what just happened.

ferostabio commented 1 year ago

Realized something small but big. While Metamask is on, it hides our notifications 😅 -so I show the "please sign the permit" notification and the user can see it for a second until MM hides it. And it's going to happen a lot for some of our more important notifications. I've seen a lot notifications on the left on crypto, I think this is the reason 🥳. I'll do the same.

Markoyw commented 1 year ago

Ohh. Yeah, you're right. I saw a few protocols that have their notification positioned in the bottom left corner and I was wondering why are they doing it that way.

brozorec commented 1 year ago
  1. A notification has the following parts: a) a title with a status icon (mandatory) b) a message and/or instructions (optional) c) link (optional)
  2. Our dapp is cross-chain so it would be good to display the chain icon on which the tx is getting processed.
  3. When there's an explorer link (etherscan, ...) with a transaction hash, display a link "View transaction".
  4. When we invite the user to ask for assistance, display a link "Discord" (https://discord.gg/EYbvwfGDhP)
  5. We can have the following types of notifications: error, info, warning, pending and success
  6. For the pre-flight state, we display a pending notification that doesn't get hidden untill the user completes the action in their wallet.
  7. Notifications are displayed in the top-left corner without overlapping with the logo.
  8. The notification transition is "slide" (according to the definitions in react-toastify)