Skip to content

Commit

Permalink
feat: Keep PreferencesController in sync with keyring state (#3799)
Browse files Browse the repository at this point in the history
## Explanation

The `PreferencesController` now listens for `KeyringController` state
changes, and updates its own state in response to account removals or
additions. New accounts are added to the `identities` state and given
default labels. Removed accounts are removed from the `identities`
state, and the `selectedAddress` is updated if it was removed.

The dependency between these two packages has been flipped; the
`@metamask/preferences-controller` package now depends upon
`@metamask/keyring-controller` rather than the other away around, so
that the `KeyringController` state type and state change event can be
accessed. The dependency the other way was just to get the types for the
four `PreferencesController` methods that are passed into the
`KeyringController` constructor. These types were easily inlined, and
these methods will soon be removed anyway.

A `getDefaultKeyringState` export was added to the
`@metamask/keyring-controller` package to make it easier to write the
necessary `PreferencesController` tests.

## References

Closes #3794

## Changelog

### `@metamask/keyring-controller`

#### Added
- Add `getDefaultKeyringState` function

#### Removed
- Remove `peerDependency` and `devDependency` upon
`@metamask/preferences-controller`
- This dependency was just used to access the types of four methods.
Those types are now inlined instead.

### `@metamask/preferences-controller`

#### Changed
- **BREAKING:** Keep `PreferencesController` state synchronized with
`KeyringController` state
- The `KeyringController:stateChange` event is now required by the
`PreferencesController` messenger, which is a breaking change.
- The package `@metamask/keyring-controller` has been added as a
`peerDependency` and as a `devDependency`, which is a breaking change.
- Previously the state was synchronized manually by calling
`syncIdentities` or `updateIdentities`. Calling these methods is no
longer required.

## Checklist

- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
  • Loading branch information
Gudahtt authored Jan 23, 2024
1 parent 007648b commit 7b139dc
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 66 deletions.
4 changes: 0 additions & 4 deletions packages/keyring-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
"@metamask/eth-keyring-controller": "^17.0.1",
"@metamask/keyring-api": "^3.0.0",
"@metamask/message-manager": "^7.3.7",
"@metamask/preferences-controller": "^6.0.0",
"@metamask/utils": "^8.3.0",
"async-mutex": "^0.2.6",
"ethereumjs-util": "^7.0.10",
Expand All @@ -62,9 +61,6 @@
"typescript": "~4.8.4",
"uuid": "^8.3.2"
},
"peerDependencies": {
"@metamask/preferences-controller": "^6.0.0"
},
"engines": {
"node": ">=16.0.0"
},
Expand Down
27 changes: 14 additions & 13 deletions packages/keyring-controller/src/KeyringController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import type {
PersonalMessageParams,
TypedMessageParams,
} from '@metamask/message-manager';
import type { PreferencesController } from '@metamask/preferences-controller';
import type { Eip1024EncryptedData, Hex, Json } from '@metamask/utils';
import { assertIsStrictHexString, hasProperty } from '@metamask/utils';
import { Mutex } from 'async-mutex';
Expand Down Expand Up @@ -200,10 +199,10 @@ export type KeyringControllerMessenger = RestrictedControllerMessenger<
>;

export type KeyringControllerOptions = {
syncIdentities: PreferencesController['syncIdentities'];
updateIdentities: PreferencesController['updateIdentities'];
setSelectedAddress: PreferencesController['setSelectedAddress'];
setAccountLabel?: PreferencesController['setAccountLabel'];
syncIdentities: (addresses: string[]) => string;
updateIdentities: (addresses: string[]) => void;
setSelectedAddress: (selectedAddress: string) => void;
setAccountLabel?: (address: string, label: string) => void;
keyringBuilders?: { (): EthKeyring<Json>; type: string }[];
messenger: KeyringControllerMessenger;
state?: { vault?: string };
Expand Down Expand Up @@ -249,9 +248,11 @@ export enum SignTypedDataVersion {
V4 = 'V4',
}

const defaultState: KeyringControllerState = {
isUnlocked: false,
keyrings: [],
export const getDefaultKeyringState = (): KeyringControllerState => {
return {
isUnlocked: false,
keyrings: [],
};
};

/**
Expand Down Expand Up @@ -289,13 +290,13 @@ export class KeyringController extends BaseController<
> {
private readonly mutex = new Mutex();

private readonly syncIdentities: PreferencesController['syncIdentities'];
private readonly syncIdentities: (addresses: string[]) => string;

private readonly updateIdentities: PreferencesController['updateIdentities'];
private readonly updateIdentities: (addresses: string[]) => void;

private readonly setSelectedAddress: PreferencesController['setSelectedAddress'];
private readonly setSelectedAddress: (selectedAddress: string) => void;

private readonly setAccountLabel?: PreferencesController['setAccountLabel'];
private readonly setAccountLabel?: (address: string, label: string) => void;

#keyring: EthKeyringController;

Expand Down Expand Up @@ -339,7 +340,7 @@ export class KeyringController extends BaseController<
},
messenger,
state: {
...defaultState,
...getDefaultKeyringState(),
...state,
},
});
Expand Down
3 changes: 0 additions & 3 deletions packages/keyring-controller/tsconfig.build.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
},
{
"path": "../message-manager/tsconfig.build.json"
},
{
"path": "../preferences-controller/tsconfig.build.json"
}
],
"include": ["../../types", "./src"]
Expand Down
3 changes: 0 additions & 3 deletions packages/keyring-controller/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
},
{
"path": "../message-manager"
},
{
"path": "../preferences-controller"
}
],
"include": ["../../types", "./src", "./tests"]
Expand Down
5 changes: 5 additions & 0 deletions packages/preferences-controller/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,19 @@
},
"devDependencies": {
"@metamask/auto-changelog": "^3.4.4",
"@metamask/keyring-controller": "^12.1.0",
"@types/jest": "^27.4.1",
"deepmerge": "^4.2.2",
"jest": "^27.5.1",
"lodash": "^4.17.21",
"ts-jest": "^27.1.4",
"typedoc": "^0.24.8",
"typedoc-plugin-missing-exports": "^2.0.0",
"typescript": "~4.8.4"
},
"peerDependencies": {
"@metamask/keyring-controller": "^12.1.0"
},
"engines": {
"node": ">=16.0.0"
},
Expand Down
Loading

0 comments on commit 7b139dc

Please sign in to comment.