Skip to content
Open
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
11 changes: 11 additions & 0 deletions packages/bridge-status-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **BREAKING:** `BridgeStatusControllerMessenger` must now allow `TransactionController:isAtomicBatchSupported` action ([#8125](https://github.com/MetaMask/core/pull/8125))

### Fixed

- Delegated accounts (EIP-7702) now use batched transactions to avoid in-flight transaction limit ([#8125](https://github.com/MetaMask/core/pull/8125))
Copy link
Member

Choose a reason for hiding this comment

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

Can you mark this as a breaking change since the clients will need to add the new action handler permissions?

Copy link
Author

Choose a reason for hiding this comment

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

Done. Just to double check, do you think this is the ideal pattern? I could also detect whether the account is delegated directly in bridge-status-controller (via eth_getCode) to avoid the breaking change, but didn't want the code duplication.

Copy link
Member

Choose a reason for hiding this comment

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

I prefer reusing TransactionController's handler too so this looks good to me

- Bridge transaction types now properly matched in 7702 batch path ([#8125](https://github.com/MetaMask/core/pull/8125))
- Delegated account batch transactions now recorded in bridge status history ([#8125](https://github.com/MetaMask/core/pull/8125))
- Gas fields now included for delegated account transactions that are not gas-sponsored ([#8125](https://github.com/MetaMask/core/pull/8125))

## [68.0.1]

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should call handleMobileHar
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -818,6 +827,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should delay after submitti
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0x2105",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -1057,6 +1075,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should delay after submitti
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xe708",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -1363,6 +1390,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should handle smart transac
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -1563,6 +1599,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should not call handleMobil
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -1802,6 +1847,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should not call handleMobil
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -2156,6 +2210,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should reset USDT allowance
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -2429,6 +2492,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should successfully submit
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -2688,6 +2760,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should successfully submit
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -2765,6 +2846,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should throw an error if ap
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -2839,6 +2929,15 @@ exports[`BridgeStatusController submitTx: EVM bridge should throw an error if ap
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -3132,6 +3231,15 @@ exports[`BridgeStatusController submitTx: EVM swap should handle smart transacti
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -3201,6 +3309,15 @@ exports[`BridgeStatusController submitTx: EVM swap should successfully submit an
"AccountsController:getAccountByAddress",
"0xaccount1",
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down Expand Up @@ -3411,6 +3528,15 @@ exports[`BridgeStatusController submitTx: EVM swap should successfully submit an
"usd_quoted_return": 0,
},
],
[
"TransactionController:isAtomicBatchSupported",
{
"address": "0xaccount1",
"chainIds": [
"0xa4b1",
],
},
],
[
"AccountsController:getAccountByAddress",
"0xaccount1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,7 @@ describe('BridgeStatusController', () => {
const setupEventTrackingMocks = (mockCall: jest.Mock) => {
mockCall.mockReturnValueOnce(mockSelectedAccount);
mockCall.mockImplementationOnce(jest.fn()); // track event
mockCall.mockReturnValueOnce([]); // isAtomicBatchSupported
};

const setupApprovalMocks = (mockCall: jest.Mock) => {
Expand Down Expand Up @@ -2854,7 +2855,7 @@ describe('BridgeStatusController', () => {
expect(estimateGasFeeFn).toHaveBeenCalledTimes(3);
expect(addTransactionFn).not.toHaveBeenCalled();
expect(addTransactionBatchFn).toHaveBeenCalledTimes(1);
expect(mockMessengerCall).toHaveBeenCalledTimes(9);
expect(mockMessengerCall).toHaveBeenCalledTimes(10);
});

it('should throw an error if approval tx fails', async () => {
Expand Down Expand Up @@ -3021,6 +3022,7 @@ describe('BridgeStatusController', () => {
},
});
mockMessengerCall.mockImplementationOnce(jest.fn()); // track event
mockMessengerCall.mockReturnValueOnce([]); // isAtomicBatchSupported

setupApprovalMocks(mockMessengerCall);
setupBridgeMocks(mockMessengerCall);
Expand Down Expand Up @@ -3103,6 +3105,7 @@ describe('BridgeStatusController', () => {
},
});
mockMessengerCall.mockImplementationOnce(jest.fn()); // track event
mockMessengerCall.mockReturnValueOnce([]); // isAtomicBatchSupported

setupApprovalMocks(mockMessengerCall);
setupBridgeMocks(mockMessengerCall);
Expand Down Expand Up @@ -3364,6 +3367,7 @@ describe('BridgeStatusController', () => {
const setupEventTrackingMocks = (mockCall: jest.Mock) => {
mockCall.mockReturnValueOnce(mockSelectedAccount);
mockCall.mockImplementationOnce(jest.fn()); // track event
mockCall.mockReturnValueOnce([]); // isAtomicBatchSupported
};

const setupApprovalMocks = () => {
Expand Down Expand Up @@ -3422,11 +3426,12 @@ describe('BridgeStatusController', () => {
const { approvalTxId } = controller.state.txHistory[result.id];
expect(approvalTxId).toBe('test-approval-tx-id');
expect(addTransactionFn).toHaveBeenCalledTimes(2);
expect(mockMessengerCall).toHaveBeenCalledTimes(11);
expect(mockMessengerCall).toHaveBeenCalledTimes(12);
});

it('should successfully submit an EVM swap transaction with featureId', async () => {
mockMessengerCall.mockReturnValueOnce(mockSelectedAccount);
mockMessengerCall.mockReturnValueOnce([]); // isAtomicBatchSupported
setupApprovalMocks();
setupBridgeMocks();

Expand All @@ -3450,7 +3455,7 @@ describe('BridgeStatusController', () => {
FeatureId.PERPS,
);
expect(addTransactionFn).toHaveBeenCalledTimes(2);
expect(mockMessengerCall).toHaveBeenCalledTimes(10);
expect(mockMessengerCall).toHaveBeenCalledTimes(11);
expect(mockMessengerCall.mock.calls).toMatchSnapshot();
});

Expand Down Expand Up @@ -3501,7 +3506,7 @@ describe('BridgeStatusController', () => {
expect(startPollingForBridgeTxStatusSpy).toHaveBeenCalledTimes(0);
expect(addTransactionFn).not.toHaveBeenCalled();
expect(addTransactionBatchFn).toHaveBeenCalledTimes(1);
expect(mockMessengerCall).toHaveBeenCalledTimes(6);
expect(mockMessengerCall).toHaveBeenCalledTimes(7);
});

it('should successfully submit an EVM swap transaction with no approval', async () => {
Expand Down Expand Up @@ -3729,7 +3734,7 @@ describe('BridgeStatusController', () => {
expect(estimateGasFeeFn).not.toHaveBeenCalled();
expect(addTransactionFn).not.toHaveBeenCalled();
expect(addTransactionBatchFn).not.toHaveBeenCalled();
expect(mockMessengerCall).toHaveBeenCalledTimes(4);
expect(mockMessengerCall).toHaveBeenCalledTimes(5);
});

it('should throw error if batched tx is not found', async () => {
Expand Down Expand Up @@ -3768,7 +3773,32 @@ describe('BridgeStatusController', () => {
expect(estimateGasFeeFn).toHaveBeenCalledTimes(2);
expect(addTransactionFn).not.toHaveBeenCalled();
expect(addTransactionBatchFn).toHaveBeenCalledTimes(1);
expect(mockMessengerCall).toHaveBeenCalledTimes(8);
expect(mockMessengerCall).toHaveBeenCalledTimes(9);
});

it('should gracefully handle isAtomicBatchSupported failure', async () => {
// Manually set up mocks without setupEventTrackingMocks
// to control the isAtomicBatchSupported mock
mockMessengerCall.mockReturnValueOnce(mockSelectedAccount); // getAccountByAddress
mockMessengerCall.mockImplementationOnce(jest.fn()); // track event
mockMessengerCall.mockRejectedValueOnce(
new Error('isAtomicBatchSupported failed'),
); // isAtomicBatchSupported throws
setupApprovalMocks();
setupBridgeMocks();

const { controller } = getController(mockMessengerCall);
const result = await controller.submitTx(
(mockEvmQuoteResponse.trade as TxData).from,
mockEvmQuoteResponse,
false, // STX disabled - uses non-batch path
);
controller.stopAllPolling();

// Should fall back to non-batch path when isAtomicBatchSupported throws
expect(addTransactionFn).toHaveBeenCalledTimes(2);
expect(addTransactionBatchFn).not.toHaveBeenCalled();
expect(result).toBeDefined();
});
});

Expand Down
Loading
Loading