Skip to content

Commit af7b80f

Browse files
committed
feat(STX-331): upgrade to smart-transactions-controller
1 parent 27aa96d commit af7b80f

14 files changed

Lines changed: 336 additions & 657 deletions

app/scripts/controller-init/messengers/smart-transactions-controller-messenger.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
1+
import type { ErrorReportingServiceCaptureExceptionAction } from '@metamask/error-reporting-service';
12
import { Messenger } from '@metamask/messenger';
2-
import type {
3-
TransactionControllerConfirmExternalTransactionAction,
4-
TransactionControllerGetNonceLockAction,
5-
TransactionControllerGetTransactionsAction,
6-
TransactionControllerUpdateTransactionAction,
7-
} from '@metamask/transaction-controller';
83
import {
94
NetworkControllerGetNetworkClientByIdAction,
105
NetworkControllerGetStateAction,
116
NetworkControllerStateChangeEvent,
127
} from '@metamask/network-controller';
8+
import type {
9+
RemoteFeatureFlagControllerGetStateAction,
10+
RemoteFeatureFlagControllerStateChangeEvent,
11+
} from '@metamask/remote-feature-flag-controller';
12+
import type {
13+
TransactionControllerGetNonceLockAction,
14+
TransactionControllerGetTransactionsAction,
15+
TransactionControllerUpdateTransactionAction,
16+
} from '@metamask/transaction-controller';
1317
import { MetaMetricsControllerTrackEventAction } from '../../controllers/metametrics-controller';
1418
import { RootMessenger } from '../../lib/messenger';
1519

1620
type MessengerActions =
21+
| ErrorReportingServiceCaptureExceptionAction
1722
| NetworkControllerGetNetworkClientByIdAction
1823
| NetworkControllerGetStateAction
24+
| RemoteFeatureFlagControllerGetStateAction
1925
| TransactionControllerGetNonceLockAction
2026
| TransactionControllerGetTransactionsAction
21-
| TransactionControllerUpdateTransactionAction
22-
| TransactionControllerConfirmExternalTransactionAction;
27+
| TransactionControllerUpdateTransactionAction;
2328

24-
type MessengerEvents = NetworkControllerStateChangeEvent;
29+
type MessengerEvents =
30+
| NetworkControllerStateChangeEvent
31+
| RemoteFeatureFlagControllerStateChangeEvent;
2532

2633
export type SmartTransactionsControllerMessenger = ReturnType<
2734
typeof getSmartTransactionsControllerMessenger
@@ -42,14 +49,18 @@ export function getSmartTransactionsControllerMessenger(
4249
messenger.delegate({
4350
messenger: controllerMessenger,
4451
actions: [
52+
'ErrorReportingService:captureException',
4553
'NetworkController:getNetworkClientById',
4654
'NetworkController:getState',
55+
'RemoteFeatureFlagController:getState',
4756
'TransactionController:getNonceLock',
48-
'TransactionController:confirmExternalTransaction',
4957
'TransactionController:getTransactions',
5058
'TransactionController:updateTransaction',
5159
],
52-
events: ['NetworkController:stateChange'],
60+
events: [
61+
'NetworkController:stateChange',
62+
'RemoteFeatureFlagController:stateChange',
63+
],
5364
});
5465
return controllerMessenger;
5566
}

app/scripts/controller-init/smart-transactions/smart-transactions-controller-init.test.ts

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ jest.mock('@metamask/smart-transactions-controller');
3535
type MockAccountsController = Pick<AccountsController, 'getSelectedAccount'>;
3636
type MockTransactionController = Pick<
3737
TransactionController,
38-
| 'getNonceLock'
39-
| 'confirmExternalTransaction'
40-
| 'getTransactions'
41-
| 'updateTransaction'
38+
'getNonceLock' | 'getTransactions' | 'updateTransaction'
4239
>;
4340

4441
type TestInitRequest = ControllerInitRequest<
@@ -96,7 +93,6 @@ describe('SmartTransactionsController Init', () => {
9693

9794
const transactionController: MockTransactionController = {
9895
getNonceLock: jest.fn().mockResolvedValue({ releaseLock: jest.fn() }),
99-
confirmExternalTransaction: jest.fn(),
10096
getTransactions: jest.fn().mockReturnValue([]),
10197
updateTransaction: jest.fn(),
10298
};
@@ -324,63 +320,6 @@ describe('SmartTransactionsController Init', () => {
324320
expect(listener).toHaveBeenCalledWith(testPayload);
325321
});
326322

327-
describe('getFeatureFlags', () => {
328-
it('returns feature flags from state', () => {
329-
const { fullRequest } = buildInitRequest();
330-
SmartTransactionsControllerInit(fullRequest);
331-
332-
const constructorCall =
333-
smartTransactionsControllerClassMock.mock.calls[0][0];
334-
const { getFeatureFlags } = constructorCall;
335-
336-
const result = getFeatureFlags();
337-
338-
expect(fullRequest.getUIState).toHaveBeenCalled();
339-
expect(result).toHaveProperty('smartTransactions');
340-
expect(result.smartTransactions).toHaveProperty('extensionActive');
341-
expect(result.smartTransactions).toHaveProperty('mobileActive');
342-
expect(result.smartTransactions).toHaveProperty('expectedDeadline');
343-
expect(result.smartTransactions).toHaveProperty('maxDeadline');
344-
expect(result.smartTransactions).toHaveProperty(
345-
'extensionReturnTxHashAsap',
346-
);
347-
});
348-
349-
it('returns default feature flags when getFeatureFlagsByChainId returns null', () => {
350-
// To test the null case, we need to make getStateUI return a state
351-
// that would cause getFeatureFlagsByChainId to return null
352-
const { fullRequest } = buildInitRequest({
353-
getUIState: jest.fn().mockReturnValue({
354-
preferences: {},
355-
selectedNetworkClientId: 'mainnet',
356-
networkConfigurationsByChainId: {
357-
'0x1': {
358-
chainId: '0x1',
359-
rpcEndpoints: [
360-
{
361-
networkClientId: 'mainnet',
362-
url: 'https://mainnet.infura.io/v3/abc',
363-
},
364-
],
365-
},
366-
},
367-
// No swapsState to test null case
368-
}),
369-
});
370-
371-
SmartTransactionsControllerInit(fullRequest);
372-
373-
const constructorCall =
374-
smartTransactionsControllerClassMock.mock.calls[0][0];
375-
const { getFeatureFlags } = constructorCall;
376-
377-
const result = getFeatureFlags();
378-
379-
// When getFeatureFlagsByChainId returns null, the result should be null
380-
expect(result).toBeNull();
381-
});
382-
});
383-
384323
describe('getMetaMetricsProps', () => {
385324
it('returns correct meta metrics properties', async () => {
386325
const { fullRequest } = buildInitRequest();

app/scripts/controller-init/smart-transactions/smart-transactions-controller-init.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ import {
55
import type { Hex } from '@metamask/utils';
66
import type { TraceCallback } from '@metamask/controller-utils';
77
import { getAllowedSmartTransactionsChainIds } from '../../../../shared/constants/smartTransactions';
8-
import { getFeatureFlagsByChainId } from '../../../../shared/modules/selectors';
9-
import { type ProviderConfigState } from '../../../../shared/modules/selectors/networks';
10-
import { type FeatureFlagsMetaMaskState } from '../../../../shared/modules/selectors/feature-flags';
11-
import type { FeatureFlags } from '../../lib/smart-transaction/smart-transactions';
128
import { ControllerInitFunction, ControllerInitRequest } from '../types';
139
import {
1410
SmartTransactionsControllerInitMessenger,
@@ -57,12 +53,6 @@ export const SmartTransactionsControllerInit: ControllerInitFunction<
5753
>[0]['trackMetaMetricsEvent'],
5854
state: persistedState.SmartTransactionsController,
5955
messenger: controllerMessenger,
60-
getFeatureFlags: () => {
61-
const state = { metamask: getUIState() };
62-
return getFeatureFlagsByChainId(
63-
state as unknown as ProviderConfigState & FeatureFlagsMetaMaskState,
64-
) as unknown as FeatureFlags;
65-
},
6656
getMetaMetricsProps: async () => {
6757
const metamask = getUIState();
6858
const { internalAccounts } = metamask;

app/scripts/lib/smart-transaction/smart-transactions.test.ts

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
type SmartTransaction,
1818
} from '@metamask/smart-transactions-controller';
1919
import type {
20-
TransactionControllerConfirmExternalTransactionAction,
2120
TransactionControllerGetNonceLockAction,
2221
TransactionControllerGetTransactionsAction,
2322
TransactionControllerUpdateTransactionAction,
@@ -88,7 +87,6 @@ function withRequest<ReturnValue>(
8887
MockAnyNamespace,
8988
| MessengerActions<SmartTransactionsControllerMessenger>
9089
| TransactionControllerGetNonceLockAction
91-
| TransactionControllerConfirmExternalTransactionAction
9290
| TransactionControllerGetTransactionsAction
9391
| TransactionControllerUpdateTransactionAction
9492
| AllowedActions,
@@ -123,6 +121,24 @@ function withRequest<ReturnValue>(
123121
const endFlowSpy = jest.fn();
124122
messenger.registerActionHandler('ApprovalController:endFlow', endFlowSpy);
125123

124+
// Register RemoteFeatureFlagController:getState handler for the new controller
125+
messenger.registerActionHandler(
126+
'RemoteFeatureFlagController:getState',
127+
jest.fn().mockReturnValue({
128+
remoteFeatureFlags: {
129+
smartTransactionsNetworks: {
130+
default: { extensionActive: true },
131+
},
132+
},
133+
}),
134+
);
135+
136+
// Register ErrorReportingService:captureException handler
137+
messenger.registerActionHandler(
138+
'ErrorReportingService:captureException',
139+
jest.fn(),
140+
);
141+
126142
const smartTransactionsControllerMessenger = new Messenger<
127143
'SmartTransactionsController',
128144
MessengerActions<SmartTransactionsControllerMessenger>,
@@ -136,19 +152,22 @@ function withRequest<ReturnValue>(
136152
messenger: smartTransactionsControllerMessenger,
137153
actions: [
138154
'TransactionController:getNonceLock',
139-
'TransactionController:confirmExternalTransaction',
140155
'TransactionController:getTransactions',
141156
'TransactionController:updateTransaction',
157+
'RemoteFeatureFlagController:getState',
158+
'ErrorReportingService:captureException',
159+
],
160+
events: [
161+
'NetworkController:stateChange',
162+
'RemoteFeatureFlagController:stateChange',
142163
],
143-
events: ['NetworkController:stateChange'],
144164
});
145165

146166
const smartTransactionsController = new SmartTransactionsController({
147167
messenger: smartTransactionsControllerMessenger,
148168
trackMetaMetricsEvent: jest.fn(),
149169
getMetaMetricsProps: jest.fn(),
150170
clientId: ClientId.Extension,
151-
getFeatureFlags: jest.fn(),
152171
});
153172

154173
jest.spyOn(smartTransactionsController, 'getFees').mockResolvedValue({
@@ -202,12 +221,10 @@ function withRequest<ReturnValue>(
202221
featureFlags: {
203222
extensionActive: true,
204223
mobileActive: false,
205-
smartTransactions: {
206-
expectedDeadline: 45,
207-
maxDeadline: 150,
208-
extensionReturnTxHashAsap: false,
209-
extensionReturnTxHashAsapBatch: false,
210-
},
224+
expectedDeadline: 45,
225+
maxDeadline: 150,
226+
extensionReturnTxHashAsap: false,
227+
extensionReturnTxHashAsapBatch: false,
211228
},
212229
...options,
213230
};
@@ -296,7 +313,7 @@ describe('submitSmartTransactionHook', () => {
296313
it('skips getting fees if the transaction is signed and sponsored', async () => {
297314
withRequest(async ({ request }) => {
298315
request.transactionMeta.isGasFeeSponsored = true;
299-
request.featureFlags.smartTransactions.extensionReturnTxHashAsap = true;
316+
request.featureFlags.extensionReturnTxHashAsap = true;
300317

301318
const result = await submitSmartTransactionHook(request);
302319

@@ -312,7 +329,7 @@ describe('submitSmartTransactionHook', () => {
312329

313330
it('returns a txHash asap if the feature flag requires it', async () => {
314331
withRequest(async ({ request }) => {
315-
request.featureFlags.smartTransactions.extensionReturnTxHashAsap = true;
332+
request.featureFlags.extensionReturnTxHashAsap = true;
316333
const result = await submitSmartTransactionHook(request);
317334
expect(result).toEqual({ transactionHash: txHash });
318335
});
@@ -901,13 +918,11 @@ describe('submitSmartTransactionHook', () => {
901918
featureFlags: {
902919
extensionActive: true,
903920
mobileActive: false,
904-
smartTransactions: {
905-
expectedDeadline: 45,
906-
maxDeadline: 150,
907-
extensionReturnTxHashAsap: false,
908-
extensionReturnTxHashAsapBatch: false,
909-
extensionSkipSmartTransactionStatusPage: true,
910-
},
921+
expectedDeadline: 45,
922+
maxDeadline: 150,
923+
extensionReturnTxHashAsap: false,
924+
extensionReturnTxHashAsapBatch: false,
925+
extensionSkipSmartTransactionStatusPage: true,
911926
},
912927
},
913928
},
@@ -939,13 +954,11 @@ describe('submitSmartTransactionHook', () => {
939954
featureFlags: {
940955
extensionActive: true,
941956
mobileActive: false,
942-
smartTransactions: {
943-
expectedDeadline: 45,
944-
maxDeadline: 150,
945-
extensionReturnTxHashAsap: false,
946-
extensionReturnTxHashAsapBatch: false,
947-
extensionSkipSmartTransactionStatusPage: false,
948-
},
957+
expectedDeadline: 45,
958+
maxDeadline: 150,
959+
extensionReturnTxHashAsap: false,
960+
extensionReturnTxHashAsapBatch: false,
961+
extensionSkipSmartTransactionStatusPage: false,
949962
},
950963
},
951964
},
@@ -977,13 +990,11 @@ describe('submitSmartTransactionHook', () => {
977990
featureFlags: {
978991
extensionActive: true,
979992
mobileActive: false,
980-
smartTransactions: {
981-
expectedDeadline: 45,
982-
maxDeadline: 150,
983-
extensionReturnTxHashAsap: false,
984-
extensionReturnTxHashAsapBatch: false,
985-
// extensionSkipSTXStatusPage is not set (undefined)
986-
},
993+
expectedDeadline: 45,
994+
maxDeadline: 150,
995+
extensionReturnTxHashAsap: false,
996+
extensionReturnTxHashAsapBatch: false,
997+
// extensionSkipSmartTransactionStatusPage is not set (undefined)
987998
},
988999
},
9891000
},
@@ -1039,13 +1050,11 @@ describe('submitSmartTransactionHook', () => {
10391050
featureFlags: {
10401051
extensionActive: true,
10411052
mobileActive: false,
1042-
smartTransactions: {
1043-
expectedDeadline: 45,
1044-
maxDeadline: 150,
1045-
extensionReturnTxHashAsap: false,
1046-
extensionReturnTxHashAsapBatch: false,
1047-
extensionSkipSmartTransactionStatusPage: true,
1048-
},
1053+
expectedDeadline: 45,
1054+
maxDeadline: 150,
1055+
extensionReturnTxHashAsap: false,
1056+
extensionReturnTxHashAsapBatch: false,
1057+
extensionSkipSmartTransactionStatusPage: true,
10491058
},
10501059
},
10511060
},
@@ -1077,13 +1086,11 @@ describe('submitSmartTransactionHook', () => {
10771086
featureFlags: {
10781087
extensionActive: true,
10791088
mobileActive: false,
1080-
smartTransactions: {
1081-
expectedDeadline: 45,
1082-
maxDeadline: 150,
1083-
extensionReturnTxHashAsap: false,
1084-
extensionReturnTxHashAsapBatch: false,
1085-
extensionSkipSmartTransactionStatusPage: true,
1086-
},
1089+
expectedDeadline: 45,
1090+
maxDeadline: 150,
1091+
extensionReturnTxHashAsap: false,
1092+
extensionReturnTxHashAsapBatch: false,
1093+
extensionSkipSmartTransactionStatusPage: true,
10871094
},
10881095
transactions: [
10891096
{
@@ -1368,7 +1375,7 @@ describe('submitBatchSmartTransactionHook', () => {
13681375

13691376
it('returns txHashes asap if extensionReturnTxHashAsapBatch feature flag is enabled', async () => {
13701377
withRequest(async ({ request }) => {
1371-
request.featureFlags.smartTransactions.extensionReturnTxHashAsapBatch = true;
1378+
request.featureFlags.extensionReturnTxHashAsapBatch = true;
13721379
request.smartTransactionsController.submitSignedTransactions = jest.fn(
13731380
async (_) => {
13741381
return {
@@ -1388,7 +1395,7 @@ describe('submitBatchSmartTransactionHook', () => {
13881395

13891396
it('waits for transaction hash if extensionReturnTxHashAsapBatch is false', async () => {
13901397
withRequest(async ({ request, messenger }) => {
1391-
request.featureFlags.smartTransactions.extensionReturnTxHashAsapBatch = false;
1398+
request.featureFlags.extensionReturnTxHashAsapBatch = false;
13921399
request.smartTransactionsController.submitSignedTransactions = jest.fn(
13931400
async (_) => {
13941401
return {

0 commit comments

Comments
 (0)