Skip to content

Commit

Permalink
[FLASK] snaps-skunkworks@0.20.0 (#15706)
Browse files Browse the repository at this point in the history
* snaps-skunkworks@0.20.0

* Generate LavaMoat policy

* Fix some breaking changes

* Update iframe execution env

* Fix unit tests

* Implement snap_getBip44Entropy

* Regenerate LavaMoat policy

* Prefer ControllerMessenger over direct calls

* Fix not showing warning for BIP44 legacy permission and E2E test

Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
  • Loading branch information
FrederikBolding and Mrtenz committed Aug 26, 2022
1 parent fe78890 commit 7fc418a
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 134 deletions.
9 changes: 6 additions & 3 deletions app/scripts/controllers/permissions/specifications.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { SnapCaveatType } from '@metamask/rpc-methods';
import {
CaveatTypes,
RestrictedMethods,
Expand All @@ -15,14 +16,16 @@ describe('PermissionController specifications', () => {
describe('caveat specifications', () => {
it('getCaveatSpecifications returns the expected specifications object', () => {
const caveatSpecifications = getCaveatSpecifications({});
expect(Object.keys(caveatSpecifications)).toHaveLength(2);
expect(Object.keys(caveatSpecifications)).toHaveLength(3);
expect(
caveatSpecifications[CaveatTypes.restrictReturnedAccounts].type,
).toStrictEqual(CaveatTypes.restrictReturnedAccounts);

// TODO: Use `SnapCaveatType` from `rpc-methods` when it's exported.
expect(caveatSpecifications.permittedDerivationPaths.type).toStrictEqual(
'permittedDerivationPaths',
SnapCaveatType.PermittedDerivationPaths,
);
expect(caveatSpecifications.permittedCoinTypes.type).toStrictEqual(
SnapCaveatType.PermittedCoinTypes,
);
});

Expand Down
34 changes: 23 additions & 11 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ export default class MetamaskController extends EventEmitter {
///: BEGIN:ONLY_INCLUDE_IN(flask)
this.snapExecutionService = new IframeExecutionService({
iframeUrl: new URL(
'https://metamask.github.io/iframe-execution-environment/0.6.0',
'https://metamask.github.io/iframe-execution-environment/0.7.0',
),
messenger: this.controllerMessenger.getRestricted({
name: 'ExecutionService',
Expand Down Expand Up @@ -1174,7 +1174,7 @@ export default class MetamaskController extends EventEmitter {
),
handleSnapRpcRequest: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:handleRpcRequest',
'SnapController:handleRequest',
),
getSnapState: this.controllerMessenger.call.bind(
this.controllerMessenger,
Expand Down Expand Up @@ -1849,12 +1849,22 @@ export default class MetamaskController extends EventEmitter {

///: BEGIN:ONLY_INCLUDE_IN(flask)
// snaps
removeSnapError: this.snapController.removeSnapError.bind(
this.snapController,
removeSnapError: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:removeSnapError',
),
disableSnap: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:disable',
),
enableSnap: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:enable',
),
removeSnap: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:remove',
),
disableSnap: this.snapController.disableSnap.bind(this.snapController),
enableSnap: this.snapController.enableSnap.bind(this.snapController),
removeSnap: this.snapController.removeSnap.bind(this.snapController),
dismissNotifications: this.dismissNotifications.bind(this),
markNotificationsAsRead: this.markNotificationsAsRead.bind(this),
///: END:ONLY_INCLUDE_IN
Expand Down Expand Up @@ -3760,8 +3770,9 @@ export default class MetamaskController extends EventEmitter {
getUnlockPromise: this.appStateController.getUnlockPromise.bind(
this.appStateController,
),
getSnaps: this.snapController.getPermittedSnaps.bind(
this.snapController,
getSnaps: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:getSnaps',
origin,
),
requestPermissions: async (requestedPermissions) => {
Expand All @@ -3778,8 +3789,9 @@ export default class MetamaskController extends EventEmitter {
origin,
),
getAccounts: this.getPermittedAccounts.bind(this, origin),
installSnaps: this.snapController.installSnaps.bind(
this.snapController,
installSnaps: this.controllerMessenger.call.bind(
this.controllerMessenger,
'SnapController:install',
origin,
),
}),
Expand Down
116 changes: 38 additions & 78 deletions lavamoat/browserify/flask/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -3350,12 +3350,14 @@
}
},
"@metamask/rpc-methods": {
"globals": {
"console.warn": true
},
"packages": {
"@metamask/controllers": true,
"@metamask/rpc-methods>@metamask/key-tree": true,
"@metamask/rpc-methods>@metamask/snap-utils": true,
"@metamask/rpc-methods>@metamask/utils": true,
"@metamask/snap-controllers": true,
"@metamask/snap-utils": true,
"@metamask/snap-utils>@metamask/utils": true,
"eth-rpc-errors": true
}
},
Expand Down Expand Up @@ -3404,34 +3406,6 @@
"@metamask/rpc-methods>@metamask/key-tree>@scure/base": true
}
},
"@metamask/rpc-methods>@metamask/snap-utils": {
"globals": {
"URL": true
},
"packages": {
"@babel/core": true,
"@babel/core>@babel/types": true,
"@metamask/rpc-methods>@metamask/snap-utils>ajv": true,
"@metamask/rpc-methods>@metamask/snap-utils>rfdc": true,
"browserify": true,
"browserify>buffer": true,
"browserify>crypto-browserify": true,
"browserify>events": true,
"browserify>path-browserify": true,
"eslint>fast-deep-equal": true,
"semver": true
}
},
"@metamask/rpc-methods>@metamask/snap-utils>rfdc": {
"packages": {
"browserify>buffer": true
}
},
"@metamask/rpc-methods>@metamask/utils": {
"packages": {
"eslint>fast-deep-equal": true
}
},
"@metamask/smart-transactions-controller": {
"globals": {
"URLSearchParams": true,
Expand Down Expand Up @@ -3486,11 +3460,8 @@
"packages": {
"@metamask/controllers": true,
"@metamask/providers>@metamask/object-multiplex": true,
"@metamask/rpc-methods>@metamask/snap-utils": true,
"@metamask/rpc-methods>@metamask/utils": true,
"@metamask/rpc-methods": true,
"@metamask/snap-controllers>@metamask/browser-passworder": true,
"@metamask/snap-controllers>@metamask/execution-environments": true,
"@metamask/snap-controllers>@metamask/obs-store": true,
"@metamask/snap-controllers>@metamask/post-message-stream": true,
"@metamask/snap-controllers>@xstate/fsm": true,
"@metamask/snap-controllers>concat-stream": true,
Expand All @@ -3499,9 +3470,10 @@
"@metamask/snap-controllers>nanoid": true,
"@metamask/snap-controllers>readable-web-to-node-stream": true,
"@metamask/snap-controllers>tar-stream": true,
"@metamask/snap-utils": true,
"@metamask/snap-utils>@metamask/utils": true,
"eth-rpc-errors": true,
"json-rpc-engine": true,
"json-rpc-engine>@metamask/safe-event-emitter": true,
"pump": true
}
},
Expand All @@ -3518,46 +3490,6 @@
"browserify>buffer": true
}
},
"@metamask/snap-controllers>@metamask/obs-store": {
"packages": {
"@metamask/snap-controllers>@metamask/obs-store>through2": true,
"browserify>stream-browserify": true,
"json-rpc-engine>@metamask/safe-event-emitter": true
}
},
"@metamask/snap-controllers>@metamask/obs-store>through2": {
"packages": {
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream": true,
"browserify>process": true,
"browserify>util": true,
"watchify>xtend": true
}
},
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream": {
"packages": {
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream>process-nextick-args": true,
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream>string_decoder": true,
"@metamask/snap-controllers>json-rpc-middleware-stream>readable-stream>safe-buffer": true,
"@storybook/api>util-deprecate": true,
"browserify>browser-resolve": true,
"browserify>events": true,
"browserify>process": true,
"browserify>timers-browserify": true,
"pumpify>inherits": true,
"readable-stream>core-util-is": true,
"readable-stream>isarray": true
}
},
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream>process-nextick-args": {
"packages": {
"browserify>process": true
}
},
"@metamask/snap-controllers>@metamask/obs-store>through2>readable-stream>string_decoder": {
"packages": {
"@metamask/snap-controllers>json-rpc-middleware-stream>readable-stream>safe-buffer": true
}
},
"@metamask/snap-controllers>@metamask/post-message-stream": {
"globals": {
"WorkerGlobalScope": true,
Expand All @@ -3568,8 +3500,8 @@
"removeEventListener": true
},
"packages": {
"@metamask/rpc-methods>@metamask/utils": true,
"@metamask/snap-controllers>@metamask/post-message-stream>readable-stream": true
"@metamask/snap-controllers>@metamask/post-message-stream>readable-stream": true,
"@metamask/snap-utils>@metamask/utils": true
}
},
"@metamask/snap-controllers>@metamask/post-message-stream>readable-stream": {
Expand Down Expand Up @@ -3784,6 +3716,34 @@
"pumpify>inherits": true
}
},
"@metamask/snap-utils": {
"globals": {
"URL": true
},
"packages": {
"@babel/core": true,
"@babel/core>@babel/types": true,
"@metamask/snap-utils>ajv": true,
"@metamask/snap-utils>rfdc": true,
"browserify": true,
"browserify>buffer": true,
"browserify>crypto-browserify": true,
"browserify>events": true,
"browserify>path-browserify": true,
"eslint>fast-deep-equal": true,
"semver": true
}
},
"@metamask/snap-utils>@metamask/utils": {
"packages": {
"eslint>fast-deep-equal": true
}
},
"@metamask/snap-utils>rfdc": {
"packages": {
"browserify>buffer": true
}
},
"@ngraveio/bc-ur": {
"packages": {
"@ngraveio/bc-ur>@apocentre/alias-sampling": true,
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@
"@metamask/obs-store": "^5.0.0",
"@metamask/post-message-stream": "^4.0.0",
"@metamask/providers": "^9.0.0",
"@metamask/rpc-methods": "^0.19.0",
"@metamask/rpc-methods": "^0.20.0",
"@metamask/slip44": "^2.1.0",
"@metamask/smart-transactions-controller": "^2.3.1",
"@metamask/snap-controllers": "^0.19.0",
"@metamask/snap-controllers": "^0.20.0",
"@metamask/snap-utils": "^0.20.0",
"@ngraveio/bc-ur": "^1.1.6",
"@popperjs/core": "^2.4.0",
"@reduxjs/toolkit": "^1.6.2",
Expand Down
2 changes: 2 additions & 0 deletions shared/constants/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const RestrictedMethods = Object.freeze({
snap_notify: 'snap_notify',
snap_manageState: 'snap_manageState',
snap_getBip32Entropy: 'snap_getBip32Entropy',
snap_getBip44Entropy: 'snap_getBip44Entropy',
'snap_getBip44Entropy_*': 'snap_getBip44Entropy_*',
'wallet_snap_*': 'wallet_snap_*',
///: END:ONLY_INCLUDE_IN
Expand All @@ -23,6 +24,7 @@ export const PermissionNamespaces = Object.freeze({
export const EndowmentPermissions = Object.freeze({
'endowment:network-access': 'endowment:network-access',
'endowment:long-running': 'endowment:long-running',
'endowment:transaction-insight': 'endowment:transaction-insight',
} as const);

// Methods / permissions in external packages that we are temporarily excluding.
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/snaps/test-snap-bip-44.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ describe('Test Snap bip-44', function () {
});
// deal with permissions popover
await driver.delay(1000);
await driver.press('#key-access-bip44-0', driver.Key.SPACE);
await driver.press('#key-access-bip44-legacy-0', driver.Key.SPACE);
await driver.clickElement({
text: 'Confirm',
tag: 'button',
Expand Down
14 changes: 14 additions & 0 deletions ui/helpers/utils/permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ const PERMISSION_DESCRIPTIONS = deepFreeze({
leftIcon: 'fas fa-door-open',
rightIcon: null,
},
[RestrictedMethods.snap_getBip44Entropy]: {
label: (t, _, permissionValue) => {
return permissionValue.caveats[0].value.map(({ coinType }) =>
t('permission_manageBip44Keys', [
<span className="permission-label-item" key={`coin-type-${coinType}`}>
{coinTypeToProtocolName(coinType) ||
`${coinType} (Unrecognized protocol)`}
</span>,
]),
);
},
leftIcon: 'fas fa-door-open',
rightIcon: null,
},
[RestrictedMethods['snap_getBip44Entropy_*']]: {
label: (t, permissionName) => {
const coinType = permissionName.split('_').slice(-1);
Expand Down
29 changes: 24 additions & 5 deletions ui/pages/permissions-connect/flask/snap-install/snap-install.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React, { useCallback, useState } from 'react';
import { flatMap } from '@metamask/snap-utils';
import { PageContainerFooter } from '../../../../components/ui/page-container';
import PermissionsConnectPermissionList from '../../../../components/app/permissions-connect-permission-list';
import PermissionsConnectFooter from '../../../../components/app/permissions-connect-footer';
Expand Down Expand Up @@ -38,7 +39,7 @@ export default function SnapInstall({
[request, approveSnapInstall],
);

const bip44EntropyPermissions =
const bip44LegacyEntropyPermissions =
request.permissions &&
Object.keys(request.permissions).filter((v) =>
v.startsWith('snap_getBip44Entropy_'),
Expand All @@ -50,8 +51,16 @@ export default function SnapInstall({
.filter(([key]) => key === 'snap_getBip32Entropy')
.map(([, value]) => value);

const bip44EntropyPermissions =
request.permissions &&
Object.entries(request.permissions)
.filter(([key]) => key === 'snap_getBip44Entropy')
.map(([, value]) => value);

const shouldShowWarning =
bip32EntropyPermissions?.length > 0 || bip44EntropyPermissions?.length > 0;
bip32EntropyPermissions?.length > 0 ||
bip44EntropyPermissions?.length > 0 ||
bip44LegacyEntropyPermissions?.length > 0;

const getCoinType = (bip44EntropyPermission) =>
bip44EntropyPermission?.split('_').slice(-1);
Expand Down Expand Up @@ -115,7 +124,7 @@ export default function SnapInstall({
onCancel={() => setIsShowingWarning(false)}
onSubmit={onSubmit}
warnings={[
...bip32EntropyPermissions.flatMap((permission, i) =>
...flatMap(bip32EntropyPermissions, (permission, i) =>
permission.caveats[0].value.map(({ path, curve }) => ({
id: `key-access-bip32-${path.join('/')}-${curve}-${i}`,
message: t('snapInstallWarningKeyAccess', [
Expand All @@ -124,10 +133,20 @@ export default function SnapInstall({
]),
})),
),
...bip44EntropyPermissions.map((permission, i) => {
...flatMap(bip44EntropyPermissions, (permission, i) =>
permission.caveats[0].value.map(({ coinType }) => ({
id: `key-access-bip44-${coinType}-${i}`,
message: t('snapInstallWarningKeyAccess', [
targetSubjectMetadata.name,
coinTypeToProtocolName(coinType) ||
t('unrecognizedProtocol', [coinType]),
]),
})),
),
...bip44LegacyEntropyPermissions.map((permission, i) => {
const coinType = getCoinType(permission);
return {
id: `key-access-bip44-${i}`,
id: `key-access-bip44-legacy-${i}`,
message: t('snapInstallWarningKeyAccess', [
targetSubjectMetadata.name,
coinTypeToProtocolName(coinType) ||
Expand Down

0 comments on commit 7fc418a

Please sign in to comment.