Skip to content

Commit

Permalink
Merge branch 'improved-keyring-metadata-error-handling' into multi-sr…
Browse files Browse the repository at this point in the history
…p-mvp
  • Loading branch information
PatrykLucka committed Feb 13, 2025
2 parents cb58d7d + ae1a759 commit f671b62
Showing 1 changed file with 54 additions and 12 deletions.
66 changes: 54 additions & 12 deletions packages/keyring-controller/src/KeyringController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2298,18 +2298,48 @@ export class KeyringController extends BaseController<
* using the given `opts`. The keyring is built using the keyring builder
* registered for the given `type`.
*
* The internal keyring and keyring metadata arrays are updated with the new
* keyring as well.
*
* @param type - The type of keyring to add.
* @param data - The data to restore a previously serialized keyring.
* @param data - Keyring initialization options.
* @returns The new keyring.
* @throws If the keyring includes duplicated accounts.
*/
async #newKeyring(type: string, data?: unknown): Promise<EthKeyring<Json>> {
this.#assertControllerMutexIsLocked();
const keyring = await this.#createKeyring(type, data);

const newKeyringMetadata: KeyringMetadata = {
id: ulid(),
name: '',
};
this.#keyrings.push(keyring);
this.#keyringsMetadata.push(getDefaultKeyringMetadata());
if (this.#keyrings.length !== this.#keyringsMetadata.length) {
throw new Error('Keyring metadata missing');
}

return keyring;
}

/**
* Instantiate, initialize and return a keyring of the given `type` using the
* given `opts`. The keyring is built using the keyring builder registered
* for the given `type`.
*
* The keyring might be new, or it might be restored from the vault. This
* function should only be called from `#newKeyring` or `#restoreKeyring`,
* for the "new" and "restore" cases respectively.
*
* The internal keyring and keyring metadata arrays are *not* updated, the
* caller is expected to update them.
*
* @param type - The type of keyring to add.
* @param data - Keyring initialization options.
* @returns The new keyring.
* @throws If the keyring includes duplicated accounts.
*/
async #createKeyring(
type: string,
data?: unknown,
): Promise<EthKeyring<Json>> {
this.#assertControllerMutexIsLocked();

const keyringBuilder = this.#getKeyringBuilderForType(type);

Expand Down Expand Up @@ -2349,11 +2379,6 @@ export class KeyringController extends BaseController<
this.#subscribeToQRKeyringEvents(keyring as unknown as QRKeyring);
}

this.#keyrings.push(keyring);
if (this.#keyringsMetadata.length < this.#keyrings.length) {
this.#keyringsMetadata.push(newKeyringMetadata);
}

return keyring;
}

Expand Down Expand Up @@ -2383,7 +2408,15 @@ export class KeyringController extends BaseController<

try {
const { type, data } = serialized;
return await this.#newKeyring(type, data);
const keyring = await this.#createKeyring(type, data);
this.#keyrings.push(keyring);
// If metadata is missing, assume the data is from an installation before
// we had keyring metadata.
if (this.#keyringsMetadata.length < this.#keyrings.length) {
console.log(`Adding missing metadata for '${type}' keyring`);
this.#keyringsMetadata.push(getDefaultKeyringMetadata());
}
return keyring;
} catch (_) {
this.#unsupportedKeyrings.push(serialized);
return undefined;
Expand Down Expand Up @@ -2617,4 +2650,13 @@ async function withLock<Result>(
}
}

/**
* Generate a new keyring metadata object.
*
* @returns Keyring metadata.
*/
function getDefaultKeyringMetadata(): KeyringMetadata {
return { id: ulid(), name: '' };
}

export default KeyringController;

0 comments on commit f671b62

Please sign in to comment.