From 274a18d4a532a00f54c964ad62bfff3796c7d7ff Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Tue, 8 Oct 2024 11:17:31 +0200 Subject: [PATCH 1/3] Add `isSnapId` utility function --- packages/snaps-utils/coverage.json | 4 +-- packages/snaps-utils/src/snaps.test.ts | 36 +++++++++++++++++++++++--- packages/snaps-utils/src/snaps.ts | 12 +++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/snaps-utils/coverage.json b/packages/snaps-utils/coverage.json index 7e74294584..76e026e3eb 100644 --- a/packages/snaps-utils/coverage.json +++ b/packages/snaps-utils/coverage.json @@ -1,6 +1,6 @@ { "branches": 99.74, - "functions": 98.91, + "functions": 98.92, "lines": 99.45, - "statements": 96.3 + "statements": 96.31 } diff --git a/packages/snaps-utils/src/snaps.test.ts b/packages/snaps-utils/src/snaps.test.ts index 20e642c690..96f995e26e 100644 --- a/packages/snaps-utils/src/snaps.test.ts +++ b/packages/snaps-utils/src/snaps.test.ts @@ -2,6 +2,7 @@ import type { SubjectPermissions, PermissionConstraint, } from '@metamask/permission-controller'; +import { MOCK_SNAP_ID } from '@metamask/snaps-utils/test-utils'; import { is } from '@metamask/superstruct'; import { SnapCaveatType } from './caveats'; @@ -14,9 +15,36 @@ import { assertIsValidSnapId, verifyRequestedSnapPermissions, stripSnapPrefix, + isSnapId, } from './snaps'; import { uri, WALLET_SNAP_PERMISSION_KEY } from './types'; +describe('isSnapId', () => { + it.each(['npm:@metamask/test-snap-bip44', 'local:http://localhost:8000'])( + 'returns `true` for "%s"', + () => { + expect(isSnapId('npm:@metamask/test-snap-bip44')).toBe(true); + }, + ); + + it.each([ + undefined, + {}, + null, + true, + 2, + 'foo:bar', + ' local:http://localhost:8000', + 'local:http://localhost:8000 ', + 'local:http://localhost:8000\n', + 'local:http://localhost:8000\r', + 'local:😎', + 'local:␡', + ])('returns `false` for "%s"', (value) => { + expect(isSnapId(value)).toBe(false); + }); +}); + describe('assertIsValidSnapId', () => { it.each([undefined, {}, null, true, 2])( 'throws for non-strings (#%#)', @@ -239,7 +267,7 @@ describe('isSnapPermitted', () => { { type: 'snapIds', value: { - foo: {}, + [MOCK_SNAP_ID]: {}, }, }, ], @@ -273,9 +301,9 @@ describe('isSnapPermitted', () => { }, }; - expect(isSnapPermitted(validPermissions, 'foo')).toBe(true); - expect(isSnapPermitted(invalidPermissions1, 'foo')).toBe(false); - expect(isSnapPermitted(invalidPermissions2, 'foo')).toBe(false); + expect(isSnapPermitted(validPermissions, MOCK_SNAP_ID)).toBe(true); + expect(isSnapPermitted(invalidPermissions1, MOCK_SNAP_ID)).toBe(false); + expect(isSnapPermitted(invalidPermissions2, MOCK_SNAP_ID)).toBe(false); }); describe('verifyRequestedSnapPermissions', () => { diff --git a/packages/snaps-utils/src/snaps.ts b/packages/snaps-utils/src/snaps.ts index f3fe08967f..6ccd71fb97 100644 --- a/packages/snaps-utils/src/snaps.ts +++ b/packages/snaps-utils/src/snaps.ts @@ -7,6 +7,7 @@ import type { BlockReason } from '@metamask/snaps-registry'; import type { SnapId, Snap as TruncatedSnap } from '@metamask/snaps-sdk'; import type { Struct } from '@metamask/superstruct'; import { + is, empty, enums, intersection, @@ -311,6 +312,17 @@ export function stripSnapPrefix(snapId: string): string { return snapId.replace(getSnapPrefix(snapId), ''); } +/** + * Check if the given value is a valid snap ID. This function is a type guard, + * and will narrow the type of the value to `SnapId` if it returns `true`. + * + * @param value - The value to check. + * @returns `true` if the value is a valid snap ID, and `false` otherwise. + */ +export function isSnapId(value: unknown): value is SnapId { + return is(value, SnapIdStruct); +} + /** * Assert that the given value is a valid snap ID. * From ba103463b5ea88d5a3cdb1aa318115bd571a6297 Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Tue, 8 Oct 2024 11:20:57 +0200 Subject: [PATCH 2/3] Fix test --- packages/snaps-utils/src/snaps.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/snaps-utils/src/snaps.test.ts b/packages/snaps-utils/src/snaps.test.ts index 96f995e26e..72ce640a97 100644 --- a/packages/snaps-utils/src/snaps.test.ts +++ b/packages/snaps-utils/src/snaps.test.ts @@ -22,8 +22,8 @@ import { uri, WALLET_SNAP_PERMISSION_KEY } from './types'; describe('isSnapId', () => { it.each(['npm:@metamask/test-snap-bip44', 'local:http://localhost:8000'])( 'returns `true` for "%s"', - () => { - expect(isSnapId('npm:@metamask/test-snap-bip44')).toBe(true); + (value) => { + expect(isSnapId(value)).toBe(true); }, ); From 888d91b3c56f7e116b5e9cd359f849363545d1ab Mon Sep 17 00:00:00 2001 From: Maarten Zuidhoorn Date: Tue, 8 Oct 2024 11:26:16 +0200 Subject: [PATCH 3/3] Fix import --- packages/snaps-utils/src/snaps.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/snaps-utils/src/snaps.test.ts b/packages/snaps-utils/src/snaps.test.ts index 72ce640a97..17ceec4d31 100644 --- a/packages/snaps-utils/src/snaps.test.ts +++ b/packages/snaps-utils/src/snaps.test.ts @@ -2,7 +2,6 @@ import type { SubjectPermissions, PermissionConstraint, } from '@metamask/permission-controller'; -import { MOCK_SNAP_ID } from '@metamask/snaps-utils/test-utils'; import { is } from '@metamask/superstruct'; import { SnapCaveatType } from './caveats'; @@ -17,6 +16,7 @@ import { stripSnapPrefix, isSnapId, } from './snaps'; +import { MOCK_SNAP_ID } from './test-utils'; import { uri, WALLET_SNAP_PERMISSION_KEY } from './types'; describe('isSnapId', () => {