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

Commit 1941d3c

Browse files
authored
Restore compatibility with QR Keyring (#252)
The `KeyringController` method `addNewKeyring` was changed in v11 to initialize the keyring options to an empty object. These options are passed to the `deserialize` method of the keyring. This broke compatibility with the QR keyring because its `deserialize` method does not expect to be passed an empty object. The `KeyringController` has been updated to no longer initialize the `addNewKeyring` options to an empty object. It should now work the same as it did prior to v11. The one functional difference is that it now throws an error when `addNewKeyring` is used to add a simple keyring without supplying any private keys, however that path would have already thrown an error.
1 parent 647eb9d commit 1941d3c

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

jest.config.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ module.exports = {
4141
// An object that configures minimum threshold enforcement for coverage results
4242
coverageThreshold: {
4343
global: {
44-
branches: 72.09,
44+
branches: 72.41,
4545
functions: 92.85,
46-
lines: 90.81,
47-
statements: 91.02,
46+
lines: 90.87,
47+
statements: 91.08,
4848
},
4949
},
5050
preset: 'ts-jest',

src/KeyringController.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,15 @@ describe('KeyringController', () => {
473473
expect(allAccounts).toStrictEqual(expectedAllAccounts);
474474
});
475475

476+
it('should throw an error when attempting to add simple key pair without private keys', async () => {
477+
const keyringController = await initializeKeyringController({
478+
password: PASSWORD,
479+
});
480+
await expect(async () =>
481+
keyringController.addNewKeyring(KeyringType.Simple),
482+
).rejects.toThrow('Private keys missing');
483+
});
484+
476485
it('should add HD Key Tree without mnemonic passed as an argument', async () => {
477486
const keyringController = await initializeKeyringController({
478487
password: PASSWORD,
@@ -504,6 +513,26 @@ describe('KeyringController', () => {
504513
expect(allAccounts).toHaveLength(3);
505514
});
506515

516+
it('should add keyring that expects undefined serialized state', async () => {
517+
let deserializedSpy = sinon.spy();
518+
const mockKeyringBuilder = () => {
519+
const keyring = new KeyringMockWithInit();
520+
deserializedSpy = sinon.spy(keyring, 'deserialize');
521+
return keyring;
522+
};
523+
mockKeyringBuilder.type = 'Mock Keyring';
524+
const keyringController = await initializeKeyringController({
525+
constructorOptions: {
526+
keyringBuilders: [mockKeyringBuilder],
527+
},
528+
password: PASSWORD,
529+
});
530+
await keyringController.addNewKeyring('Mock Keyring');
531+
532+
expect(deserializedSpy.callCount).toBe(1);
533+
expect(deserializedSpy.calledWith(undefined)).toBe(true);
534+
});
535+
507536
it('should call init method if available', async () => {
508537
const keyringController = await initializeKeyringController({
509538
password: PASSWORD,

src/KeyringController.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ 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';
66
import { ObservableStore } from '@metamask/obs-store';
7-
import { remove0x, isValidHexAddress } from '@metamask/utils';
7+
import { remove0x, isValidHexAddress, isObject } from '@metamask/utils';
88
import type {
99
Hex,
1010
Json,
@@ -586,11 +586,14 @@ class KeyringController extends EventEmitter {
586586
*/
587587
async addNewKeyring(
588588
type: string,
589-
opts: Record<string, unknown> = {},
589+
opts?: Record<string, unknown>,
590590
): Promise<Keyring<Json>> {
591591
let keyring: Keyring<Json>;
592592
switch (type) {
593593
case KeyringType.Simple:
594+
if (!isObject(opts)) {
595+
throw new Error('Private keys missing');
596+
}
594597
keyring = await this.#newKeyring(type, opts.privateKeys);
595598
break;
596599
default:
@@ -602,7 +605,7 @@ class KeyringController extends EventEmitter {
602605
throw new Error(KeyringControllerError.NoKeyring);
603606
}
604607

605-
if (!opts.mnemonic && type === KeyringType.HD) {
608+
if (type === KeyringType.HD && (!isObject(opts) || !opts.mnemonic)) {
606609
if (!keyring.generateRandomMnemonic) {
607610
throw new Error(
608611
KeyringControllerError.UnsupportedGenerateRandomMnemonic,

0 commit comments

Comments
 (0)