From d6a6b31fcb13f1965624434fd3adb242642b831a Mon Sep 17 00:00:00 2001 From: Daniel Rocha Date: Wed, 20 Sep 2023 15:30:25 +0200 Subject: [PATCH] fix: ignore event if account was already removed (#101) * fix: ignore event if account was already removed * test: add missing unit test (coverage) --- src/SnapKeyring.test.ts | 10 ++++------ src/SnapKeyring.ts | 17 ++++++++++++----- src/util.test.ts | 8 +++++++- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/SnapKeyring.test.ts b/src/SnapKeyring.test.ts index a5a2b8e3..feab6ccd 100644 --- a/src/SnapKeyring.test.ts +++ b/src/SnapKeyring.test.ts @@ -69,19 +69,17 @@ describe('SnapKeyring', () => { ]); }); - it('throws when removing an account that does not exist', async () => { + it('returns null when removing an account that does not exist', async () => { mockCallbacks.removeAccount.mockImplementation(async (address) => { await keyring.removeAccount(address); }); - await expect( - keyring.handleKeyringSnapMessage(snapId, { + expect( + await keyring.handleKeyringSnapMessage(snapId, { method: KeyringEvent.AccountDeleted, params: { id: 'bcda5b5f-098f-4706-919b-ee919402f0dd' }, }), - ).rejects.toThrow( - "Account 'bcda5b5f-098f-4706-919b-ee919402f0dd' not found", - ); + ).toBeNull(); }); it('fails when the method is not supported', async () => { diff --git a/src/SnapKeyring.ts b/src/SnapKeyring.ts index 324f385b..baa8ec6c 100644 --- a/src/SnapKeyring.ts +++ b/src/SnapKeyring.ts @@ -21,7 +21,7 @@ import { CaseInsensitiveMap } from './CaseInsensitiveMap'; import { DeferredPromise } from './DeferredPromise'; import type { SnapMessage } from './types'; import { SnapMessageStruct } from './types'; -import { strictMask, throwError, toJson, unique } from './util'; +import { strictMask, toJson, unique } from './util'; export const SNAP_KEYRING_TYPE = 'Snap Keyring'; @@ -89,10 +89,17 @@ export class SnapKeyring extends EventEmitter { case KeyringEvent.AccountDeleted: { const { id } = params as any; - const account = - this.#getAccountById(id) ?? - throwError(`Account '${id as string}' not found`); - await this.#callbacks.removeAccount(account.address); + const account = this.#getAccountById(id); + + // We can ignore the case where the account was already removed from + // the keyring. + // + // This happens when the keyring calls the snap to delete an account, + // and the snap responds with an AccountDeleted event. + if (account !== undefined) { + await this.#callbacks.removeAccount(account.address); + } + return null; } diff --git a/src/util.test.ts b/src/util.test.ts index d60c7ccd..8c834458 100644 --- a/src/util.test.ts +++ b/src/util.test.ts @@ -1,4 +1,4 @@ -import { ensureDefined, toJson, unique } from './util'; +import { ensureDefined, throwError, toJson, unique } from './util'; describe('unique', () => { it('returns an empty array when given an empty array', () => { @@ -52,3 +52,9 @@ describe('ensureDefined', () => { expect(() => ensureDefined(undefined)).toThrow('Argument is undefined'); }); }); + +describe('throwError', () => { + it('throws an error with the given message', () => { + expect(() => throwError('hello')).toThrow('hello'); + }); +});