Skip to content

Commit fc3b5d4

Browse files
chore(runway): cherry-pick 0e57cdc (#29268)
- chore: bump @metamask/smart-transactions-controller to ^24.0.0 (#28943) ## **Description** Bumps `@metamask/smart-transactions-controller` from `^23.0.0` to `^24.0.0` and handles the v24 breaking change. **Breaking change in v24:** The `getBearerToken` constructor parameter was removed. The controller now calls `AuthenticationController:getBearerToken` directly through its own runtime messenger. Changes made: - `AuthenticationController:getBearerToken` moved from the init messenger to the controller's runtime messenger (`getSmartTransactionsControllerMessenger`) - Removed the `getBearerToken` wrapper closure from `smart-transactions-controller-init.ts` - Mobile-specific: `setSentinelApiAuth` still needs the bearer token and now calls `controllerMessenger.call('AuthenticationController:getBearerToken')` directly - Updated unit tests to match the new constructor signature No behavior change — the bearer token is still fetched and sent with authenticated requests. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: STX-503 ## **Manual testing steps** ```gherkin Feature: smart transactions controller bump Scenario: no behavior change Given the app is open When smart transactions are used Then they behave identically to before the bump ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [ ] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. #### Performance checks (if applicable) N/A — no runtime behavior change. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches auth token plumbing and messenger delegation for Smart Transactions/Sentinel requests; incorrect wiring could silently drop authenticated headers or break controller calls, though the change is narrowly scoped and covered by updated tests. > > **Overview** > Updates `@metamask/smart-transactions-controller` to `^24.0.0` and adjusts the engine integration for the v24 breaking change that removes the controller constructor’s `getBearerToken` option. > > `AuthenticationController:getBearerToken` delegation is moved to the Smart Transactions *runtime* messenger, and init-time delegation is removed; `smart-transactions-controller-init` now configures Sentinel auth via `setSentinelApiAuth` using a token getter that calls `controllerMessenger.call('AuthenticationController:getBearerToken')`. Unit tests are updated to assert the new constructor signature and to validate Sentinel auth setup/token retrieval behavior. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit e0e1eb3. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY --> [0e57cdc](0e57cdc) Co-authored-by: Remi ARQUEVAUX <r.arquevaux@gmail.com>
1 parent 4c406ba commit fc3b5d4

6 files changed

Lines changed: 47 additions & 48 deletions

app/core/Engine/controllers/smart-transactions-controller-init.test.ts

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import {
1111
SmartTransactionsControllerMessenger,
1212
} from '@metamask/smart-transactions-controller';
1313
import { MOCK_ANY_NAMESPACE, MockAnyNamespace } from '@metamask/messenger';
14+
import { setSentinelApiAuth } from '../../../util/transactions/sentinel-api';
1415

1516
jest.mock('@metamask/smart-transactions-controller');
17+
jest.mock('../../../util/transactions/sentinel-api');
1618

1719
function getInitRequestMock(): jest.Mocked<
1820
MessengerClientInitRequest<
@@ -51,69 +53,69 @@ describe('SmartTransactionsControllerInit', () => {
5153
clientId: 'mobile',
5254
getMetaMetricsProps: expect.any(Function),
5355
trackMetaMetricsEvent: expect.any(Function),
54-
getBearerToken: expect.any(Function),
5556
trace: expect.any(Function),
5657
});
5758
});
5859

59-
describe('getBearerToken', () => {
60-
it('passes getter that returns token when AuthenticationController returns one', async () => {
60+
describe('sentinel API auth', () => {
61+
const mockSetSentinelApiAuth = jest.mocked(setSentinelApiAuth);
62+
63+
beforeEach(() => {
64+
mockSetSentinelApiAuth.mockClear();
65+
});
66+
67+
it('configures sentinel API auth that returns token when AuthenticationController returns one', async () => {
6168
const bearerToken = 'test-bearer-token';
6269
const request = getInitRequestMock();
6370
const mockCall = jest.fn().mockResolvedValue(bearerToken);
64-
jest.spyOn(request.initMessenger, 'call').mockImplementation(mockCall);
71+
jest
72+
.spyOn(request.controllerMessenger, 'call')
73+
.mockImplementation(mockCall);
6574

6675
smartTransactionsControllerInit(request);
6776

68-
const controllerMock = jest.mocked(SmartTransactionsController);
69-
const constructorCall =
70-
controllerMock.mock.calls[controllerMock.mock.calls.length - 1][0];
71-
const getBearerToken = constructorCall.getBearerToken as () => Promise<
72-
string | undefined
73-
>;
74-
75-
const result = await getBearerToken();
77+
expect(mockSetSentinelApiAuth).toHaveBeenCalledWith(expect.any(Function));
78+
const sentinelGetter = mockSetSentinelApiAuth.mock.calls[0][0] as (
79+
...args: unknown[]
80+
) => Promise<string | undefined>;
81+
const result = await sentinelGetter();
7682

7783
expect(result).toBe(bearerToken);
7884
expect(mockCall).toHaveBeenCalledWith(
7985
'AuthenticationController:getBearerToken',
8086
);
8187
});
8288

83-
it('passes getter that returns undefined when AuthenticationController returns undefined', async () => {
89+
it('configures sentinel API auth that returns undefined when AuthenticationController returns undefined', async () => {
8490
const request = getInitRequestMock();
8591
const mockCall = jest.fn().mockResolvedValue(undefined);
86-
jest.spyOn(request.initMessenger, 'call').mockImplementation(mockCall);
92+
jest
93+
.spyOn(request.controllerMessenger, 'call')
94+
.mockImplementation(mockCall);
8795

8896
smartTransactionsControllerInit(request);
8997

90-
const controllerMock = jest.mocked(SmartTransactionsController);
91-
const constructorCall =
92-
controllerMock.mock.calls[controllerMock.mock.calls.length - 1][0];
93-
const getBearerToken = constructorCall.getBearerToken as () => Promise<
94-
string | undefined
95-
>;
96-
97-
const result = await getBearerToken();
98+
const sentinelGetter = mockSetSentinelApiAuth.mock.calls[0][0] as (
99+
...args: unknown[]
100+
) => Promise<string | undefined>;
101+
const result = await sentinelGetter();
98102

99103
expect(result).toBeUndefined();
100104
});
101105

102-
it('passes getter that returns undefined when AuthenticationController throws', async () => {
106+
it('configures sentinel API auth that returns undefined when AuthenticationController throws', async () => {
103107
const request = getInitRequestMock();
104108
const mockCall = jest.fn().mockRejectedValue(new Error('auth error'));
105-
jest.spyOn(request.initMessenger, 'call').mockImplementation(mockCall);
109+
jest
110+
.spyOn(request.controllerMessenger, 'call')
111+
.mockImplementation(mockCall);
106112

107113
smartTransactionsControllerInit(request);
108114

109-
const controllerMock = jest.mocked(SmartTransactionsController);
110-
const constructorCall =
111-
controllerMock.mock.calls[controllerMock.mock.calls.length - 1][0];
112-
const getBearerToken = constructorCall.getBearerToken as () => Promise<
113-
string | undefined
114-
>;
115-
116-
const result = await getBearerToken();
115+
const sentinelGetter = mockSetSentinelApiAuth.mock.calls[0][0] as (
116+
...args: unknown[]
117+
) => Promise<string | undefined>;
118+
const result = await sentinelGetter();
117119

118120
expect(result).toBeUndefined();
119121
});

app/core/Engine/controllers/smart-transactions-controller-init.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export const smartTransactionsControllerInit: MessengerClientInitFunction<
5555
const getBearerToken = async (): Promise<string | undefined> => {
5656
try {
5757
return await Promise.resolve(
58-
initMessenger.call('AuthenticationController:getBearerToken'),
58+
controllerMessenger.call('AuthenticationController:getBearerToken'),
5959
);
6060
} catch {
6161
return undefined;
@@ -74,7 +74,6 @@ export const smartTransactionsControllerInit: MessengerClientInitFunction<
7474
// transactions.
7575
getMetaMetricsProps: () => Promise.resolve({}),
7676
trackMetaMetricsEvent,
77-
getBearerToken,
7877

7978
// @ts-expect-error: Type of `TraceRequest` is different.
8079
trace,

app/core/Engine/messengers/smart-transactions-controller-messenger.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('getSmartTransactionsControllerMessenger', () => {
3737
expect(delegateSpy).toHaveBeenCalledWith(
3838
expect.objectContaining({
3939
actions: expect.arrayContaining([
40+
'AuthenticationController:getBearerToken',
4041
'NetworkController:getNetworkClientById',
4142
'NetworkController:getState',
4243
'RemoteFeatureFlagController:getState',

app/core/Engine/messengers/smart-transactions-controller-messenger.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
import { RootMessenger } from '../types';
77
import { SmartTransactionsControllerMessenger } from '@metamask/smart-transactions-controller';
88
import { AnalyticsControllerActions } from '@metamask/analytics-controller';
9-
import { AuthenticationController } from '@metamask/profile-sync-controller';
109

1110
/**
1211
* Get the messenger for the smart transactions controller. This is scoped to the
@@ -29,6 +28,7 @@ export function getSmartTransactionsControllerMessenger(
2928
});
3029
rootMessenger.delegate({
3130
actions: [
31+
'AuthenticationController:getBearerToken',
3232
'NetworkController:getNetworkClientById',
3333
'NetworkController:getState',
3434
'RemoteFeatureFlagController:getState',
@@ -46,8 +46,7 @@ export function getSmartTransactionsControllerMessenger(
4646
}
4747

4848
type SmartTransactionsControllerInitMessengerActions =
49-
| AnalyticsControllerActions
50-
| AuthenticationController.AuthenticationControllerGetBearerTokenAction;
49+
AnalyticsControllerActions;
5150

5251
/**
5352
* Get the SmartTransactionsControllerInitMessenger for the SmartTransactionsController.
@@ -79,10 +78,7 @@ export function getSmartTransactionsControllerInitMessenger(
7978
});
8079

8180
rootMessenger.delegate({
82-
actions: [
83-
'AnalyticsController:trackEvent',
84-
'AuthenticationController:getBearerToken',
85-
],
81+
actions: ['AnalyticsController:trackEvent'],
8682
events: [],
8783
messenger,
8884
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@
313313
"@metamask/selected-network-controller": "^25.0.0",
314314
"@metamask/signature-controller": "^39.1.2",
315315
"@metamask/slip44": "^4.2.0",
316-
"@metamask/smart-transactions-controller": "^23.0.0",
316+
"@metamask/smart-transactions-controller": "^24.0.0",
317317
"@metamask/snaps-controllers": "^20.0.1",
318318
"@metamask/snaps-execution-environments": "^11.0.2",
319319
"@metamask/snaps-rpc-methods": "^15.1.1",

yarn.lock

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9934,9 +9934,9 @@ __metadata:
99349934
languageName: node
99359935
linkType: hard
99369936

9937-
"@metamask/smart-transactions-controller@npm:^23.0.0":
9938-
version: 23.0.0
9939-
resolution: "@metamask/smart-transactions-controller@npm:23.0.0"
9937+
"@metamask/smart-transactions-controller@npm:^24.0.0":
9938+
version: 24.0.0
9939+
resolution: "@metamask/smart-transactions-controller@npm:24.0.0"
99409940
dependencies:
99419941
"@babel/runtime": "npm:^7.24.1"
99429942
"@ethereumjs/tx": "npm:^5.2.1"
@@ -9948,9 +9948,10 @@ __metadata:
99489948
"@metamask/controller-utils": "npm:^11.0.0"
99499949
"@metamask/eth-json-rpc-provider": "npm:^4.1.6"
99509950
"@metamask/eth-query": "npm:^4.0.0"
9951-
"@metamask/messenger": "npm:^0.3.0"
9951+
"@metamask/messenger": "npm:^1.1.0"
99529952
"@metamask/network-controller": "npm:^30.0.0"
99539953
"@metamask/polling-controller": "npm:^16.0.0"
9954+
"@metamask/profile-sync-controller": "npm:^28.0.2"
99549955
"@metamask/remote-feature-flag-controller": "npm:^4.1.0"
99559956
"@metamask/superstruct": "npm:^3.1.0"
99569957
"@metamask/transaction-controller": "npm:^63.0.0"
@@ -9968,7 +9969,7 @@ __metadata:
99689969
optional: true
99699970
"@metamask/gas-fee-controller":
99709971
optional: true
9971-
checksum: 10/5dc6e3fdc8ad93967da8e1a8ec9334b3fd82444793074689981ac56a38159a8c7f651d86ac2282463af424519ca5630d46f09d0833da149928974761f8fac7fe
9972+
checksum: 10/9dad9c49e6c2ce84377b5f1ba13184a6c131763f2d001ef33ac7ec82329303ae8f5c1b5be36bc98e86dfbdcef91f9d63a67050a93ce070d6a2d17836ee632e64
99729973
languageName: node
99739974
linkType: hard
99749975

@@ -35972,7 +35973,7 @@ __metadata:
3597235973
"@metamask/selected-network-controller": "npm:^25.0.0"
3597335974
"@metamask/signature-controller": "npm:^39.1.2"
3597435975
"@metamask/slip44": "npm:^4.2.0"
35975-
"@metamask/smart-transactions-controller": "npm:^23.0.0"
35976+
"@metamask/smart-transactions-controller": "npm:^24.0.0"
3597635977
"@metamask/snaps-controllers": "npm:^20.0.1"
3597735978
"@metamask/snaps-execution-environments": "npm:^11.0.2"
3597835979
"@metamask/snaps-rpc-methods": "npm:^15.1.1"

0 commit comments

Comments
 (0)