Skip to content

Commit c9af853

Browse files
authored
Merge branch 'main' into dismiss-conditions
2 parents f5579f3 + 907dbd1 commit c9af853

File tree

96 files changed

+3501
-1283
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+3501
-1283
lines changed

.github/CODEOWNERS

+3-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ app/scripts/controllers/swaps @MetaMask/swaps-engineers
111111
**/snaps/** @MetaMask/snaps-devs
112112
shared/constants/permissions.ts @MetaMask/snaps-devs
113113
ui/helpers/utils/permission.js @MetaMask/snaps-devs
114-
ui/hooks/useTransactionInsights.js @MetaMask/snaps-devs
114+
115+
# Co-owned by Confirmations and Snaps
116+
ui/components/app/metamask-template-renderer @MetaMask/confirmations @MetaMask/snaps-devs
115117

116118
# Wallet UX
117119
ui/components/multichain @MetaMask/wallet-ux

.yarnrc.yml

+6
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ npmAuditIgnoreAdvisories:
126126
# New package name format for new versions: @ethereumjs/wallet.
127127
- 'ethereumjs-wallet (deprecation)'
128128

129+
# The new trezor version breaks the webpack build due to issues with ESM and CommonJS
130+
# Leading to this error on start: `Uncaught ReferenceError: exports is not defined`
131+
# We temporarily ignore the audit failure until we can safely upgrade to the new version without breaking the webpack build
132+
# Check Trezor 9.5.X Changelog for more info: https://github.com/trezor/trezor-suite/blob/develop/packages/connect/CHANGELOG.md
133+
- '@trezor/connect-web (deprecation)'
134+
129135
plugins:
130136
- path: .yarn/plugins/@yarnpkg/plugin-allow-scripts.cjs
131137
spec: 'https://raw.githubusercontent.com/LavaMoat/LavaMoat/main/packages/yarn-plugin-allow-scripts/bundles/@yarnpkg/plugin-allow-scripts.js'

app/_locales/en/messages.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/_locales/en_GB/messages.json

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/images/MegaETH-logo-testnet.svg

+44
Loading

app/scripts/controller-init/confirmations/transaction-controller-init.test.ts

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ function buildControllerMock(
3939

4040
function buildInitRequestMock(): jest.Mocked<
4141
ControllerInitRequest<
42-
// @ts-expect-error TODO: Resolve mismatch between base-controller versions.
4342
TransactionControllerMessenger,
4443
TransactionControllerInitMessenger
4544
>

app/scripts/controller-init/confirmations/transaction-controller-init.ts

-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ import { TransactionMetricsRequest } from '../../../../shared/types/metametrics'
4848

4949
export const TransactionControllerInit: ControllerInitFunction<
5050
TransactionController,
51-
// @ts-expect-error TODO: Resolve mismatch between base-controller versions.
5251
TransactionControllerMessenger,
5352
TransactionControllerInitMessenger
5453
> = (request) => {
@@ -189,7 +188,6 @@ function getApi(
189188

190189
function getControllers(
191190
request: ControllerInitRequest<
192-
// @ts-expect-error TODO: Resolve mismatch between base-controller versions.
193191
TransactionControllerMessenger,
194192
TransactionControllerInitMessenger
195193
>,

app/scripts/controller-init/controller-list.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import {
3030
RateLimitController,
3131
RateLimitedApiMap,
3232
} from '@metamask/rate-limit-controller';
33+
import { Controller as AuthenticationController } from '@metamask/profile-sync-controller/auth';
34+
import { Controller as UserStorageController } from '@metamask/profile-sync-controller/user-storage';
3335
import OnboardingController from '../controllers/onboarding';
3436
import { PreferencesController } from '../controllers/preferences-controller';
3537
import SwapsController from '../controllers/swaps';
@@ -38,6 +40,7 @@ import SwapsController from '../controllers/swaps';
3840
* Union of all controllers supporting or required by modular initialization.
3941
*/
4042
export type Controller =
43+
| AuthenticationController
4144
| CronjobController
4245
| ExecutionService
4346
| GasFeeController
@@ -65,13 +68,15 @@ export type Controller =
6568
| (TransactionUpdateController & {
6669
name: 'TransactionUpdateController';
6770
state: Record<string, unknown>;
68-
});
71+
})
72+
| UserStorageController;
6973

7074
/**
7175
* Flat state object for all controllers supporting or required by modular initialization.
7276
* e.g. `{ transactions: [] }`.
7377
*/
7478
export type ControllerFlatState = AccountsController['state'] &
79+
AuthenticationController['state'] &
7580
CronjobController['state'] &
7681
GasFeeController['state'] &
7782
JsonSnapsRegistry['state'] &
@@ -94,4 +99,5 @@ export type ControllerFlatState = AccountsController['state'] &
9499
SnapInsightsController['state'] &
95100
SnapInterfaceController['state'] &
96101
TransactionController['state'] &
97-
SwapsController['state'];
102+
SwapsController['state'] &
103+
UserStorageController['state'];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Controller as AuthenticationController } from '@metamask/profile-sync-controller/auth';
2+
import { Messenger } from '@metamask/base-controller';
3+
import { buildControllerInitRequestMock } from '../test/utils';
4+
import { ControllerInitRequest } from '../types';
5+
import {
6+
getAuthenticationControllerMessenger,
7+
AuthenticationControllerMessenger,
8+
} from '../messengers/identity';
9+
import { AuthenticationControllerInit } from './authentication-controller-init';
10+
11+
jest.mock('@metamask/profile-sync-controller/auth');
12+
13+
function buildInitRequestMock(): jest.Mocked<
14+
ControllerInitRequest<AuthenticationControllerMessenger>
15+
> {
16+
const baseControllerMessenger = new Messenger();
17+
18+
return {
19+
...buildControllerInitRequestMock(),
20+
controllerMessenger: getAuthenticationControllerMessenger(
21+
baseControllerMessenger,
22+
),
23+
initMessenger: undefined,
24+
};
25+
}
26+
27+
describe('AuthenticationControllerInit', () => {
28+
const AuthenticationControllerClassMock = jest.mocked(
29+
AuthenticationController,
30+
);
31+
32+
beforeEach(() => {
33+
jest.resetAllMocks();
34+
});
35+
36+
it('returns controller instance', () => {
37+
const requestMock = buildInitRequestMock();
38+
expect(AuthenticationControllerInit(requestMock).controller).toBeInstanceOf(
39+
AuthenticationController,
40+
);
41+
});
42+
43+
it('initializes with correct messenger and state', () => {
44+
const requestMock = buildInitRequestMock();
45+
AuthenticationControllerInit(requestMock);
46+
47+
expect(AuthenticationControllerClassMock).toHaveBeenCalledWith({
48+
messenger: requestMock.controllerMessenger,
49+
state: requestMock.persistedState.AuthenticationController,
50+
metametrics: {
51+
getMetaMetricsId: requestMock.getMetaMetricsId,
52+
agent: 'extension',
53+
},
54+
});
55+
});
56+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {
2+
AuthenticationControllerState,
3+
Controller as AuthenticationController,
4+
} from '@metamask/profile-sync-controller/auth';
5+
import { ControllerInitFunction } from '../types';
6+
import { AuthenticationControllerMessenger } from '../messengers/identity';
7+
8+
/**
9+
* Initialize the Authentication controller.
10+
*
11+
* @param request - The request object.
12+
* @param request.controllerMessenger - The messenger to use for the controller.
13+
* @param request.persistedState - The persisted state of the extension.
14+
* @param request.getMetaMetricsId
15+
* @returns The initialized controller.
16+
*/
17+
export const AuthenticationControllerInit: ControllerInitFunction<
18+
AuthenticationController,
19+
AuthenticationControllerMessenger
20+
> = ({ controllerMessenger, persistedState, getMetaMetricsId }) => {
21+
const controller = new AuthenticationController({
22+
messenger: controllerMessenger,
23+
state:
24+
persistedState.AuthenticationController as AuthenticationControllerState,
25+
metametrics: {
26+
getMetaMetricsId,
27+
agent: 'extension',
28+
},
29+
});
30+
31+
return {
32+
controller,
33+
};
34+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { Controller as UserStorageController } from '@metamask/profile-sync-controller/user-storage';
2+
import { Messenger } from '@metamask/base-controller';
3+
import { buildControllerInitRequestMock } from '../test/utils';
4+
import { ControllerInitRequest } from '../types';
5+
import {
6+
getUserStorageControllerMessenger,
7+
UserStorageControllerMessenger,
8+
} from '../messengers/identity';
9+
import { UserStorageControllerInit } from './user-storage-controller-init';
10+
11+
jest.mock('@metamask/profile-sync-controller/user-storage');
12+
jest.mock('../../../../shared/modules/mv3.utils', () => ({
13+
isManifestV3: true,
14+
}));
15+
jest.mock('../../../../shared/modules/environment', () => ({
16+
isProduction: () => false,
17+
}));
18+
19+
function buildInitRequestMock(): jest.Mocked<
20+
ControllerInitRequest<UserStorageControllerMessenger>
21+
> {
22+
const baseControllerMessenger = new Messenger();
23+
24+
return {
25+
...buildControllerInitRequestMock(),
26+
controllerMessenger: getUserStorageControllerMessenger(
27+
baseControllerMessenger,
28+
),
29+
initMessenger: undefined,
30+
};
31+
}
32+
33+
describe('UserStorageControllerInit', () => {
34+
const UserStorageControllerClassMock = jest.mocked(UserStorageController);
35+
36+
beforeEach(() => {
37+
jest.resetAllMocks();
38+
});
39+
40+
it('returns controller instance', () => {
41+
const requestMock = buildInitRequestMock();
42+
expect(UserStorageControllerInit(requestMock).controller).toBeInstanceOf(
43+
UserStorageController,
44+
);
45+
});
46+
47+
it('initializes with correct messenger and state', () => {
48+
const requestMock = buildInitRequestMock();
49+
UserStorageControllerInit(requestMock);
50+
51+
expect(UserStorageControllerClassMock).toHaveBeenCalledWith({
52+
messenger: requestMock.controllerMessenger,
53+
state: requestMock.persistedState.UserStorageController,
54+
config: {
55+
accountSyncing: {
56+
maxNumberOfAccountsToAdd: 100,
57+
onAccountAdded: expect.any(Function),
58+
onAccountNameUpdated: expect.any(Function),
59+
onAccountSyncErroneousSituation: expect.any(Function),
60+
},
61+
},
62+
env: {
63+
isAccountSyncingEnabled: true,
64+
},
65+
});
66+
});
67+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import {
2+
UserStorageControllerMessenger,
3+
UserStorageControllerState,
4+
Controller as UserStorageController,
5+
} from '@metamask/profile-sync-controller/user-storage';
6+
import { captureException } from '@sentry/browser';
7+
import { ControllerInitFunction } from '../types';
8+
import { isProduction } from '../../../../shared/modules/environment';
9+
import {
10+
MetaMetricsEventCategory,
11+
MetaMetricsEventName,
12+
} from '../../../../shared/constants/metametrics';
13+
import { isManifestV3 } from '../../../../shared/modules/mv3.utils';
14+
15+
/**
16+
* Initialize the UserStorage controller.
17+
*
18+
* @param request - The request object.
19+
* @param request.controllerMessenger - The messenger to use for the controller.
20+
* @param request.persistedState - The persisted state of the extension.
21+
* @returns The initialized controller.
22+
*/
23+
export const UserStorageControllerInit: ControllerInitFunction<
24+
UserStorageController,
25+
UserStorageControllerMessenger
26+
> = (request) => {
27+
const { controllerMessenger, persistedState, trackEvent } = request;
28+
const controller = new UserStorageController({
29+
messenger: controllerMessenger,
30+
state: persistedState.UserStorageController as UserStorageControllerState,
31+
config: {
32+
accountSyncing: {
33+
maxNumberOfAccountsToAdd: isProduction() ? undefined : 100,
34+
onAccountAdded: (profileId) => {
35+
trackEvent({
36+
category: MetaMetricsEventCategory.ProfileSyncing,
37+
event: MetaMetricsEventName.AccountsSyncAdded,
38+
properties: {
39+
profile_id: profileId,
40+
},
41+
});
42+
},
43+
onAccountNameUpdated: (profileId) => {
44+
trackEvent({
45+
category: MetaMetricsEventCategory.ProfileSyncing,
46+
event: MetaMetricsEventName.AccountsSyncNameUpdated,
47+
properties: {
48+
profile_id: profileId,
49+
},
50+
});
51+
},
52+
onAccountSyncErroneousSituation: (
53+
profileId,
54+
situationMessage,
55+
sentryContext,
56+
) => {
57+
captureException(
58+
new Error(`Account sync - ${situationMessage}`),
59+
sentryContext,
60+
);
61+
trackEvent({
62+
category: MetaMetricsEventCategory.ProfileSyncing,
63+
event: MetaMetricsEventName.AccountsSyncErroneousSituation,
64+
properties: {
65+
profile_id: profileId,
66+
situation_message: situationMessage,
67+
},
68+
});
69+
},
70+
},
71+
},
72+
env: {
73+
isAccountSyncingEnabled: isManifestV3,
74+
},
75+
});
76+
77+
return {
78+
controller,
79+
};
80+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Messenger, RestrictedMessenger } from '@metamask/base-controller';
2+
import { getAuthenticationControllerMessenger } from './authentication-controller-messenger';
3+
4+
describe('getAuthenticationControllerMessenger', () => {
5+
it('returns a restricted messenger', () => {
6+
const messenger = new Messenger<never, never>();
7+
const authenticationControllerMessenger =
8+
getAuthenticationControllerMessenger(messenger);
9+
10+
expect(authenticationControllerMessenger).toBeInstanceOf(
11+
RestrictedMessenger,
12+
);
13+
});
14+
});

0 commit comments

Comments
 (0)