-
-
Notifications
You must be signed in to change notification settings - Fork 276
feat(transaction-pay): add ordered strategy fallback orchestration #7868
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
base: main
Are you sure you want to change the base?
Conversation
23573ac to
55549a1
Compare
55549a1 to
e2818b3
Compare
packages/transaction-pay-controller/src/helpers/TransactionPayPublishHook.ts
Outdated
Show resolved
Hide resolved
e2818b3 to
5158351
Compare
packages/transaction-pay-controller/src/TransactionPayController.ts
Outdated
Show resolved
Hide resolved
c450bc6 to
782bc16
Compare
|
|
||
| `TransactionPayController` provides an ordered strategy list via `getStrategies`. | ||
| The quote flow iterates strategies in order, applies `supports(...)` compatibility checks when present, and falls back to the next compatible strategy if quote retrieval fails or returns no quotes. | ||
| The publish hook uses the same ordered fallback approach if execution fails for the primary quote strategy. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in the previous PR, I don't think quote execution fallback is possible since we have no opportunity to present the new fee to the user, which may be higher, or have an alternate network fee, or require gas station etc.
| }; | ||
|
|
||
| /** Action to get the ordered pay strategies for a transaction. */ | ||
| export type TransactionPayControllerGetStrategiesAction = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we remove the execution fallback, we shouldn't need a new messenger action, as we only need to identify the strategy based on the quote in the state.
Though in retrospect, we should probably do that via the strategy property on the quote itself, which would mean we also would no longer need the getStrategy action either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept getStrategy for now, as this would be a breaking change to the client. I'm keeping track of this on a ticket, however, so we can clean that up later.
| * @returns Array of quote requests. | ||
| */ | ||
| function buildQuoteRequests({ | ||
| export function buildQuoteRequests({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't need to be exported if we remove fallback execution.
|
|
||
| for (const strategy of strategies) { | ||
| try { | ||
| if (strategy.supports && !strategy.supports(request)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth a log to confirm when a strategy doesn't support a request?
| )) as TransactionPayQuote<Json>[]; | ||
|
|
||
| if (!quotes.length) { | ||
| continue; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth a log to confirm a single strategy found no quotes?
| const quotes = | ||
| (controllerState.transactionData?.[transactionId] | ||
| ?.quotes as TransactionPayQuote<unknown>[]) ?? []; | ||
| (transactionData?.quotes as TransactionPayQuote<unknown>[]) ?? []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned, all we should do here is identify the strategy from the saved quotes using the strategy property, and execute them. We shouldn't fallback here given fee implications.
| } catch (error) { | ||
| log('Error fetching quotes', { error, transactionId }); | ||
| if (!requests?.length) { | ||
| return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth a log to help debug all these branches?
| strategies = [this.#getStrategy(transaction)]; | ||
| } | ||
|
|
||
| return strategies.length ? strategies : [TransactionPayStrategy.Relay]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we not adding the feature flag fallback order in this PR, or are we letting the client own the order?
| const { id: transactionId } = transaction; | ||
| const strategy = getStrategy(messenger as never, transaction); | ||
| let quotes: TransactionPayQuote<Json>[] | undefined = []; | ||
| const strategies = getStrategies(messenger as never, transaction); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we remove both messenger actions for getting strategies, we could just get this via another callback such as getStrategies in the UpdateQuotesRequest.
9b2de51 to
44ee983
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
44ee983 to
eeca0ed
Compare
Explanation
As per preemptive validation on #7806
TransactionPayController:getStrategieswhile preserving existinggetStrategybehavior.supports(...)) during strategy selection.References
Addresses https://github.com/MetaMask/MetaMask-planning/issues/6992
Checklist
Note
Medium Risk
Changes core quote-selection and execution routing logic; incorrect ordering/fallback behavior could lead to missing quotes or executing the wrong pay path, though guarded by defaults/tests and fallback-to-default strategy order.
Overview
Implements ordered
PayStrategyorchestration for quote retrieval:TransactionPayControllernow acceptsgetStrategies(with feature-flag default ordering) andupdateQuotesiterates strategies in order, applying optionalsupports(...)checks and falling back on errors or empty quotes/batch transactions.Publish-time execution is aligned with quote selection by executing via the strategy recorded on the quote (
quotes[0].strategy) rather than re-resolving strategy from the transaction. Adds a newconfirmations_pay.strategyOrderfeature flag with validation/deduping, updates quote refresh plumbing to pass strategy ordering through, and updates docs/tests accordingly.Written by Cursor Bugbot for commit eeca0ed. This will update automatically on new commits. Configure here.