From 3a6191d3400bc483dbfa10f790b69def80c060e6 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 7 Dec 2022 16:25:35 +0100 Subject: [PATCH 01/14] use ui param instead of fields --- packages/rpc-methods/src/restricted/dialog.ts | 69 ++++++------------- packages/rpc-methods/tsconfig.build.json | 3 + packages/rpc-methods/tsconfig.json | 2 +- 3 files changed, 25 insertions(+), 49 deletions(-) diff --git a/packages/rpc-methods/src/restricted/dialog.ts b/packages/rpc-methods/src/restricted/dialog.ts index c8963d1622..8dc407b167 100644 --- a/packages/rpc-methods/src/restricted/dialog.ts +++ b/packages/rpc-methods/src/restricted/dialog.ts @@ -4,6 +4,7 @@ import { RestrictedMethodOptions, ValidPermissionSpecification, } from '@metamask/permission-controller'; +import { Component, ComponentStruct } from '@metamask/snaps-ui'; import { NonEmptyArray } from '@metamask/utils'; import { ethErrors } from 'eth-rpc-errors'; import { @@ -12,7 +13,6 @@ import { Infer, literal, object, - omit, optional, size, string, @@ -30,58 +30,23 @@ export enum DialogType { Prompt = 'Prompt', } -const BaseFieldsStruct = object({ - title: size(string(), 1, 40), - description: optional(size(string(), 1, 140)), - textAreaContent: optional(size(string(), 1, 1800)), - placeholder: optional(size(string(), 1, 40)), -}); - -const PromptFieldsStruct = omit(BaseFieldsStruct, ['textAreaContent']); - -const AlertFieldsStruct = omit(BaseFieldsStruct, ['placeholder']); +const PlaceholderStruct = optional(size(string(), 1, 40)); -const ConfirmationFieldsStruct = omit(BaseFieldsStruct, ['placeholder']); - -/** - * @property title - The alert title, no greater than 40 characters long. - * @property description - A description, displayed with the title, no greater - * than 140 characters long. - * @property textAreaContent - Free-from text content, no greater than 1800 - * characters long. - */ -export type AlertFields = Infer; - -/** - * @property title - A question describing what the user is confirming, no - * greater than 40 characters long. - * @property description - A description, displayed with the question, no - * greater than 140 characters long. - * @property textAreaContent - Free-from text content, no greater than 1800 - * characters long. - */ -export type ConfirmationFields = Infer; - -/** - * @property title - The prompt title, no greater than 40 characters long. - * @property description - A description, displayed with the prompt, no greater - * than 140 characters long. - */ -export type PromptFields = Infer; - -export type DialogFields = AlertFields | ConfirmationFields | PromptFields; +export type Placeholder = Infer; type ShowDialog = ( snapId: string, type: DialogType, - fields: DialogFields, + ui: Component, + placeholder: Placeholder, ) => Promise; export type DialogMethodHooks = { /** * @param snapId - The ID of the Snap that created the alert. * @param type - The dialog type. - * @param fields - The dialog fields. + * @param ui - The dialog custom UI. + * @param placeholder - The placeholder for the Prompt dialog input. */ showDialog: ShowDialog; }; @@ -144,23 +109,24 @@ const BaseParamsStruct = type({ const AlertParametersStruct = object({ type: literal(DialogType.Alert), - fields: AlertFieldsStruct, + ui: ComponentStruct, }); const ConfirmationParametersStruct = object({ type: literal(DialogType.Confirmation), - fields: ConfirmationFieldsStruct, + ui: ComponentStruct, }); const PromptParametersStruct = object({ type: literal(DialogType.Prompt), - fields: PromptFieldsStruct, + ui: ComponentStruct, + placeholder: PlaceholderStruct, }); const DialogParametersStruct = union([ + PromptParametersStruct, AlertParametersStruct, ConfirmationParametersStruct, - PromptParametersStruct, ]); export type DialogParameters = Infer; @@ -190,9 +156,16 @@ export function getDialogImplementation({ showDialog }: DialogMethodHooks) { } = args; const validatedType = getValidatedType(params); - const { fields } = getValidatedParams(params, structs[validatedType]); + const validatedParams = getValidatedParams(params, structs[validatedType]); + + const { ui } = validatedParams; + + const placeholder = + validatedParams.type === DialogType.Prompt + ? validatedParams.placeholder + : undefined; - return showDialog(origin, validatedType, fields); + return showDialog(origin, validatedType, ui, placeholder); }; } diff --git a/packages/rpc-methods/tsconfig.build.json b/packages/rpc-methods/tsconfig.build.json index 4dc952c93e..2e893ca60b 100644 --- a/packages/rpc-methods/tsconfig.build.json +++ b/packages/rpc-methods/tsconfig.build.json @@ -15,6 +15,9 @@ "references": [ { "path": "../snaps-utils/tsconfig.build.json" + }, + { + "path": "../snaps-ui/tsconfig.build.json" } ] } diff --git a/packages/rpc-methods/tsconfig.json b/packages/rpc-methods/tsconfig.json index a4f2b5a12e..fc8dd526b9 100644 --- a/packages/rpc-methods/tsconfig.json +++ b/packages/rpc-methods/tsconfig.json @@ -4,5 +4,5 @@ "baseUrl": "./" }, "include": ["./src"], - "references": [{ "path": "../snaps-utils" }] + "references": [{ "path": "../snaps-utils" }, { "path": "../snaps-ui" }] } From 74dd7d0ba40e723c5a35cce5544cc6a6daa86953 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 7 Dec 2022 16:54:04 +0100 Subject: [PATCH 02/14] add tests --- .../rpc-methods/src/restricted/dialog.test.ts | 231 +++--------------- packages/rpc-methods/src/restricted/dialog.ts | 11 +- 2 files changed, 37 insertions(+), 205 deletions(-) diff --git a/packages/rpc-methods/src/restricted/dialog.test.ts b/packages/rpc-methods/src/restricted/dialog.test.ts index d12d218777..034928b906 100644 --- a/packages/rpc-methods/src/restricted/dialog.test.ts +++ b/packages/rpc-methods/src/restricted/dialog.test.ts @@ -1,4 +1,5 @@ import { PermissionType } from '@metamask/permission-controller'; +import { heading, panel, text } from '@metamask/snaps-ui'; import { dialogBuilder, @@ -49,20 +50,17 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), }, }); expect(hooks.showDialog).toHaveBeenCalledTimes(1); - expect(hooks.showDialog).toHaveBeenCalledWith('foo', DialogType.Alert, { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }); + expect(hooks.showDialog).toHaveBeenCalledWith( + 'foo', + DialogType.Alert, + panel([heading('foo'), text('bar')]), + undefined, + ); }); }); @@ -75,11 +73,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Confirmation, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), }, }); @@ -87,11 +81,8 @@ describe('implementation', () => { expect(hooks.showDialog).toHaveBeenCalledWith( 'foo', DialogType.Confirmation, - { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - }, + panel([heading('foo'), text('bar')]), + undefined, ); }); }); @@ -105,20 +96,18 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - placeholder: 'Baz', - }, + ui: panel([heading('foo'), text('bar')]), + placeholder: 'foobar', }, }); expect(hooks.showDialog).toHaveBeenCalledTimes(1); - expect(hooks.showDialog).toHaveBeenCalledWith('foo', DialogType.Prompt, { - title: 'Foo', - description: 'Bar', - placeholder: 'Baz', - }); + expect(hooks.showDialog).toHaveBeenCalledWith( + 'foo', + DialogType.Prompt, + panel([heading('foo'), text('bar')]), + 'foobar', + ); }); }); @@ -169,12 +158,12 @@ describe('implementation', () => { it.each([ { type: DialogType.Alert }, - { type: DialogType.Alert, fields: null }, - { type: DialogType.Alert, fields: false }, - { type: DialogType.Alert, fields: '' }, - { type: DialogType.Alert, fields: 'abc' }, - { type: DialogType.Alert, fields: 2 }, - { type: DialogType.Alert, fields: [] }, + { type: DialogType.Alert, ui: null }, + { type: DialogType.Alert, ui: false }, + { type: DialogType.Alert, ui: '' }, + { type: DialogType.Alert, ui: 'abc' }, + { type: DialogType.Alert, ui: 2 }, + { type: DialogType.Alert, ui: [] }, ])('rejects invalid fields', async (value) => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); @@ -190,128 +179,9 @@ describe('implementation', () => { ); }); - it.each([undefined, null, false, 2, [], {}, new (class {})()])( - 'rejects invalid titles', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: value, - description: 'Bar', - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields.title -- Expected a string, but received: .*\./u, - ); - }, - ); - - it('rejects titles with invalid length', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: '', - description: 'Bar', - textAreaContent: 'Baz', - }, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.title -- Expected a string with a length between `1` and `40` but received one with a length of `0`.', - ); - }); - - it.each([true, 2, [], {}, new (class {})()])( - 'rejects invalid descriptions', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: value, - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields.description -- Expected a string, but received: .*\./u, - ); - }, - ); - - it('rejects too long descriptions', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'a'.repeat(141), - textAreaContent: 'Baz', - } as any, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.description -- Expected a string with a length between `1` and `140` but received one with a length of `141`.', - ); - }); - - it.each([true, 2, [], {}, new (class {})()])( - 'rejects invalid text area contents', - async (value) => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); - - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: value, - } as any, - }, - }), - ).rejects.toThrow( - /Invalid params: At path: fields\.textAreaContent -- Expected a string, but received: .*\./u, - ); - }, - ); - it.each([true, 2, [], {}, new (class {})()])( 'rejects invalid placeholder contents', - async (value) => { + async (value: any) => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); @@ -321,59 +191,32 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - placeholder: value, - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: value, }, }), ).rejects.toThrow( - /Invalid params: At path: fields\.placeholder -- Expected a string, but received: .*\./u, + /Invalid params: At path: placeholder -- Expected a string, but received: .*\./u, ); }, ); - it('rejects too long text area contents', async () => { + it('rejects placeholders with invalid length', async () => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); - await expect( - implementation({ - context: { origin: 'foo' }, - method: 'snap_dialog', - params: { - type: DialogType.Alert, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'a'.repeat(1801), - } as any, - }, - }), - ).rejects.toThrow( - 'Invalid params: At path: fields.textAreaContent -- Expected a string with a length between `1` and `1800` but received one with a length of `1801`.', - ); - }); - - it('rejects textAreaContent field for prompts', async () => { - const hooks = getMockDialogHooks(); - const implementation = getDialogImplementation(hooks); await expect( implementation({ context: { origin: 'foo' }, method: 'snap_dialog', params: { type: DialogType.Prompt, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: '', }, }), ).rejects.toThrow( - 'Invalid params: Prompts may not specify a "textAreaContent" field.', + 'Invalid params: At path: placeholder -- Expected a string with a length between `1` and `40` but received one with a length of `0`.', ); }); @@ -388,12 +231,8 @@ describe('implementation', () => { method: 'snap_dialog', params: { type, - fields: { - title: 'Foo', - description: 'Bar', - textAreaContent: 'Baz', - placeholder: 'Foobar', - } as any, + ui: panel([heading('foo'), text('bar')]), + placeholder: 'foobar', }, }), ).rejects.toThrow( diff --git a/packages/rpc-methods/src/restricted/dialog.ts b/packages/rpc-methods/src/restricted/dialog.ts index 8dc407b167..e229d07842 100644 --- a/packages/rpc-methods/src/restricted/dialog.ts +++ b/packages/rpc-methods/src/restricted/dialog.ts @@ -38,7 +38,7 @@ type ShowDialog = ( snapId: string, type: DialogType, ui: Component, - placeholder: Placeholder, + placeholder?: Placeholder, ) => Promise; export type DialogMethodHooks = { @@ -124,9 +124,9 @@ const PromptParametersStruct = object({ }); const DialogParametersStruct = union([ - PromptParametersStruct, AlertParametersStruct, ConfirmationParametersStruct, + PromptParametersStruct, ]); export type DialogParameters = Infer; @@ -206,13 +206,6 @@ function getValidatedParams( if (error instanceof StructError) { const { key, type: errorType } = error; - if (key === 'textAreaContent' && errorType === 'never') { - throw ethErrors.rpc.invalidParams({ - message: - 'Invalid params: Prompts may not specify a "textAreaContent" field.', - }); - } - if (key === 'placeholder' && errorType === 'never') { throw ethErrors.rpc.invalidParams({ message: From ea46382a65ef29d923d2c4ecda3b4e0379c5db5f Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 7 Dec 2022 17:03:52 +0100 Subject: [PATCH 03/14] remove workspace usage of snaps-ui package --- packages/rpc-methods/package.json | 7 +++++++ yarn.lock | 1 + 2 files changed, 8 insertions(+) diff --git a/packages/rpc-methods/package.json b/packages/rpc-methods/package.json index abb59558a0..1d343a36dc 100644 --- a/packages/rpc-methods/package.json +++ b/packages/rpc-methods/package.json @@ -29,6 +29,7 @@ "@metamask/browser-passworder": "^4.0.2", "@metamask/key-tree": "^6.0.0", "@metamask/permission-controller": "^1.0.1", + "@metamask/snaps-ui": "^0.25.0", "@metamask/snaps-utils": "^0.26.2", "@metamask/types": "^1.1.0", "@metamask/utils": "^3.3.1", @@ -70,5 +71,11 @@ "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" + }, + "lavamoat": { + "allowScripts": { + "@metamask/permission-controller>@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>keccak": false, + "@metamask/permission-controller>@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>secp256k1": false + } } } diff --git a/yarn.lock b/yarn.lock index ca398db6b4..bb8cfc5cef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2685,6 +2685,7 @@ __metadata: "@metamask/eslint-config-typescript": ^11.0.0 "@metamask/key-tree": ^6.0.0 "@metamask/permission-controller": ^1.0.1 + "@metamask/snaps-ui": ^0.25.0 "@metamask/snaps-utils": ^0.26.2 "@metamask/types": ^1.1.0 "@metamask/utils": ^3.3.1 From 1f4e071540e73d826f451792e9e8c750b98e3e8b Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 7 Dec 2022 17:10:09 +0100 Subject: [PATCH 04/14] remove old type exports --- packages/rpc-methods/src/restricted/index.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/rpc-methods/src/restricted/index.ts b/packages/rpc-methods/src/restricted/index.ts index 8e7ff25ae1..da4927bdea 100644 --- a/packages/rpc-methods/src/restricted/index.ts +++ b/packages/rpc-methods/src/restricted/index.ts @@ -24,13 +24,7 @@ import { invokeSnapBuilder, InvokeSnapMethodHooks } from './invokeSnap'; import { manageStateBuilder, ManageStateMethodHooks } from './manageState'; import { notifyBuilder, NotifyMethodHooks } from './notify'; -export type { - AlertFields, - ConfirmationFields, - DialogFields, - DialogParameters, - PromptFields, -} from './dialog'; +export type { DialogParameters } from './dialog'; export { DialogType } from './dialog'; export { ManageStateOperation } from './manageState'; export type { NotificationArgs } from './notify'; From 739daa3601d39746f94b020d61df2a6d6ad0cb98 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Mon, 12 Dec 2022 14:48:29 +0100 Subject: [PATCH 05/14] rename `ui` param to `content` --- .../rpc-methods/src/restricted/dialog.test.ts | 24 +++++++++---------- packages/rpc-methods/src/restricted/dialog.ts | 14 +++++------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/rpc-methods/src/restricted/dialog.test.ts b/packages/rpc-methods/src/restricted/dialog.test.ts index 034928b906..f93e9e2fd3 100644 --- a/packages/rpc-methods/src/restricted/dialog.test.ts +++ b/packages/rpc-methods/src/restricted/dialog.test.ts @@ -50,7 +50,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Alert, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), }, }); @@ -73,7 +73,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Confirmation, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), }, }); @@ -96,7 +96,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), placeholder: 'foobar', }, }); @@ -158,12 +158,12 @@ describe('implementation', () => { it.each([ { type: DialogType.Alert }, - { type: DialogType.Alert, ui: null }, - { type: DialogType.Alert, ui: false }, - { type: DialogType.Alert, ui: '' }, - { type: DialogType.Alert, ui: 'abc' }, - { type: DialogType.Alert, ui: 2 }, - { type: DialogType.Alert, ui: [] }, + { type: DialogType.Alert, content: null }, + { type: DialogType.Alert, content: false }, + { type: DialogType.Alert, content: '' }, + { type: DialogType.Alert, content: 'abc' }, + { type: DialogType.Alert, content: 2 }, + { type: DialogType.Alert, content: [] }, ])('rejects invalid fields', async (value) => { const hooks = getMockDialogHooks(); const implementation = getDialogImplementation(hooks); @@ -191,7 +191,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), placeholder: value, }, }), @@ -211,7 +211,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type: DialogType.Prompt, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), placeholder: '', }, }), @@ -231,7 +231,7 @@ describe('implementation', () => { method: 'snap_dialog', params: { type, - ui: panel([heading('foo'), text('bar')]), + content: panel([heading('foo'), text('bar')]), placeholder: 'foobar', }, }), diff --git a/packages/rpc-methods/src/restricted/dialog.ts b/packages/rpc-methods/src/restricted/dialog.ts index e229d07842..255a1a5e49 100644 --- a/packages/rpc-methods/src/restricted/dialog.ts +++ b/packages/rpc-methods/src/restricted/dialog.ts @@ -37,7 +37,7 @@ export type Placeholder = Infer; type ShowDialog = ( snapId: string, type: DialogType, - ui: Component, + content: Component, placeholder?: Placeholder, ) => Promise; @@ -45,7 +45,7 @@ export type DialogMethodHooks = { /** * @param snapId - The ID of the Snap that created the alert. * @param type - The dialog type. - * @param ui - The dialog custom UI. + * @param content - The dialog custom UI. * @param placeholder - The placeholder for the Prompt dialog input. */ showDialog: ShowDialog; @@ -109,17 +109,17 @@ const BaseParamsStruct = type({ const AlertParametersStruct = object({ type: literal(DialogType.Alert), - ui: ComponentStruct, + content: ComponentStruct, }); const ConfirmationParametersStruct = object({ type: literal(DialogType.Confirmation), - ui: ComponentStruct, + content: ComponentStruct, }); const PromptParametersStruct = object({ type: literal(DialogType.Prompt), - ui: ComponentStruct, + content: ComponentStruct, placeholder: PlaceholderStruct, }); @@ -158,14 +158,14 @@ export function getDialogImplementation({ showDialog }: DialogMethodHooks) { const validatedType = getValidatedType(params); const validatedParams = getValidatedParams(params, structs[validatedType]); - const { ui } = validatedParams; + const { content } = validatedParams; const placeholder = validatedParams.type === DialogType.Prompt ? validatedParams.placeholder : undefined; - return showDialog(origin, validatedType, ui, placeholder); + return showDialog(origin, validatedType, content, placeholder); }; } From 57e4c513ae355627c9b847565dc05e007f17c533 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 14 Dec 2022 15:23:33 +0100 Subject: [PATCH 06/14] bump snaps-ui --- packages/rpc-methods/package.json | 2 +- yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rpc-methods/package.json b/packages/rpc-methods/package.json index 1d343a36dc..de6d3a4e99 100644 --- a/packages/rpc-methods/package.json +++ b/packages/rpc-methods/package.json @@ -29,7 +29,7 @@ "@metamask/browser-passworder": "^4.0.2", "@metamask/key-tree": "^6.0.0", "@metamask/permission-controller": "^1.0.1", - "@metamask/snaps-ui": "^0.25.0", + "@metamask/snaps-ui": "^0.26.2", "@metamask/snaps-utils": "^0.26.2", "@metamask/types": "^1.1.0", "@metamask/utils": "^3.3.1", diff --git a/yarn.lock b/yarn.lock index bb8cfc5cef..4d8f3387b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2685,7 +2685,7 @@ __metadata: "@metamask/eslint-config-typescript": ^11.0.0 "@metamask/key-tree": ^6.0.0 "@metamask/permission-controller": ^1.0.1 - "@metamask/snaps-ui": ^0.25.0 + "@metamask/snaps-ui": ^0.26.2 "@metamask/snaps-utils": ^0.26.2 "@metamask/types": ^1.1.0 "@metamask/utils": ^3.3.1 From ef6fd2a7e3ed2ddf572d15fa4e4eb45b1d0a3ed5 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 14 Dec 2022 15:35:05 +0100 Subject: [PATCH 07/14] remove unnecessary lavamoat script policy --- package.json | 3 +++ packages/rpc-methods/package.json | 6 ------ yarn.lock | 3 ++- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index a8aa372432..08554f4ef2 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,9 @@ "prettier --write" ] }, + "dependencies": { + "@metamask/snaps-ui": "workspace:^" + }, "devDependencies": { "@lavamoat/allow-scripts": "^2.0.3", "@metamask/auto-changelog": "^3.1.0", diff --git a/packages/rpc-methods/package.json b/packages/rpc-methods/package.json index de6d3a4e99..0c4c87d73d 100644 --- a/packages/rpc-methods/package.json +++ b/packages/rpc-methods/package.json @@ -71,11 +71,5 @@ "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" - }, - "lavamoat": { - "allowScripts": { - "@metamask/permission-controller>@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>keccak": false, - "@metamask/permission-controller>@metamask/controller-utils>ethereumjs-util>ethereum-cryptography>secp256k1": false - } } } diff --git a/yarn.lock b/yarn.lock index 4d8f3387b2..f724a9820f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3014,7 +3014,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/snaps-ui@^0.26.2, @metamask/snaps-ui@workspace:packages/snaps-ui": +"@metamask/snaps-ui@^0.26.2, @metamask/snaps-ui@workspace:^, @metamask/snaps-ui@workspace:packages/snaps-ui": version: 0.0.0-use.local resolution: "@metamask/snaps-ui@workspace:packages/snaps-ui" dependencies: @@ -14144,6 +14144,7 @@ __metadata: "@metamask/eslint-config-jest": ^11.0.0 "@metamask/eslint-config-nodejs": ^11.0.1 "@metamask/eslint-config-typescript": ^11.0.0 + "@metamask/snaps-ui": "workspace:^" "@types/jest": ^27.5.1 "@types/node": ^14.14.25 "@typescript-eslint/eslint-plugin": ^5.42.1 From c637da98df4ee2b438af6b6069b96415ead32071 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Wed, 14 Dec 2022 15:36:35 +0100 Subject: [PATCH 08/14] remove snaps-ui from monorepo package.json --- package.json | 3 --- yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/package.json b/package.json index 08554f4ef2..a8aa372432 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,6 @@ "prettier --write" ] }, - "dependencies": { - "@metamask/snaps-ui": "workspace:^" - }, "devDependencies": { "@lavamoat/allow-scripts": "^2.0.3", "@metamask/auto-changelog": "^3.1.0", diff --git a/yarn.lock b/yarn.lock index f724a9820f..4d8f3387b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3014,7 +3014,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/snaps-ui@^0.26.2, @metamask/snaps-ui@workspace:^, @metamask/snaps-ui@workspace:packages/snaps-ui": +"@metamask/snaps-ui@^0.26.2, @metamask/snaps-ui@workspace:packages/snaps-ui": version: 0.0.0-use.local resolution: "@metamask/snaps-ui@workspace:packages/snaps-ui" dependencies: @@ -14144,7 +14144,6 @@ __metadata: "@metamask/eslint-config-jest": ^11.0.0 "@metamask/eslint-config-nodejs": ^11.0.1 "@metamask/eslint-config-typescript": ^11.0.0 - "@metamask/snaps-ui": "workspace:^" "@types/jest": ^27.5.1 "@types/node": ^14.14.25 "@typescript-eslint/eslint-plugin": ^5.42.1 From 2acfbe72f302e5d6c747c8c78423c55ae76e7ed3 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:30:23 +0100 Subject: [PATCH 09/14] update examples --- packages/examples/examples/bls-signer/package.json | 1 + .../examples/examples/bls-signer/snap.manifest.json | 2 +- packages/examples/examples/bls-signer/src/index.js | 12 ++++++++---- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/examples/examples/bls-signer/package.json b/packages/examples/examples/bls-signer/package.json index 5c6dab32b6..76ae2e3152 100644 --- a/packages/examples/examples/bls-signer/package.json +++ b/packages/examples/examples/bls-signer/package.json @@ -18,6 +18,7 @@ "clean": "rimraf 'dist/*'" }, "dependencies": { + "@metamask/snaps-ui": "^0.26.2", "eth-json-rpc-errors": "^1.1.0", "noble-bls12-381": "^0.2.3" }, diff --git a/packages/examples/examples/bls-signer/snap.manifest.json b/packages/examples/examples/bls-signer/snap.manifest.json index 913a340bee..b6a94e13de 100644 --- a/packages/examples/examples/bls-signer/snap.manifest.json +++ b/packages/examples/examples/bls-signer/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps-monorepo.git" }, "source": { - "shasum": "qjjWC6kWkmjne8yYUCbzXT8M2A51dQkOkZLReVwJM50=", + "shasum": "0pghQxoIyUyZTKlK76ooT02EeGB0UQQgXok/CWsQOgQ=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/examples/bls-signer/src/index.js b/packages/examples/examples/bls-signer/src/index.js index 25e1975caa..464c6b5893 100644 --- a/packages/examples/examples/bls-signer/src/index.js +++ b/packages/examples/examples/bls-signer/src/index.js @@ -1,3 +1,4 @@ +const { panel, header, copyable } = require('@metamask/snaps-ui'); const { errors: rpcErrors } = require('eth-json-rpc-errors'); const bls = require('noble-bls12-381'); @@ -62,17 +63,20 @@ async function getPubKey() { /** * Displays a prompt to the user in the MetaMask UI. * - * @param {string} header - A prompt, phrased as a question, no greater than 40 + * @param {string} headerContent - A prompt, phrased as a question, no greater than 40 * characters long. * @param {string} [message] - Free-from text content, no greater than 1800 * characters long. * @returns {Promise} `true` if the user accepted the confirmation, * and `false` otherwise. */ -async function promptUser(header, message) { +async function promptUser(headerContent, message) { const response = await snap.request({ - method: 'snap_confirm', - params: [{ prompt: header, textAreaContent: message }], + method: 'snap_dialog', + params: { + type: 'Confirmation', + content: panel([header(headerContent), copyable(message)]), + }, }); return response; } From 44007640694f3645b05df5ec350fa5fc0912b254 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:32:43 +0100 Subject: [PATCH 10/14] update manifest --- packages/examples/examples/bls-signer/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/examples/examples/bls-signer/snap.manifest.json b/packages/examples/examples/bls-signer/snap.manifest.json index b6a94e13de..3bb7cf5d4d 100644 --- a/packages/examples/examples/bls-signer/snap.manifest.json +++ b/packages/examples/examples/bls-signer/snap.manifest.json @@ -17,7 +17,7 @@ } }, "initialPermissions": { - "snap_confirm": {} + "snap_dialog": {} }, "manifestVersion": "0.1" } From 55f0acb11566bff8f191748f84b2889e81fd70ef Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:33:53 +0100 Subject: [PATCH 11/14] lockfile --- yarn.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn.lock b/yarn.lock index 4d8f3387b2..8a5343abf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5349,6 +5349,7 @@ __metadata: "@metamask/eslint-config-nodejs": ^11.0.1 "@metamask/eslint-config-typescript": ^11.0.0 "@metamask/snaps-cli": ^0.26.2 + "@metamask/snaps-ui": ^0.26.2 "@typescript-eslint/eslint-plugin": ^5.42.1 "@typescript-eslint/parser": ^5.42.1 eslint: ^8.27.0 From c97ad6f36fd0adcd4465be3a58b806d3c267998e Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:40:17 +0100 Subject: [PATCH 12/14] update threshold --- packages/rpc-methods/jest.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rpc-methods/jest.config.js b/packages/rpc-methods/jest.config.js index 4758e29423..86a89c495f 100644 --- a/packages/rpc-methods/jest.config.js +++ b/packages/rpc-methods/jest.config.js @@ -12,8 +12,8 @@ module.exports = deepmerge(baseConfig, { global: { branches: 75.18, functions: 87.5, - lines: 88.67, - statements: 88.32, + lines: 88.61, + statements: 88.26, }, }, testTimeout: 2500, From b043f919f3ea5930f00d5ae92af767ab7065cf23 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:41:49 +0100 Subject: [PATCH 13/14] rename to title --- packages/examples/examples/bls-signer/src/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/examples/examples/bls-signer/src/index.js b/packages/examples/examples/bls-signer/src/index.js index 464c6b5893..d33eb5518e 100644 --- a/packages/examples/examples/bls-signer/src/index.js +++ b/packages/examples/examples/bls-signer/src/index.js @@ -63,19 +63,19 @@ async function getPubKey() { /** * Displays a prompt to the user in the MetaMask UI. * - * @param {string} headerContent - A prompt, phrased as a question, no greater than 40 + * @param {string} title - A prompt, phrased as a question, no greater than 40 * characters long. * @param {string} [message] - Free-from text content, no greater than 1800 * characters long. * @returns {Promise} `true` if the user accepted the confirmation, * and `false` otherwise. */ -async function promptUser(headerContent, message) { +async function promptUser(title, message) { const response = await snap.request({ method: 'snap_dialog', params: { type: 'Confirmation', - content: panel([header(headerContent), copyable(message)]), + content: panel([header(title), copyable(message)]), }, }); return response; From 690a031423c0b575faac517c5862019271f64803 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 15 Dec 2022 14:43:32 +0100 Subject: [PATCH 14/14] update manifest --- packages/examples/examples/bls-signer/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/examples/examples/bls-signer/snap.manifest.json b/packages/examples/examples/bls-signer/snap.manifest.json index 3bb7cf5d4d..492e0fa478 100644 --- a/packages/examples/examples/bls-signer/snap.manifest.json +++ b/packages/examples/examples/bls-signer/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps-monorepo.git" }, "source": { - "shasum": "0pghQxoIyUyZTKlK76ooT02EeGB0UQQgXok/CWsQOgQ=", + "shasum": "WFEHEX72iejZA/ER6IF6nxhdZscMzdf2TcvNt1mkk1s=", "location": { "npm": { "filePath": "dist/bundle.js",