Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add swap+send STX typings #4634

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

feat: add swap+send STX typings #4634

wants to merge 10 commits into from

Conversation

BZahory
Copy link
Contributor

@BZahory BZahory commented Aug 21, 2024

Explanation

Swap+Send currently bypasses both the confirmations and STX flow for the Extension, due to an inability to use a single confirmation page. This adds typing and handling for both a swap+send approval event and a new transaction property that tracks data for an approval that should be executed right before the transaction.

Both the transaction-controller and user-controller had to be updated here, as both contain typing relating to the transactions.

References

Relates to MetaMask/metamask-extension#25734

Changelog

@metamask/transaction-controller

  • ADDED: SwapAndSendApproval typing and event
  • ADDED: approvalTxParams transaction property and handling

@metamask/user-operation-controller

  • ADDED: approvalTxParams transaction property and handling

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've highlighted breaking changes using the "BREAKING" category above as appropriate

@BZahory BZahory requested review from a team as code owners August 21, 2024 17:51
micaelae
micaelae previously approved these changes Aug 21, 2024
micaelae
micaelae previously approved these changes Aug 21, 2024
packages/transaction-controller/src/types.ts Outdated Show resolved Hide resolved
packages/transaction-controller/src/utils/swaps.ts Outdated Show resolved Hide resolved
@@ -348,6 +349,17 @@ export type SwapsMetadata = {
/** Symbol of the destination token. */
destinationTokenSymbol: string | null;

approvalTxParams?: {
Copy link
Member

@matthewwalsh0 matthewwalsh0 Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here, we already store the transactionParams and transactionType in the UserOperationMetadata so don't want to duplicate any state.

Plus won't the meta property be a duplicate of the other properties in this type?

Or a approvalUserOperationId if it's ultimately concerning an alternate user operation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that we are bundling the approval TX with the trade TX, so there wouldn't be an approval TX ID to reference in this case, since the user would be shown that approval as well. The goal is to have one confirmation screen for the trade that triggers the approval right before the trade is submitted – very similar to a callback/hook pattern. This thread provides good context towards the end: https://consensys.slack.com/archives/C068SFX90PN/p1720616402512989

As for duplication, when creating the transaction at the surface level (i.e., in the send ducks file), we pass the approvalTx as swaps metadata, and it is ultimately converted into transaction metadata in getTransactionMetadata() (core)

Copy link
Member

@matthewwalsh0 matthewwalsh0 Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand the goal from the client perspective is to have a single confirmation that triggers both the approval and trade transactions.

But from the core perspective, it still has to deal with them one at a time, meaning it still requires separate calls to addTransaction, so there will eventually be two transactions in the state.

So my query is why we need to couple the controller itself to this metadata, if it's ultimately the client orchestrating the process meaning the client can have state in the confirmation that knows it needs two transactions.

Ultimately, we don't want to couple the controller unnecessarily to client problems, so I'm not sure what benefit this new metadata would have?

Copy link
Contributor Author

@BZahory BZahory Aug 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately, we don't want to couple the controller unnecessarily to client problems, so I'm not sure what benefit this new metadata would have?

The issue is that the controller manages the transaction that the confirmations component would handle, so this PR is a direct result of deep coupling. I do believe this is well within the scope of the controller, as this directly relates to how transactions are handled and presented to the confirmations component.

So my query is why we need to couple the controller itself to this metadata, if it's ultimately the client orchestrating the process meaning the client can have state in the confirmation that knows it needs two transactions.

This goes back to the point of keeping these coupled to mitigate the risk of any bug or edge cases where the approval is either cleared a) after the trade or b) not at all. Keeping this bundled until we are actually submitting the transactions prevents a lot of the race conditions that transactions are prone to.

There is an approach where we accomplish the same on the client side, but this would require a ton of confirmation refactors that would (rightfully) blow up the review/testing scope of the extension PR.

@@ -357,6 +372,7 @@ function updateSwapTransaction(
* @param propsToUpdate.swapMetaData - Metadata of the swap
* @param propsToUpdate.swapTokenValue - Value of the token to be swapped – possibly the same as sourceTokenAmount; included for consistency
* @param propsToUpdate.type - Type of the transaction
* @param propsToUpdate.approvalTxParams - The parameters of the approval transaction
* @returns The updated transaction meta object.
*/
function updateSwapAndSendTransaction(
Copy link
Member

@matthewwalsh0 matthewwalsh0 Aug 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the purpose of the approvalTxParams is ultimately to be included in this event, could we instead just include them in the addTransaction method options and pass them to updateSwapsTransaction then here and then include them as an alternate property in the event?

That way the event has the info, but we don't have to persist anything new?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the approval TX for the confirmations screen in extension, not just this method. The idea is that we ensure it's always bundled with the tx, so that we don't lose it if the send state in extension is lost (ie the user closes the extension and reopens it)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the user closes the extension, then I believe we automatically reject the transaction.

BZahory added a commit to MetaMask/metamask-extension that referenced this pull request Aug 23, 2024
You need to link the branch in MetaMask/core#4634, so build and replace my name w your name, then once matt walsh is done yapping it up, get that merged and deployed, then finally replace all the linking with the latest npm version for the user-operations-controller and transaction-controller.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants