From 82674806f522cbc5d27d0e35d4e704d9b48d9292 Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 22 Aug 2023 10:40:44 +0200 Subject: [PATCH 1/3] Add new snap metadata The added metadata will be visible to users when they're adding a new snap account. All the newly introduced fields are optional, as they might not be necessary for other types of snaps. --- src/index.ts | 8 ++++++++ src/registry.test.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/index.ts b/src/index.ts index 78a69e02..0a5fd2b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import { union, optional, Infer, + enums, } from 'superstruct'; const VerifiedSnapVersionStruct = object({ @@ -21,6 +22,13 @@ export const VerifiedSnapStruct = object({ id: string(), metadata: object({ name: string(), + type: optional(enums(['account'])), + author: optional(string()), + website: optional(string()), + summary: optional(string()), + description: optional(string()), + reports: optional(array(string())), + tags: optional(array(string())), }), versions: record(VersionStruct, VerifiedSnapVersionStruct), }); diff --git a/src/registry.test.ts b/src/registry.test.ts index 67b811b0..93fba483 100644 --- a/src/registry.test.ts +++ b/src/registry.test.ts @@ -7,4 +7,37 @@ describe('Snaps Registry', () => { it('has valid format', () => { expect(() => assert(registry, SnapsRegistryDatabaseStruct)).not.toThrow(); }); + + it('has a valid account snap', () => { + /* eslint-disable @typescript-eslint/naming-convention */ + const registryDb = { + verifiedSnaps: { + 'npm:example-snap': { + id: 'npm:example-snap', + metadata: { + name: 'Example Snap', + type: 'account', + author: 'Example Author', + website: 'https://metamask.io', + summary: 'Example Snap', + description: 'Longer Example Snap description.', + reports: [ + 'https://metamask.io/example/report-1.pdf', + 'https://metamask.io/example/report-2.pdf', + ], + tags: ['accounts', 'example'], + }, + versions: { + '0.1.0': { + checksum: 'A83r5/ZIcKeKw3An13HBeV4CAofj7jGK5hOStmHY6A0=', + }, + }, + }, + }, + blockedSnaps: [], + }; + /* eslint-enable @typescript-eslint/naming-convention */ + + expect(() => assert(registryDb, SnapsRegistryDatabaseStruct)).not.toThrow(); + }); }); From f36d5bfe9472a4a8a5bced535128edb1f5973a14 Mon Sep 17 00:00:00 2001 From: Daniel Rocha Date: Fri, 1 Sep 2023 09:47:01 +0200 Subject: [PATCH 2/3] Rename `reports` to `audits` Co-authored-by: Frederik Bolding --- src/index.ts | 2 +- src/registry.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 0a5fd2b0..a4169d76 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,7 +27,7 @@ export const VerifiedSnapStruct = object({ website: optional(string()), summary: optional(string()), description: optional(string()), - reports: optional(array(string())), + audits: optional(array(string())), tags: optional(array(string())), }), versions: record(VersionStruct, VerifiedSnapVersionStruct), diff --git a/src/registry.test.ts b/src/registry.test.ts index 93fba483..2f05d811 100644 --- a/src/registry.test.ts +++ b/src/registry.test.ts @@ -21,7 +21,7 @@ describe('Snaps Registry', () => { website: 'https://metamask.io', summary: 'Example Snap', description: 'Longer Example Snap description.', - reports: [ + audits: [ 'https://metamask.io/example/report-1.pdf', 'https://metamask.io/example/report-2.pdf', ], From dfaf1cf511874f9822c4ba687651e25f8d5804da Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Fri, 1 Sep 2023 14:23:13 +0200 Subject: [PATCH 3/3] Add `support` and `sourceCode` fields --- src/index.ts | 2 ++ src/registry.test.ts | 77 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index a4169d76..f2a04177 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,8 @@ export const VerifiedSnapStruct = object({ description: optional(string()), audits: optional(array(string())), tags: optional(array(string())), + support: optional(string()), + sourceCode: optional(string()), }), versions: record(VersionStruct, VerifiedSnapVersionStruct), }); diff --git a/src/registry.test.ts b/src/registry.test.ts index 2f05d811..70461509 100644 --- a/src/registry.test.ts +++ b/src/registry.test.ts @@ -25,6 +25,8 @@ describe('Snaps Registry', () => { 'https://metamask.io/example/report-1.pdf', 'https://metamask.io/example/report-2.pdf', ], + support: 'https://metamask.io/example/support', + sourceCode: 'https://metamask.io/example/source-code', tags: ['accounts', 'example'], }, versions: { @@ -34,10 +36,83 @@ describe('Snaps Registry', () => { }, }, }, - blockedSnaps: [], + blockedSnaps: [ + { + id: 'npm:example-blocked-snap', + versionRange: '^0.1.0', + reason: { + explanation: 'Example explanation', + url: 'https://metamask.io/example/explanation', + }, + }, + { + checksum: 'B3ar53ZIcKeKw3An3aqBeV4CAofj7jGK5hOAAxQY6A0=', + reason: { + explanation: 'Example explanation', + url: 'https://metamask.io/example/explanation', + }, + }, + ], }; /* eslint-enable @typescript-eslint/naming-convention */ expect(() => assert(registryDb, SnapsRegistryDatabaseStruct)).not.toThrow(); }); + + it('has a only mandatory fields', () => { + /* eslint-disable @typescript-eslint/naming-convention */ + const registryDb = { + verifiedSnaps: { + 'npm:example-snap': { + id: 'npm:example-snap', + metadata: { + name: 'Example Snap', + }, + versions: { + '0.1.0': { + checksum: 'A83r5/ZIcKeKw3An13HBeV4CAofj7jGK5hOStmHY6A0=', + }, + }, + }, + }, + blockedSnaps: [ + { + id: 'npm:example-blocked-snap', + versionRange: '^0.1.0', + }, + { + checksum: 'B3ar53ZIcKeKw3An3aqBeV4CAofj7jGK5hOAAxQY6A0=', + }, + ], + }; + /* eslint-enable @typescript-eslint/naming-convention */ + + expect(() => assert(registryDb, SnapsRegistryDatabaseStruct)).not.toThrow(); + }); + + it('should throw when the metadata has an unexpected field', () => { + /* eslint-disable @typescript-eslint/naming-convention */ + const registryDb = { + verifiedSnaps: { + 'npm:example-snap': { + id: 'npm:example-snap', + metadata: { + name: 'Example Snap', + unexpected: 'field', + }, + versions: { + '0.1.0': { + checksum: 'A83r5/ZIcKeKw3An13HBeV4CAofj7jGK5hOStmHY6A0=', + }, + }, + }, + }, + blockedSnaps: [], + }; + /* eslint-enable @typescript-eslint/naming-convention */ + + expect(() => assert(registryDb, SnapsRegistryDatabaseStruct)).toThrow( + 'At path: verifiedSnaps.npm:example-snap.metadata.unexpected -- Expected a value of type `never`, but received: `"field"`', + ); + }); });