Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix initial permissions types #2111

Merged
merged 7 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('manifest', () => {
'/snap/snap.manifest.json',
JSON.stringify(
getSnapManifest({
shasum: 'arUMLnuZBGUP4bP3mDBddSs5emfHMgEThNB54+LCm+c=',
shasum: 'G/W5b2JZVv+epgNX9pkN63X6Lye9EJVJ4NLSgAw/afc=',
}),
),
);
Expand Down
24 changes: 12 additions & 12 deletions packages/snaps-controllers/src/snaps/SnapController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3628,7 +3628,7 @@ describe('SnapController', () => {
],
},
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_confirm: {},
snap_dialog: {},
},
subject: { origin: MOCK_SNAP_ID },
},
Expand Down Expand Up @@ -3694,7 +3694,7 @@ describe('SnapController', () => {
expect(rootMessenger.call).toHaveBeenCalledWith(
'PermissionController:revokePermissions',
{
[MOCK_SNAP_ID]: ['snap_confirm'],
[MOCK_SNAP_ID]: ['snap_dialog'],
},
);

Expand Down Expand Up @@ -3823,7 +3823,7 @@ describe('SnapController', () => {
],
},
// eslint-disable-next-line @typescript-eslint/naming-convention
snap_confirm: {},
snap_dialog: {},
},
subject: { origin: MOCK_SNAP_ID },
},
Expand Down Expand Up @@ -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<string, Caveat<string, any>>
> = {
snap_confirm: {
snap_dialog: {
caveats: null,
parentCapability: 'snap_confirm',
parentCapability: 'snap_dialog',
id: '1',
date: 1,
invoker: MOCK_SNAP_ID,
Expand Down Expand Up @@ -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': {},
},
}),
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<string, Caveat<string, any>>
> = {
snap_confirm: {
snap_dialog: {
caveats: null,
parentCapability: 'snap_confirm',
parentCapability: 'snap_dialog',
id: '1',
date: 1,
invoker: MOCK_SNAP_ID,
Expand Down Expand Up @@ -5963,7 +5963,7 @@ describe('SnapController', () => {
snaps: false,
dapps: true,
},
snap_confirm: {},
snap_dialog: {},
'endowment:network-access': {},
},
}),
Expand Down
20 changes: 17 additions & 3 deletions packages/snaps-controllers/src/snaps/registry/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import type { JsonSnapsRegistryArgs } from './json';
import { JsonSnapsRegistry } from './json';
import { SnapsRegistryStatus } from './registry';

// Public key for the private key:
// `0x541c6759fd86c69eceb8d792d7174623db139d81a5b560aa026afcb2dd1bb21c`.
FrederikBolding marked this conversation as resolved.
Show resolved Hide resolved
const MOCK_PUBLIC_KEY =
'0x0351e33621fd89183c3db90db7db2a518a91ad0534d1345d031625d33e581e495a';
'0x03a885324b8520fba54a173999629952cfa1f97930c20902ec389f9c32c6ffbc40';

const getRegistry = (args?: Partial<JsonSnapsRegistryArgs>) => {
const messenger = getRestrictedSnapsRegistryControllerMessenger();
Expand Down Expand Up @@ -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',
Expand Down
8 changes: 4 additions & 4 deletions packages/snaps-controllers/src/test-utils/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -178,7 +178,7 @@ export const MOCK_ORIGIN_PERMISSIONS: Record<string, PermissionConstraint> = {

export const MOCK_SNAP_PERMISSIONS: Record<string, PermissionConstraint> = {
[SnapEndowments.Rpc]: MOCK_RPC_ORIGINS_PERMISSION,
[snapConfirmPermissionKey]: MOCK_SNAP_CONFIRM_PERMISSION,
[snapDialogPermissionKey]: MOCK_SNAP_DIALOG_PERMISSION,
};

export const getControllerMessenger = (registry = new MockSnapsRegistry()) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -332,7 +332,7 @@ describe('BaseSnapExecutor', () => {
message: 'The method does not exist / is not available.',
data: {
cause: null,
method: 'snap_confirm',
method: 'snap_dialog',
},
}),
},
Expand Down Expand Up @@ -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();
Expand Down
43 changes: 23 additions & 20 deletions packages/snaps-sdk/src/types/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, RequestedSnap>;
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<string, RequestedSnap>;
/* eslint-enable @typescript-eslint/naming-convention */
};
}>;
18 changes: 9 additions & 9 deletions packages/snaps-utils/src/manifest/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand All @@ -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({})),
Expand Down
4 changes: 2 additions & 2 deletions packages/snaps-utils/src/test-utils/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down