Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
4530da6
feat: add getAmountData callback to TransactionPayController
OGPoyraz Jun 3, 2026
70c06c3
fix: fiat moneyAccountDeposit three-phase relay submit
OGPoyraz Jun 3, 2026
876a525
fix: lint errors and update tests for fiat submit changes
OGPoyraz Jun 3, 2026
61064db
Fix lint
OGPoyraz Jun 3, 2026
d5ac30b
docs: update transaction-pay-controller changelog
OGPoyraz Jun 3, 2026
c894ce0
Update changelog
OGPoyraz Jun 3, 2026
59236fb
fix: only reject rate drift when rate worsens, not improves
OGPoyraz Jun 3, 2026
4786428
Update changelog
OGPoyraz Jun 3, 2026
e87e784
fix: lint errors in fiat-submit tests
OGPoyraz Jun 3, 2026
176207b
fix: skip source balance check for relay execute flow
OGPoyraz Jun 3, 2026
48d856b
fix: use accountOverride for wallet address in fiat flow
OGPoyraz Jun 3, 2026
3dbd8f2
fix: revert isExecute balance skip test changes
OGPoyraz Jun 3, 2026
794ad91
fix: remove hasFiatStrategy totals test
OGPoyraz Jun 3, 2026
b63168e
fix: pass fiatPaymentAmount to totals for correct fiat total calculation
OGPoyraz Jun 3, 2026
26ef707
Fix the total derivation
OGPoyraz Jun 3, 2026
56e7a33
test: add coverage for fiat strategy payment amount in totals
OGPoyraz Jun 3, 2026
e36f8af
Address PR review feedback from matthewwalsh0
OGPoyraz Jun 4, 2026
eee7376
feat: skip discovery quote for simple fiat deposits (Perps, Predict)
OGPoyraz Jun 4, 2026
e8acf57
feat: fee-as-buffer strategy, simple relay path, and file split for f…
OGPoyraz Jun 4, 2026
fe4fc11
fix: decouple processTransactions from isPostQuote in relay-quotes
OGPoyraz Jun 4, 2026
50d7476
fix: set skipProcessTransactions for simple fiat relay to fix recipie…
OGPoyraz Jun 4, 2026
f4f7ba4
fix: sum nested call values for EIP-7702 batch transaction
OGPoyraz Jun 5, 2026
90e9a8e
fix: post-quote gas handling for zero-balance fiat-funded accounts
OGPoyraz Jun 5, 2026
fcb6e36
test: add coverage for EIP-7702 batch value summing and update changelog
OGPoyraz Jun 5, 2026
25ece51
test: achieve 100% coverage for relay-quotes, feature-flags, and fiat…
OGPoyraz Jun 5, 2026
e03e64b
revert: remove unvalidated chainId/networkClientId override in fiat-s…
OGPoyraz Jun 5, 2026
55c412f
fix: detect Polygon native token for post-quote gas subtraction
OGPoyraz Jun 5, 2026
ba47bef
fix: skip batch gas estimation when accountOverride diverges from txP…
OGPoyraz Jun 5, 2026
7c27231
fix: use accountOverride for wallet address in fiat-quotes
OGPoyraz Jun 5, 2026
6e97dae
fix: skip source balance check for relay execute flow
OGPoyraz Jun 5, 2026
57a14f2
fix: bump fee reserve multiplier to 1.2 and move rate drift check to …
OGPoyraz Jun 5, 2026
0f35336
Merge branch 'main' into ogp/fiat-money-account-deposit-fix
OGPoyraz Jun 5, 2026
d4d107c
fix: add missing 67.0.0 link in transaction-controller changelog
OGPoyraz Jun 5, 2026
4808a41
Merge branch 'main' into ogp/fiat-money-account-deposit-fix
OGPoyraz Jun 5, 2026
4cc2c79
Address minor issues
OGPoyraz Jun 8, 2026
a1b8960
fix: address PR review - simplify fee reserve, remove gas buffer flag…
OGPoyraz Jun 8, 2026
4a3d7ec
Update
OGPoyraz Jun 8, 2026
e75280a
Revert isExecute validate balance checks
OGPoyraz Jun 8, 2026
fefdba2
Revert TC changes
OGPoyraz Jun 8, 2026
fa70190
Update
OGPoyraz Jun 8, 2026
e889d0a
Changelog update
OGPoyraz Jun 8, 2026
c6962f5
Update lint
OGPoyraz Jun 8, 2026
5946484
Merge branch 'main' into ogp/fiat-money-account-deposit-fix
OGPoyraz Jun 8, 2026
bc33f20
Fix changelog
OGPoyraz Jun 8, 2026
c77262c
Update
OGPoyraz Jun 8, 2026
e9febec
Merge branch 'main' into ogp/fiat-money-account-deposit-fix
OGPoyraz Jun 8, 2026
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-pay-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]

### Changed

- Fix fiat `moneyAccountDeposit` failing after on-ramp settlement by adding `getAmountData` callback for calldata re-encoding, correcting wallet address, quote amount, slippage validation, and switching to a three-phase relay flow with fee-as-buffer strategy; simple deposits (Perps, Predict) skip to a single EXACT_INPUT relay quote for cheaper fees ([#8987](https://github.com/MetaMask/core/pull/8987))

## [23.2.0]

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ export type TransactionPayControllerGetDelegationTransactionAction = {
* @param args - The arguments forwarded to the {@link GetPaymentOverrideDataCallback}.
* @returns A promise resolving to the additional transactions array.
*/
export type TransactionPayControllerGetAmountDataAction = {
type: `TransactionPayController:getAmountData`;
handler: TransactionPayController['getAmountData'];
};

export type TransactionPayControllerGetPaymentOverrideDataAction = {
type: `TransactionPayController:getPaymentOverrideData`;
handler: TransactionPayController['getPaymentOverrideData'];
Expand Down Expand Up @@ -128,6 +133,7 @@ export type TransactionPayControllerMethodActions =
| TransactionPayControllerUpdatePaymentTokenAction
| TransactionPayControllerUpdateFiatPaymentAction
| TransactionPayControllerGetDelegationTransactionAction
| TransactionPayControllerGetAmountDataAction
| TransactionPayControllerGetPaymentOverrideDataAction
| TransactionPayControllerGetStrategyAction
| TransactionPayControllerPolymarketGetDepositWalletAddressAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,51 @@ describe('TransactionPayController', () => {
});
});

describe('getAmountData', () => {
it('delegates to the callback', async () => {
const resultMock = {
updates: [{ nestedTransactionIndex: 0, data: '0xabc' as const }],
};
const getAmountDataMock = jest.fn().mockResolvedValue(resultMock);

new TransactionPayController({
getAmountData: getAmountDataMock,
getDelegationTransaction: jest.fn(),
messenger,
});

const requestMock = {
amount: '5000000',
transaction: TRANSACTION_META_MOCK,
};

const result = await messenger.call(
'TransactionPayController:getAmountData',
requestMock,
);

expect(getAmountDataMock).toHaveBeenCalledWith(requestMock);
expect(result).toStrictEqual(resultMock);
});

it('returns empty updates when no callback is configured', async () => {
new TransactionPayController({
getDelegationTransaction: jest.fn(),
messenger,
});

const result = await messenger.call(
'TransactionPayController:getAmountData',
{
amount: '5000000',
transaction: TRANSACTION_META_MOCK,
},
);

expect(result).toStrictEqual({ updates: [] });
});
});

describe('polymarket callbacks', () => {
const EOA_MOCK = '0x1111111111111111111111111111111111111111' as Hex;
const DEPOSIT_WALLET_MOCK =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { QuoteRefresher } from './helpers/QuoteRefresher';
import { deriveFiatAssetForFiatPayment } from './strategy/fiat/utils';
import type {
GetAmountDataCallback,
GetDelegationTransactionCallback,
GetPaymentOverrideDataCallback,
PolymarketCallbacks,
Expand All @@ -36,6 +37,7 @@ import {
} from './utils/transaction';

const MESSENGER_EXPOSED_METHODS = [
'getAmountData',
'getDelegationTransaction',
'getPaymentOverrideData',
'getStrategy',
Expand Down Expand Up @@ -64,6 +66,8 @@ export class TransactionPayController extends BaseController<
TransactionPayControllerState,
TransactionPayControllerMessenger
> {
readonly #getAmountData?: GetAmountDataCallback;

readonly #getDelegationTransaction: GetDelegationTransactionCallback;

readonly #getPaymentOverrideData?: GetPaymentOverrideDataCallback;
Expand All @@ -79,6 +83,7 @@ export class TransactionPayController extends BaseController<
readonly #polymarket?: PolymarketCallbacks;

constructor({
getAmountData,
getDelegationTransaction,
getPaymentOverrideData,
getStrategy,
Expand All @@ -94,6 +99,7 @@ export class TransactionPayController extends BaseController<
state: { ...getDefaultState(), ...state },
});

this.#getAmountData = getAmountData;
this.#getDelegationTransaction = getDelegationTransaction;
this.#getPaymentOverrideData = getPaymentOverrideData;
this.#getStrategy = getStrategy;
Expand Down Expand Up @@ -233,6 +239,12 @@ export class TransactionPayController extends BaseController<
* @param args - The arguments forwarded to the {@link GetPaymentOverrideDataCallback}.
* @returns A promise resolving to the additional transactions array.
*/
getAmountData(
...args: Parameters<GetAmountDataCallback>
): ReturnType<GetAmountDataCallback> {
return this.#getAmountData?.(...args) ?? Promise.resolve({ updates: [] });
}

getPaymentOverrideData(
...args: Parameters<GetPaymentOverrideDataCallback>
): ReturnType<GetPaymentOverrideDataCallback> {
Expand Down
4 changes: 4 additions & 0 deletions packages/transaction-pay-controller/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export type {
GetAmountDataCallback,
GetAmountDataRequest,
GetAmountDataResponse,
GetPaymentOverrideDataRequest,
GetPaymentOverrideDataResponse,
TransactionConfig,
Expand All @@ -23,6 +26,7 @@ export type {
UpdatePaymentTokenRequest,
} from './types';
export type {
TransactionPayControllerGetAmountDataAction,
TransactionPayControllerGetDelegationTransactionAction,
TransactionPayControllerGetStrategyAction,
TransactionPayControllerPolymarketGetDepositWalletAddressAction,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ describe('Bridge Quotes Utils', () => {

request = {
accountSupports7702: true,
from: '0x0000000000000000000000000000000000000000',
requests: [QUOTE_REQUEST_1_MOCK, QUOTE_REQUEST_2_MOCK],
messenger,
transaction: TRANSACTION_META_MOCK,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function getRequest({
request: {
accountSupports7702: false,
fiatPaymentMethod,
from: WALLET_ADDRESS,
messenger: {
call: callMock,
} as unknown as PayStrategyGetQuotesRequest['messenger'],
Expand Down Expand Up @@ -336,6 +337,7 @@ describe('getFiatQuotes', () => {
const result = await getFiatQuotes({
accountSupports7702: false,
fiatPaymentMethod: '/payments/debit-credit-card',
from: WALLET_ADDRESS,
messenger: {
call: callMock,
} as unknown as PayStrategyGetQuotesRequest['messenger'],
Expand Down Expand Up @@ -520,6 +522,7 @@ describe('getFiatQuotes', () => {
await getFiatQuotes({
accountSupports7702: false,
fiatPaymentMethod: '/payments/debit-credit-card',
from: WALLET_ADDRESS,
messenger: {
call: callMock,
} as unknown as PayStrategyGetQuotesRequest['messenger'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,18 @@ const log = createModuleLogger(projectLogger, 'fiat-strategy');
export async function getFiatQuotes(
request: PayStrategyGetQuotesRequest,
): Promise<TransactionPayQuote<FiatQuote>[]> {
const { accountSupports7702, fiatPaymentMethod, messenger, transaction } =
request;
const {
accountSupports7702,
fiatPaymentMethod,
from: walletAddress,
messenger,
transaction,
} = request;
const transactionId = transaction.id;

const state = messenger.call('TransactionPayController:getState');
const transactionData = state.transactionData[transactionId];
const amountFiat = transactionData?.fiatPayment?.amountFiat;
const walletAddress = transaction.txParams.from as Hex;
const requiredTokens = getRequiredTokens(transactionData?.tokens);
const fiatAsset = deriveFiatAssetForFiatPayment(transaction, messenger);

Expand Down Expand Up @@ -80,6 +84,7 @@ export async function getFiatQuotes(

const relayQuotes = await getRelayQuotes({
accountSupports7702,
from: walletAddress,
messenger,
requests: [relayRequest],
transaction,
Expand Down
Loading
Loading