Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/transaction-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `isPostQuote` field to `MetamaskPayMetadata` type for withdrawal flows ([#7773](https://github.com/MetaMask/core/pull/7773))

## [62.11.0]

### Added
Expand Down
6 changes: 6 additions & 0 deletions packages/transaction-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,12 @@ export type MetamaskPayMetadata = {
/** Chain ID of the payment token. */
chainId?: Hex;

/**
* Whether this is a post-quote transaction (e.g., withdrawal flow).
* When true, the token represents the destination rather than source.
*/
isPostQuote?: boolean;

/** Total network fee in fiat currency, including the original and bridge transactions. */
networkFeeFiat?: string;

Expand Down
5 changes: 5 additions & 0 deletions packages/transaction-pay-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `isPostQuote` and `selectedToken` fields to `TransactionData` type for withdrawal flows ([#7773](https://github.com/MetaMask/core/pull/7773))
- Add `UpdateSelectedTokenRequest` type and related action types ([#7773](https://github.com/MetaMask/core/pull/7773))

## [12.0.2]

### Changed
Expand Down
3 changes: 3 additions & 0 deletions packages/transaction-pay-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ export type {
TransactionPayControllerMessenger,
TransactionPayControllerOptions,
TransactionPayControllerSetIsMaxAmountAction,
TransactionPayControllerSetIsPostQuoteAction,
TransactionPayControllerState,
TransactionPayControllerStateChangeEvent,
TransactionPayControllerUpdatePaymentTokenAction,
TransactionPayControllerUpdateSelectedTokenAction,
TransactionPaymentToken,
TransactionPayQuote,
TransactionPayRequiredToken,
TransactionPaySourceAmount,
TransactionPayTotals,
UpdatePaymentTokenRequest,
UpdateSelectedTokenRequest,
} from './types';
export { TransactionPayStrategy } from './constants';
export { TransactionPayController } from './TransactionPayController';
Expand Down
49 changes: 47 additions & 2 deletions packages/transaction-pay-controller/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ export type TransactionPayControllerUpdatePaymentTokenAction = {
handler: (request: UpdatePaymentTokenRequest) => void;
};

/** Action to update the selected token for a transaction (used for withdrawals). */
export type TransactionPayControllerUpdateSelectedTokenAction = {
type: `${typeof CONTROLLER_NAME}:updateSelectedToken`;
handler: (request: UpdateSelectedTokenRequest) => void;
};

/** Action to set the post-quote flag for a transaction. */
export type TransactionPayControllerSetIsPostQuoteAction = {
type: `${typeof CONTROLLER_NAME}:setIsPostQuote`;
handler: (transactionId: string, isPostQuote: boolean) => void;
};
Copy link

Choose a reason for hiding this comment

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

New action types lack corresponding handler registrations

Medium Severity

The new action types TransactionPayControllerUpdateSelectedTokenAction and TransactionPayControllerSetIsPostQuoteAction are added to the TransactionPayControllerActions union and exported, but no handlers are registered in TransactionPayController. Existing actions like setIsMaxAmount and updatePaymentToken follow a pattern where they're defined in types, have corresponding controller methods, and handlers are registered via messenger.registerActionHandler. The new action types break this pattern — calling them via the messenger will fail at runtime.

Additional Locations (1)

Fix in Cursor Fix in Web


/** Action to set the max amount flag for a transaction. */
export type TransactionPayControllerSetIsMaxAmountAction = {
type: `${typeof CONTROLLER_NAME}:setIsMaxAmount`;
Expand All @@ -102,7 +114,9 @@ export type TransactionPayControllerActions =
| TransactionPayControllerGetStateAction
| TransactionPayControllerGetStrategyAction
| TransactionPayControllerSetIsMaxAmountAction
| TransactionPayControllerUpdatePaymentTokenAction;
| TransactionPayControllerSetIsPostQuoteAction
| TransactionPayControllerUpdatePaymentTokenAction
| TransactionPayControllerUpdateSelectedTokenAction;

export type TransactionPayControllerEvents =
TransactionPayControllerStateChangeEvent;
Expand Down Expand Up @@ -142,7 +156,26 @@ export type TransactionData = {
/** Whether the user has selected the maximum amount. */
isMaxAmount?: boolean;

/** Source token selected for the transaction. */
/**
* Whether this is a post-quote transaction (e.g., withdrawal flow).
* When true, the selectedToken represents the destination token,
* and the quote source is derived from the transaction's native token.
Copy link
Member

Choose a reason for hiding this comment

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

This isn't quite true, the source would be whatever the original transaction generated / it's output.

* Used for Predict/Perps withdrawals where funds flow:
* withdrawal → bridge/swap → destination token
*/
isPostQuote?: boolean;
Copy link
Member

Choose a reason for hiding this comment

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

I'd usually recommend against a type only PR as easier to judge it's value when it's being utilised in new logic.


/**
* Token selected for the transaction.
* - For deposits (isPostQuote=false): This is the SOURCE/payment token
* - For withdrawals (isPostQuote=true): This is the DESTINATION token
*/
selectedToken?: TransactionPaymentToken;
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't bother renaming this yet until the entire feature is done, given the breaking change, and refactor needed in the clients.

Though we can still update the JSDoc to clarify it's broader use.


/**
* @deprecated Use selectedToken instead. Kept for backwards compatibility.
* Source token selected for the transaction.
*/
paymentToken?: TransactionPaymentToken;

/** Quotes retrieved for the transaction. */
Expand Down Expand Up @@ -450,6 +483,18 @@ export type UpdatePaymentTokenRequest = {
chainId: Hex;
};

/** Request to update the selected token for a transaction (used for withdrawals). */
export type UpdateSelectedTokenRequest = {
Copy link
Member

Choose a reason for hiding this comment

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

Also here, wouldn't bother with a new action type yet as we can refactor later with a dedicated breaking change PR.

/** ID of the transaction to update. */
transactionId: string;

/** Address of the selected token. */
tokenAddress: Hex;

/** Chain ID of the selected token. */
chainId: Hex;
};

/** Callback to convert a transaction to a redeem delegation. */
export type GetDelegationTransactionCallback = ({
transaction,
Expand Down
Loading