diff --git a/packages/snaps-cli/src/commands/manifest/implementation.test.ts b/packages/snaps-cli/src/commands/manifest/implementation.test.ts index fe72a55338..7c5ef2a99f 100644 --- a/packages/snaps-cli/src/commands/manifest/implementation.test.ts +++ b/packages/snaps-cli/src/commands/manifest/implementation.test.ts @@ -38,7 +38,7 @@ describe('manifest', () => { '/snap/snap.manifest.json', JSON.stringify( getSnapManifest({ - shasum: 'arUMLnuZBGUP4bP3mDBddSs5emfHMgEThNB54+LCm+c=', + shasum: 'G/W5b2JZVv+epgNX9pkN63X6Lye9EJVJ4NLSgAw/afc=', }), ), ); diff --git a/packages/snaps-controllers/src/snaps/SnapController.test.ts b/packages/snaps-controllers/src/snaps/SnapController.test.ts index 6bc9c6f282..35bac6303f 100644 --- a/packages/snaps-controllers/src/snaps/SnapController.test.ts +++ b/packages/snaps-controllers/src/snaps/SnapController.test.ts @@ -3628,7 +3628,7 @@ describe('SnapController', () => { ], }, // eslint-disable-next-line @typescript-eslint/naming-convention - snap_confirm: {}, + snap_dialog: {}, }, subject: { origin: MOCK_SNAP_ID }, }, @@ -3694,7 +3694,7 @@ describe('SnapController', () => { expect(rootMessenger.call).toHaveBeenCalledWith( 'PermissionController:revokePermissions', { - [MOCK_SNAP_ID]: ['snap_confirm'], + [MOCK_SNAP_ID]: ['snap_dialog'], }, ); @@ -3823,7 +3823,7 @@ describe('SnapController', () => { ], }, // eslint-disable-next-line @typescript-eslint/naming-convention - snap_confirm: {}, + snap_dialog: {}, }, subject: { origin: MOCK_SNAP_ID }, }, @@ -5557,16 +5557,16 @@ describe('SnapController', () => { /* eslint-disable @typescript-eslint/naming-convention */ const initialPermissions = { [handlerEndowments.onRpcRequest]: { snaps: false, dapps: true }, - snap_confirm: {}, + snap_dialog: {}, snap_manageState: {}, }; const approvedPermissions: SubjectPermissions< ValidPermission> > = { - snap_confirm: { + snap_dialog: { caveats: null, - parentCapability: 'snap_confirm', + parentCapability: 'snap_dialog', id: '1', date: 1, invoker: MOCK_SNAP_ID, @@ -5607,7 +5607,7 @@ describe('SnapController', () => { version: '1.1.0' as SemVerRange, initialPermissions: { [handlerEndowments.onRpcRequest]: { snaps: false, dapps: true }, - snap_confirm: {}, + snap_dialog: {}, 'endowment:network-access': {}, }, }), @@ -5712,7 +5712,7 @@ describe('SnapController', () => { approvedPermissions: { [handlerEndowments.onRpcRequest]: approvedPermissions[handlerEndowments.onRpcRequest], - snap_confirm: approvedPermissions.snap_confirm, + snap_dialog: approvedPermissions.snap_dialog, }, unusedPermissions: { snap_manageState: approvedPermissions.snap_manageState, @@ -5911,15 +5911,15 @@ describe('SnapController', () => { /* eslint-disable @typescript-eslint/naming-convention */ const initialPermissions = { [handlerEndowments.onRpcRequest]: { snaps: false, dapps: true }, - snap_confirm: {}, + snap_dialog: {}, snap_manageState: {}, }; const approvedPermissions: SubjectPermissions< ValidPermission> > = { - snap_confirm: { + snap_dialog: { caveats: null, - parentCapability: 'snap_confirm', + parentCapability: 'snap_dialog', id: '1', date: 1, invoker: MOCK_SNAP_ID, @@ -5963,7 +5963,7 @@ describe('SnapController', () => { snaps: false, dapps: true, }, - snap_confirm: {}, + snap_dialog: {}, 'endowment:network-access': {}, }, }), diff --git a/packages/snaps-controllers/src/snaps/registry/json.test.ts b/packages/snaps-controllers/src/snaps/registry/json.test.ts index 75111315c4..5441367f81 100644 --- a/packages/snaps-controllers/src/snaps/registry/json.test.ts +++ b/packages/snaps-controllers/src/snaps/registry/json.test.ts @@ -11,8 +11,10 @@ import type { JsonSnapsRegistryArgs } from './json'; import { JsonSnapsRegistry } from './json'; import { SnapsRegistryStatus } from './registry'; +// Public key for the private key: +// `0x541c6759fd86c69eceb8d792d7174623db139d81a5b560aa026afcb2dd1bb21c`. const MOCK_PUBLIC_KEY = - '0x0351e33621fd89183c3db90db7db2a518a91ad0534d1345d031625d33e581e495a'; + '0x03a885324b8520fba54a173999629952cfa1f97930c20902ec389f9c32c6ffbc40'; const getRegistry = (args?: Partial) => { const messenger = getRestrictedSnapsRegistryControllerMessenger(); @@ -54,16 +56,28 @@ const MOCK_DATABASE: SnapsRegistryDatabase = { ], }; +// To regenerate this signature: +// 1. Use the private key above, and paste it in `secp256k1-key` in +// `snaps-registry`. +// 2. JSON.stringify the database above, and paste it in the `sign-registry` +// script in `snaps-registry` (instead of `fs.readFile`). +// - Pasting the JSON in the registry file directly will not work, as it +// contains a trailing newline. +// 3. Run the `sign-registry` script. +// 4. Copy the signature from the `signature.json` file. const MOCK_SIGNATURE = - '0x3044022067256cfed70fe93696246f58aa7ff252eba82fd3a6741d2551a58dcda017111402201cc11efbf5bc5f381b4bae4b83d84565ba478ad33308d72c23b47e8dda5b9983'; + '0x304402201bfe1a98837631b669643135766de58deb426dc3eeb0a908c8000f85a047db3102207ac621072ea59737287099ac830323b34e59bfc41fb62119b16ce24d0c433f9e'; const MOCK_SIGNATURE_FILE = { signature: MOCK_SIGNATURE, curve: 'secp256k1', format: 'DER', }; +// To regenerate this signature: +// 1. Follow the steps above, but use the empty database below: +// `{"verifiedSnaps":{},"blockedSnaps":[]}` const MOCK_EMPTY_SIGNATURE = - '0x304402202de0931fff0173f5c0e701cc8228f2b732da5fa719199b487d7c05e7a47b954702202ff96a4a4748af9cc3a9b6eb7065235f84a2680add6e3aee3ee761eb3084a8e1'; + '0x30450221009394dd1ab94c99079ce0e9f24170e4e4c40811e261013d3e6b80e4076cca7f9c0220201b6f5479a553fd50fc43fc50d18874583f29757b3f44cd088fae5aeb3595e2'; const MOCK_EMPTY_SIGNATURE_FILE = { signature: MOCK_EMPTY_SIGNATURE, curve: 'secp256k1', diff --git a/packages/snaps-controllers/src/test-utils/controller.ts b/packages/snaps-controllers/src/test-utils/controller.ts index 4e6e4ca6cb..9b5ac87144 100644 --- a/packages/snaps-controllers/src/test-utils/controller.ts +++ b/packages/snaps-controllers/src/test-utils/controller.ts @@ -96,7 +96,7 @@ export class MockApprovalController { export const approvalControllerMock = new MockApprovalController(); -export const snapConfirmPermissionKey = 'snap_confirm'; +export const snapDialogPermissionKey = 'snap_dialog'; export const MOCK_SNAP_SUBJECT_METADATA: SubjectMetadata = { origin: MOCK_SNAP_ID, @@ -144,12 +144,12 @@ export const MOCK_DAPPS_RPC_ORIGINS_PERMISSION: PermissionConstraint = { parentCapability: SnapEndowments.Rpc, }; -export const MOCK_SNAP_CONFIRM_PERMISSION: PermissionConstraint = { +export const MOCK_SNAP_DIALOG_PERMISSION: PermissionConstraint = { caveats: null, date: 1664187844588, id: 'izn0WGUO8cvq_jqvLQuQP', invoker: MOCK_SNAP_ID, - parentCapability: snapConfirmPermissionKey, + parentCapability: snapDialogPermissionKey, }; export const MOCK_WALLET_SNAP_PERMISSION: PermissionConstraint = { @@ -178,7 +178,7 @@ export const MOCK_ORIGIN_PERMISSIONS: Record = { export const MOCK_SNAP_PERMISSIONS: Record = { [SnapEndowments.Rpc]: MOCK_RPC_ORIGINS_PERMISSION, - [snapConfirmPermissionKey]: MOCK_SNAP_CONFIRM_PERMISSION, + [snapDialogPermissionKey]: MOCK_SNAP_DIALOG_PERMISSION, }; export const getControllerMessenger = (registry = new MockSnapsRegistry()) => { diff --git a/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts b/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts index 98ef405245..322c90e34b 100644 --- a/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts +++ b/packages/snaps-execution-environments/src/common/BaseSnapExecutor.test.browser.ts @@ -296,7 +296,7 @@ describe('BaseSnapExecutor', () => { it("doesn't allow snap APIs in the Ethereum provider", async () => { const CODE = ` - module.exports.onRpcRequest = () => ethereum.request({ method: 'snap_confirm', params: [] }); + module.exports.onRpcRequest = () => ethereum.request({ method: 'snap_dialog', params: [] }); `; const executor = new TestSnapExecutor(); @@ -332,7 +332,7 @@ describe('BaseSnapExecutor', () => { message: 'The method does not exist / is not available.', data: { cause: null, - method: 'snap_confirm', + method: 'snap_dialog', }, }), }, @@ -536,7 +536,7 @@ describe('BaseSnapExecutor', () => { it("doesn't allow direct access to ethereum internals", async () => { const CODE = ` module.exports.onRpcRequest = () => - ethereum._rpcEngine.handle({ method: 'snap_confirm', params: [] }); + ethereum._rpcEngine.handle({ method: 'snap_dialog', params: [] }); `; const executor = new TestSnapExecutor(); diff --git a/packages/snaps-sdk/src/types/permissions.ts b/packages/snaps-sdk/src/types/permissions.ts index 50f4e3aea8..0599b90e05 100644 --- a/packages/snaps-sdk/src/types/permissions.ts +++ b/packages/snaps-sdk/src/types/permissions.ts @@ -22,38 +22,41 @@ export type RequestedSnap = { version?: string; }; -export type InitialPermissions = { - 'endowment:cronjob'?: { +export type InitialPermissions = Partial<{ + 'endowment:cronjob': { jobs: Cronjob[]; }; - 'endowment:keyring'?: { + 'endowment:ethereum-provider': EmptyObject; + 'endowment:keyring': { allowedOrigins?: string[]; }; - 'endowment:name-lookup'?: ChainId[]; - 'endowment:network-access'?: EmptyObject; - 'endowment:rpc'?: { + 'endowment:lifecycle-hooks': EmptyObject; + 'endowment:name-lookup': ChainId[]; + 'endowment:network-access': EmptyObject; + 'endowment:page-home': EmptyObject; + 'endowment:rpc': { dapps?: boolean; snaps?: boolean; allowedOrigins?: string[]; }; - 'endowment:signature-insight'?: { + 'endowment:signature-insight': { allowSignatureOrigin?: boolean; }; - 'endowment:transaction-insight'?: { + 'endowment:transaction-insight': { allowTransactionOrigin?: boolean; }; - 'endowment:webassembly'?: EmptyObject; + 'endowment:webassembly': EmptyObject; /* eslint-disable @typescript-eslint/naming-convention */ - snap_confirm?: EmptyObject; - snap_dialog?: EmptyObject; - snap_getBip32Entropy?: Bip32Entropy[]; - snap_getBip32PublicKey?: Bip32Entropy[]; - snap_getBip44Entropy?: Bip44Entropy[]; - snap_getEntropy?: EmptyObject; - snap_manageAccounts?: EmptyObject; - snap_manageState?: EmptyObject; - snap_notify?: EmptyObject; - wallet_snap?: Record; + snap_dialog: EmptyObject; + snap_getBip32Entropy: Bip32Entropy[]; + snap_getBip32PublicKey: Bip32Entropy[]; + snap_getBip44Entropy: Bip44Entropy[]; + snap_getEntropy: EmptyObject; + snap_getLocale: EmptyObject; + snap_manageAccounts: EmptyObject; + snap_manageState: EmptyObject; + snap_notify: EmptyObject; + wallet_snap: Record; /* eslint-enable @typescript-eslint/naming-convention */ -}; +}>; diff --git a/packages/snaps-utils/src/manifest/validation.ts b/packages/snaps-utils/src/manifest/validation.ts index fc8eab028f..750fd42c4b 100644 --- a/packages/snaps-utils/src/manifest/validation.ts +++ b/packages/snaps-utils/src/manifest/validation.ts @@ -145,9 +145,16 @@ export const ChainIdsStruct = array(ChainIdStruct); /* eslint-disable @typescript-eslint/naming-convention */ export const PermissionsStruct = type({ + 'endowment:cronjob': optional( + object({ jobs: CronjobSpecificationArrayStruct }), + ), 'endowment:ethereum-provider': optional(object({})), + 'endowment:keyring': optional(KeyringOriginsStruct), + 'endowment:lifecycle-hooks': optional(object({})), + 'endowment:name-lookup': optional(ChainIdsStruct), 'endowment:network-access': optional(object({})), - 'endowment:webassembly': optional(object({})), + 'endowment:page-home': optional(object({})), + 'endowment:rpc': optional(RpcOriginsStruct), 'endowment:signature-insight': optional( object({ allowSignatureOrigin: optional(boolean()), @@ -158,15 +165,8 @@ export const PermissionsStruct = type({ allowTransactionOrigin: optional(boolean()), }), ), - 'endowment:cronjob': optional( - object({ jobs: CronjobSpecificationArrayStruct }), - ), - 'endowment:rpc': optional(RpcOriginsStruct), - 'endowment:name-lookup': optional(ChainIdsStruct), - 'endowment:keyring': optional(KeyringOriginsStruct), + 'endowment:webassembly': optional(object({})), snap_dialog: optional(object({})), - // TODO: Remove - snap_confirm: optional(object({})), snap_manageState: optional(object({})), snap_manageAccounts: optional(object({})), snap_notify: optional(object({})), diff --git a/packages/snaps-utils/src/test-utils/manifest.ts b/packages/snaps-utils/src/test-utils/manifest.ts index 3e435bfb21..f95126d505 100644 --- a/packages/snaps-utils/src/test-utils/manifest.ts +++ b/packages/snaps-utils/src/test-utils/manifest.ts @@ -30,7 +30,7 @@ export const MOCK_SNAP_DESCRIPTION = 'The test example snap!'; export const MOCK_SNAP_VERSION = '1.0.0' as SemVerVersion; /* eslint-disable @typescript-eslint/naming-convention */ export const MOCK_INITIAL_PERMISSIONS = { - snap_confirm: {}, + snap_dialog: {}, 'endowment:rpc': { snaps: true, dapps: false }, }; /* eslint-enable @typescript-eslint/naming-convention */ @@ -69,7 +69,7 @@ export const ALTERNATIVE_SNAP_ICON = // This will need to be recalculated if the checksum inputs change. export const DEFAULT_SNAP_SHASUM = - '7KGs2hbdzoEBXD1cjwQ6+K0v7HlzuY5ah+H9Gdh7g6k='; + 'rNyfINgNh161cBmUop+F7xlE+GSEDZH53Y/HDpGLGGg='; /** * Get a mock snap manifest, based on the provided options. This is useful for