Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add main network sync controller integration #4701

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -1417,17 +1417,9 @@ function mockUserStorageMessenger(options?: {
return mockAccountsUpdateAccountMetadata(args.slice(1));
}

if (actionType === 'AccountsController:getAccountByAddress') {
return mockAccountsGetAccountByAddress();
}

const exhaustedMessengerMocks = (action: never) => {
throw new Error(
`MOCK_FAIL - unsupported messenger call: ${action as string}`,
);
};

return exhaustedMessengerMocks(actionType);
throw new Error(
`MOCK_FAIL - unsupported messenger call: ${actionType as string}`,
);
Prithpal-Sooriya marked this conversation as resolved.
Show resolved Hide resolved
});

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ import type {
KeyringControllerUnlockEvent,
KeyringControllerAddNewAccountAction,
} from '@metamask/keyring-controller';
import type { NetworkConfiguration } from '@metamask/network-controller';
import type {
NetworkConfiguration,
NetworkController,
NetworkControllerGetStateAction,
} from '@metamask/network-controller';
import type { HandleSnapRequest } from '@metamask/snaps-controllers';

import { createSnapSignMessageRequest } from '../authentication/auth-snap-requests';
Expand All @@ -35,7 +39,10 @@ import {
mapInternalAccountToUserStorageAccount,
} from './accounts/user-storage';
import { createSHA256Hash } from './encryption';
import { startNetworkSyncing } from './network-syncing/controller-integration';
import {
performMainNetworkSync,
startNetworkSyncing,
} from './network-syncing/controller-integration';
import type {
UserStoragePathWithFeatureAndKey,
UserStoragePathWithFeatureOnly,
Expand All @@ -46,26 +53,32 @@ import {
upsertUserStorage,
} from './services';

// TODO: add external NetworkController event
// Need to listen for when a network gets added
// TODO - replace shimmed interface with actual interfaces once merged
// Waiting on #4698
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For visibility: #4698

type NetworkControllerNetworkAddedEvent = {
type: 'NetworkController:networkAdded';
payload: [networkConfiguration: NetworkConfiguration];
};

// TODO: add external NetworkController event
// Need to listen for when a network is updated, or the default rpc/block explorer changes
type NetworkControllerNetworkChangedEvent = {
type: 'NetworkController:networkChanged';
type NetworkControllerNetworkUpdatedEvent = {
type: 'NetworkController:networkUpdated';
payload: [networkConfiguration: NetworkConfiguration];
};

// TODO: add external NetworkController event
// Need to listen for when a network gets deleted
type NetworkControllerNetworkDeletedEvent = {
type: 'NetworkController:networkDeleted';
type NetworkControllerNetworkRemovedEvent = {
type: 'NetworkController:networkRemoved';
payload: [networkConfiguration: NetworkConfiguration];
};
type NetworkControllerAddNetworkAction = {
type: 'NetworkController:addNetwork';
handler: NetworkController['addNetwork'];
};
type NetworkControllerUpdateNetworkAction = {
type: 'NetworkController:updateNetwork';
handler: NetworkController['updateNetwork'];
};
type NetworkControllerRemoveNetworkAction = {
type: 'NetworkController:removeNetwork';
handler: NetworkController['removeNetwork'];
};

// TODO: fix external dependencies
export declare type NotificationServicesControllerDisableNotificationServices =
Expand Down Expand Up @@ -173,10 +186,15 @@ export type AllowedActions =
// Metamask Notifications
| NotificationServicesControllerDisableNotificationServices
| NotificationServicesControllerSelectIsNotificationServicesEnabled
// Account syncing
// Account Syncing
| AccountsControllerListAccountsAction
| AccountsControllerUpdateAccountMetadataAction
| KeyringControllerAddNewAccountAction;
| KeyringControllerAddNewAccountAction
// Network Syncing
| NetworkControllerGetStateAction
| NetworkControllerAddNetworkAction
| NetworkControllerUpdateNetworkAction
| NetworkControllerRemoveNetworkAction;

// Messenger events
export type UserStorageControllerStateChangeEvent = ControllerStateChangeEvent<
Expand Down Expand Up @@ -207,8 +225,8 @@ export type AllowedEvents =
| AccountsControllerAccountRenamedEvent
// Network Syncing Events
| NetworkControllerNetworkAddedEvent
| NetworkControllerNetworkChangedEvent
| NetworkControllerNetworkDeletedEvent;
| NetworkControllerNetworkUpdatedEvent
| NetworkControllerNetworkRemovedEvent;

// Messenger
export type UserStorageControllerMessenger = RestrictedControllerMessenger<
Expand All @@ -232,6 +250,13 @@ export default class UserStorageController extends BaseController<
UserStorageControllerState,
UserStorageControllerMessenger
> {
// This is replaced with the actual value in the constructor
// We will remove this once the feature will be released
#env = {
isAccountSyncingEnabled: false,
isNetworkSyncingEnabled: false,
};

#auth = {
getBearerToken: async () => {
return await this.messagingSystem.call(
Expand Down Expand Up @@ -260,17 +285,12 @@ export default class UserStorageController extends BaseController<
};

#accounts = {
// This is replaced with the actual value in the constructor
// We will remove this once the feature will be released
isAccountSyncingEnabled: false,
isAccountSyncingInProgress: false,
canSync: () => {
try {
this.#assertProfileSyncingEnabled();

return (
this.#accounts.isAccountSyncingEnabled && this.#auth.isAuthEnabled()
);
return this.#env.isAccountSyncingEnabled && this.#auth.isAuthEnabled();
} catch {
return false;
}
Expand Down Expand Up @@ -406,9 +426,8 @@ export default class UserStorageController extends BaseController<
state: { ...defaultState, ...state },
});

this.#accounts.isAccountSyncingEnabled = Boolean(
env?.isAccountSyncingEnabled,
);
this.#env.isAccountSyncingEnabled = Boolean(env?.isAccountSyncingEnabled);
this.#env.isNetworkSyncingEnabled = Boolean(env?.isNetworkSyncingEnabled);

this.getMetaMetricsState = getMetaMetricsState;
this.#keyringController.setupLockedStateSubscriptions();
Expand All @@ -417,18 +436,10 @@ export default class UserStorageController extends BaseController<
this.#accounts.setupAccountSyncingSubscriptions();

// Network Syncing
if (env?.isNetworkSyncingEnabled) {
if (this.#env.isNetworkSyncingEnabled) {
startNetworkSyncing({
messenger,
getStorageConfig: async () => {
const { storageKey, bearerToken } =
await this.#getStorageKeyAndBearerToken();
return {
storageKey,
bearerToken,
nativeScryptCrypto: this.#nativeScryptCrypto,
};
},
getStorageConfig: this.#getStorageOptions,
});
}
}
Expand Down Expand Up @@ -479,6 +490,20 @@ export default class UserStorageController extends BaseController<
);
}

async #getStorageOptions() {
if (!this.state.isProfileSyncingEnabled) {
return null;
}

const { storageKey, bearerToken } =
await this.#getStorageKeyAndBearerToken();
return {
storageKey,
bearerToken,
nativeScryptCrypto: this.#nativeScryptCrypto,
};
}

public async enableProfileSyncing(): Promise<void> {
try {
this.#setIsProfileSyncingUpdateLoading(true);
Expand Down Expand Up @@ -868,4 +893,15 @@ export default class UserStorageController extends BaseController<
);
}
}

async syncNetworks() {
if (!this.#env.isNetworkSyncingEnabled) {
return;
}

await performMainNetworkSync({
messenger: this.messagingSystem,
getStorageConfig: this.#getStorageOptions,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,13 @@ type ExternalEvents = NotNamespacedBy<
>;
const getEvents = (): ExternalEvents[] => [
'NetworkController:networkAdded',
'NetworkController:networkChanged',
'NetworkController:networkDeleted',
'NetworkController:networkUpdated',
'NetworkController:networkRemoved',
];

const testMatrix = [
{
event: 'NetworkController:networkAdded' as const,
arrangeSyncFnMock: () =>
jest.spyOn(SyncModule, 'addNetwork').mockResolvedValue(),
},
{
event: 'NetworkController:networkChanged' as const,
arrangeSyncFnMock: () =>
jest.spyOn(SyncModule, 'updateNetwork').mockResolvedValue(),
},
{
event: 'NetworkController:networkDeleted' as const,
event: 'NetworkController:networkRemoved' as const,
arrangeSyncFnMock: () =>
jest.spyOn(SyncModule, 'deleteNetwork').mockResolvedValue(),
},
Expand Down
Loading
Loading