Skip to content
This repository was archived by the owner on Oct 7, 2024. It is now read-only.

Commit f0baaac

Browse files
mikespositomcmire
andauthored
Add types for store and fix type discrepancies (#247)
* fix: add types for persistent and memory store * fix: lint * refactor: remove return from void function * refactor: edit keyringBuilders type * fix: make keyringBuilders arg optional * rollback setLocked change * Update src/KeyringController.test.ts Co-authored-by: Elliot Winkler <[email protected]> * refactor: rollback unlockKeyrings --------- Co-authored-by: Elliot Winkler <[email protected]>
1 parent ec8b5da commit f0baaac

File tree

5 files changed

+72
-80
lines changed

5 files changed

+72
-80
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444
"@metamask/eth-hd-keyring": "^6.0.0",
4545
"@metamask/eth-sig-util": "^6.0.0",
4646
"@metamask/eth-simple-keyring": "^5.0.0",
47-
"@metamask/utils": "^6.2.0",
48-
"obs-store": "^4.0.3"
47+
"@metamask/obs-store": "^8.1.0",
48+
"@metamask/utils": "^6.2.0"
4949
},
5050
"devDependencies": {
5151
"@lavamoat/allow-scripts": "^2.3.1",

src/KeyringController.test.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ describe('KeyringController', () => {
122122
await keyringController.persistAllKeyrings();
123123

124124
const { vault } = keyringController.store.getState();
125+
assert(vault, 'Vault is not set');
125126
const keyrings = await mockEncryptor.decrypt(PASSWORD, vault);
126127
expect(keyrings).toContain(unsupportedKeyring);
127128
expect(keyrings).toHaveLength(2);
@@ -136,7 +137,9 @@ describe('KeyringController', () => {
136137
const vault = JSON.stringify({ salt: vaultEncryptionSalt });
137138
keyringController.store.updateState({ vault });
138139

139-
expect(keyringController.memStore.getState().encryptionKey).toBeNull();
140+
expect(
141+
keyringController.memStore.getState().encryptionKey,
142+
).toBeUndefined();
140143
expect(
141144
keyringController.memStore.getState().encryptionSalt,
142145
).toBeUndefined();
@@ -201,7 +204,7 @@ describe('KeyringController', () => {
201204

202205
describe('createNewVaultAndKeychain', () => {
203206
it('should create a new vault', async () => {
204-
keyringController.store.updateState({ vault: null });
207+
keyringController.store.putState({});
205208
assert(!keyringController.store.getState().vault, 'no previous vault');
206209

207210
const newVault = await keyringController.createNewVaultAndKeychain(
@@ -213,7 +216,7 @@ describe('KeyringController', () => {
213216
});
214217

215218
it('should unlock the vault', async () => {
216-
keyringController.store.updateState({ vault: null });
219+
keyringController.store.putState({});
217220
assert(!keyringController.store.getState().vault, 'no previous vault');
218221

219222
await keyringController.createNewVaultAndKeychain(PASSWORD);
@@ -222,7 +225,7 @@ describe('KeyringController', () => {
222225
});
223226

224227
it('should encrypt keyrings with the correct password each time they are persisted', async () => {
225-
keyringController.store.updateState({ vault: null });
228+
keyringController.store.putState({});
226229
assert(!keyringController.store.getState().vault, 'no previous vault');
227230

228231
await keyringController.createNewVaultAndKeychain(PASSWORD);
@@ -254,7 +257,7 @@ describe('KeyringController', () => {
254257
await keyringController.createNewVaultAndKeychain(PASSWORD);
255258
const finalMemStore = keyringController.memStore.getState();
256259

257-
expect(initialMemStore.encryptionKey).toBeNull();
260+
expect(initialMemStore.encryptionKey).toBeUndefined();
258261
expect(initialMemStore.encryptionSalt).toBeUndefined();
259262

260263
expect(finalMemStore.encryptionKey).toBe(MOCK_HARDCODED_KEY);
@@ -347,7 +350,7 @@ describe('KeyringController', () => {
347350
);
348351
const finalMemStore = keyringController.memStore.getState();
349352

350-
expect(initialMemStore.encryptionKey).toBeNull();
353+
expect(initialMemStore.encryptionKey).toBeUndefined();
351354
expect(initialMemStore.encryptionSalt).toBeUndefined();
352355

353356
expect(finalMemStore.encryptionKey).toBe(MOCK_HARDCODED_KEY);
@@ -888,9 +891,13 @@ describe('KeyringController', () => {
888891

889892
await keyringController.setLocked();
890893

891-
expect(keyringController.memStore.getState().encryptionSalt).toBeNull();
894+
expect(
895+
keyringController.memStore.getState().encryptionSalt,
896+
).toBeUndefined();
892897
expect(keyringController.password).toBeUndefined();
893-
expect(keyringController.memStore.getState().encryptionKey).toBeNull();
898+
expect(
899+
keyringController.memStore.getState().encryptionKey,
900+
).toBeUndefined();
894901
});
895902
});
896903

src/KeyringController.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as encryptorUtils from '@metamask/browser-passworder';
33
import HDKeyring from '@metamask/eth-hd-keyring';
44
import { normalize as normalizeToHex } from '@metamask/eth-sig-util';
55
import SimpleKeyring from '@metamask/eth-simple-keyring';
6+
import { ObservableStore } from '@metamask/obs-store';
67
import { remove0x, isValidHexAddress } from '@metamask/utils';
78
import type {
89
Hex,
@@ -14,13 +15,13 @@ import type {
1415
// TODO: Stop using `events`, and remove the notice about this from the README
1516
// eslint-disable-next-line import/no-nodejs-modules
1617
import { EventEmitter } from 'events';
17-
import ObservableStore from 'obs-store';
1818

1919
import { KeyringType, KeyringControllerError } from './constants';
2020
import {
2121
SerializedKeyring,
2222
KeyringControllerArgs,
2323
KeyringControllerState,
24+
KeyringControllerPersistentState,
2425
} from './types';
2526

2627
const defaultKeyringBuilders = [
@@ -31,9 +32,9 @@ const defaultKeyringBuilders = [
3132
class KeyringController extends EventEmitter {
3233
keyringBuilders: { (): Keyring<Json>; type: string }[];
3334

34-
public store: typeof ObservableStore;
35+
public store: ObservableStore<KeyringControllerPersistentState>;
3536

36-
public memStore: typeof ObservableStore;
37+
public memStore: ObservableStore<KeyringControllerState>;
3738

3839
public encryptor: any;
3940

@@ -62,7 +63,6 @@ class KeyringController extends EventEmitter {
6263
(keyringBuilder) => keyringBuilder.type,
6364
),
6465
keyrings: [],
65-
encryptionKey: null,
6666
});
6767

6868
this.encryptor = encryptor;
@@ -167,10 +167,9 @@ class KeyringController extends EventEmitter {
167167
delete this.password;
168168

169169
// set locked
170-
this.memStore.updateState({
170+
this.memStore.putState({
171171
isUnlocked: false,
172-
encryptionKey: null,
173-
encryptionSalt: null,
172+
keyrings: [],
174173
});
175174

176175
// remove keyrings
@@ -362,9 +361,9 @@ class KeyringController extends EventEmitter {
362361
*
363362
* Updates the in-memory keyrings, without persisting.
364363
*/
365-
async updateMemStoreKeyrings(): Promise<Json> {
364+
async updateMemStoreKeyrings(): Promise<void> {
366365
const keyrings = await Promise.all(this.keyrings.map(displayForKeyring));
367-
return this.memStore.updateState({ keyrings });
366+
this.memStore.updateState({ keyrings });
368367
}
369368

370369
/**
@@ -900,7 +899,10 @@ class KeyringController extends EventEmitter {
900899
// is not yet inside the memStore
901900
this.memStore.updateState({
902901
encryptionKey,
903-
encryptionSalt,
902+
// we can safely assume that encryptionSalt is defined here
903+
// because we compare it with the salt from the vault
904+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
905+
encryptionSalt: encryptionSalt!,
904906
});
905907
}
906908
} else {

src/types.ts

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
import type { Json, Keyring } from '@metamask/utils';
2-
import ObservableStore from 'obs-store';
32

43
export type KeyringControllerArgs = {
5-
keyringBuilders:
6-
| { (): Keyring<Json>; type: string }
7-
| ConcatArray<{ (): Keyring<Json>; type: string }>;
8-
4+
keyringBuilders?: { (): Keyring<Json>; type: string }[];
95
cacheEncryptionKey: boolean;
10-
initState?: KeyringControllerState;
6+
initState?: KeyringControllerPersistentState;
117
encryptor?: any;
128
};
139

14-
export type KeyringControllerState = {
15-
keyringBuilders?: { (): Keyring<Json>; type: string }[];
16-
17-
store?: typeof ObservableStore;
18-
19-
memStore?: typeof ObservableStore;
20-
21-
keyrings?: Keyring<Json>[];
10+
export type KeyringObject = {
11+
type: string;
12+
accounts: string[];
13+
};
2214

23-
isUnlocked?: boolean;
15+
export type KeyringControllerPersistentState = {
16+
vault?: string;
17+
};
2418

19+
export type KeyringControllerState = {
20+
keyrings: KeyringObject[];
21+
isUnlocked: boolean;
2522
encryptionKey?: string;
26-
2723
encryptionSalt?: string;
28-
29-
password?: string;
3024
};
3125

3226
export type SerializedKeyring = {

yarn.lock

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,7 @@ __metadata:
10401040
"@metamask/eth-hd-keyring": ^6.0.0
10411041
"@metamask/eth-sig-util": ^6.0.0
10421042
"@metamask/eth-simple-keyring": ^5.0.0
1043+
"@metamask/obs-store": ^8.1.0
10431044
"@metamask/utils": ^6.2.0
10441045
"@types/jest": ^29.4.0
10451046
"@types/sinon": ^10.0.13
@@ -1056,7 +1057,6 @@ __metadata:
10561057
ethereumjs-wallet: ^1.0.2
10571058
jest: ^29.0.0
10581059
jest-it-up: ^2.0.2
1059-
obs-store: ^4.0.3
10601060
prettier: ^2.8.1
10611061
prettier-plugin-packagejson: ^2.3.0
10621062
rimraf: ^3.0.2
@@ -1108,6 +1108,23 @@ __metadata:
11081108
languageName: node
11091109
linkType: hard
11101110

1111+
"@metamask/obs-store@npm:^8.1.0":
1112+
version: 8.1.0
1113+
resolution: "@metamask/obs-store@npm:8.1.0"
1114+
dependencies:
1115+
"@metamask/safe-event-emitter": ^2.0.0
1116+
through2: ^2.0.3
1117+
checksum: 92356067fa3517526d656f2f0bdfbc4d39f65e27fb30d84240cfc9c1aa9cd5d743498952df18ed8efbb8887b6cc1bc1fab37bde3fb0fc059539e0dfcc67ff86f
1118+
languageName: node
1119+
linkType: hard
1120+
1121+
"@metamask/safe-event-emitter@npm:^2.0.0":
1122+
version: 2.0.0
1123+
resolution: "@metamask/safe-event-emitter@npm:2.0.0"
1124+
checksum: 8b717ac5d53df0027c05509f03d0534700b5898dd1c3a53fb2dc4c0499ca5971b14aae67f522d09eb9f509e77f50afa95fdb3eda1afbff8b071c18a3d2905e93
1125+
languageName: node
1126+
linkType: hard
1127+
11111128
"@metamask/scure-bip39@npm:^2.0.3":
11121129
version: 2.1.0
11131130
resolution: "@metamask/scure-bip39@npm:2.1.0"
@@ -3453,13 +3470,6 @@ __metadata:
34533470
languageName: node
34543471
linkType: hard
34553472

3456-
"events@npm:^3.0.0":
3457-
version: 3.3.0
3458-
resolution: "events@npm:3.3.0"
3459-
checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780
3460-
languageName: node
3461-
linkType: hard
3462-
34633473
"evp_bytestokey@npm:^1.0.3":
34643474
version: 1.0.3
34653475
resolution: "evp_bytestokey@npm:1.0.3"
@@ -5689,18 +5699,6 @@ __metadata:
56895699
languageName: node
56905700
linkType: hard
56915701

5692-
"obs-store@npm:^4.0.3":
5693-
version: 4.0.3
5694-
resolution: "obs-store@npm:4.0.3"
5695-
dependencies:
5696-
readable-stream: ^2.2.2
5697-
safe-event-emitter: ^1.0.1
5698-
through2: ^2.0.3
5699-
xtend: ^4.0.1
5700-
checksum: a3c05dad7483489f2c083059256f24838b106e10012dd296c7d3e8066869bbc7313dc90775354b519cbeb7aa4c230b0f66cc87ef1414189bad6d03adb0b00b75
5701-
languageName: node
5702-
linkType: hard
5703-
57045702
"once@npm:^1.3.0":
57055703
version: 1.4.0
57065704
resolution: "once@npm:1.4.0"
@@ -6090,7 +6088,18 @@ __metadata:
60906088
languageName: node
60916089
linkType: hard
60926090

6093-
"readable-stream@npm:^2.2.2, readable-stream@npm:~2.3.6":
6091+
"readable-stream@npm:^3.6.0":
6092+
version: 3.6.2
6093+
resolution: "readable-stream@npm:3.6.2"
6094+
dependencies:
6095+
inherits: ^2.0.3
6096+
string_decoder: ^1.1.1
6097+
util-deprecate: ^1.0.1
6098+
checksum: bdcbe6c22e846b6af075e32cf8f4751c2576238c5043169a1c221c92ee2878458a816a4ea33f4c67623c0b6827c8a400409bfb3cf0bf3381392d0b1dfb52ac8d
6099+
languageName: node
6100+
linkType: hard
6101+
6102+
"readable-stream@npm:~2.3.6":
60946103
version: 2.3.8
60956104
resolution: "readable-stream@npm:2.3.8"
60966105
dependencies:
@@ -6105,17 +6114,6 @@ __metadata:
61056114
languageName: node
61066115
linkType: hard
61076116

6108-
"readable-stream@npm:^3.6.0":
6109-
version: 3.6.2
6110-
resolution: "readable-stream@npm:3.6.2"
6111-
dependencies:
6112-
inherits: ^2.0.3
6113-
string_decoder: ^1.1.1
6114-
util-deprecate: ^1.0.1
6115-
checksum: bdcbe6c22e846b6af075e32cf8f4751c2576238c5043169a1c221c92ee2878458a816a4ea33f4c67623c0b6827c8a400409bfb3cf0bf3381392d0b1dfb52ac8d
6116-
languageName: node
6117-
linkType: hard
6118-
61196117
"readdirp@npm:^3.5.0, readdirp@npm:~3.6.0":
61206118
version: 3.6.0
61216119
resolution: "readdirp@npm:3.6.0"
@@ -6298,15 +6296,6 @@ __metadata:
62986296
languageName: node
62996297
linkType: hard
63006298

6301-
"safe-event-emitter@npm:^1.0.1":
6302-
version: 1.0.1
6303-
resolution: "safe-event-emitter@npm:1.0.1"
6304-
dependencies:
6305-
events: ^3.0.0
6306-
checksum: 2a15094bd28b0966571693f219b5a846949ae24f7ba87c6024f0ed552bef63ebe72970a784b85b77b1f03f1c95e78fabe19306d44538dbc4a3a685bed31c18c4
6307-
languageName: node
6308-
linkType: hard
6309-
63106299
"safe-regex-test@npm:^1.0.0":
63116300
version: 1.0.0
63126301
resolution: "safe-regex-test@npm:1.0.0"
@@ -7306,7 +7295,7 @@ __metadata:
73067295
languageName: node
73077296
linkType: hard
73087297

7309-
"xtend@npm:^4.0.1, xtend@npm:~4.0.1":
7298+
"xtend@npm:~4.0.1":
73107299
version: 4.0.2
73117300
resolution: "xtend@npm:4.0.2"
73127301
checksum: ac5dfa738b21f6e7f0dd6e65e1b3155036d68104e67e5d5d1bde74892e327d7e5636a076f625599dc394330a731861e87343ff184b0047fef1360a7ec0a5a36a

0 commit comments

Comments
 (0)