Skip to content

Commit 81fb2ac

Browse files
authored
Merge pull request #185 from MetaMask/fix/profile-sync-unauthorized
Fix profile sync unauthorized issue
2 parents 20aa38b + 61cf238 commit 81fb2ac

File tree

5 files changed

+66
-46
lines changed

5 files changed

+66
-46
lines changed

packages/gator-permissions-snap/snap.manifest.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33

44
import type { SnapManifest } from '@metamask/7715-permissions-shared/types';
55

6-
const kernelSnapId = process.env.KERNEL_SNAP_ID;
6+
// eslint-disable-next-line import/no-relative-packages
7+
import packageJson from './package.json' with { type: 'json' };
78

9+
const kernelSnapId = process.env.KERNEL_SNAP_ID;
10+
const messageSnapId = process.env.MESSAGE_SIGNING_SNAP_ID;
11+
const snapEnv = process.env.SNAP_ENV;
812
const manifest: SnapManifest = {
9-
version: '0.2.1',
13+
version: packageJson.version,
1014
description: 'Grants 7715 permissions from a DeleGator smart account',
1115
proposedName: 'Gator Permissions',
1216
repository: {
@@ -41,8 +45,25 @@ const manifest: SnapManifest = {
4145

4246
if (kernelSnapId) {
4347
manifest.initialConnections = {
44-
[kernelSnapId]: {},
48+
...(kernelSnapId ? { [kernelSnapId]: {} } : {}),
49+
...(messageSnapId ? { [messageSnapId]: {} } : {}),
4550
};
4651
}
4752

53+
if (snapEnv === 'local') {
54+
/**
55+
* Grant lifecycle hooks permission in local development environment.
56+
*
57+
* The lifecycle hooks endowment is required to enable the onInstall handler
58+
* which automatically installs the message signing snap during local development.
59+
* This ensures that the gator permissions snap can establish the necessary
60+
* connection to the message signing snap for 7715 permissions functionality.
61+
*
62+
* In production environments, the message signing snap is pre-installed by
63+
* the MetaMask extension, making this endowment unnecessary and it's excluded
64+
* to minimize the snap's permission footprint.
65+
*/
66+
manifest.initialPermissions['endowment:lifecycle-hooks'] = {};
67+
}
68+
4869
export default manifest;

packages/gator-permissions-snap/src/index.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/* eslint-disable no-restricted-globals */
2+
import type { GetSnapsResponse } from '@metamask/7715-permissions-shared/types';
23
import { logger } from '@metamask/7715-permissions-shared/utils';
34
import {
45
AuthType,
@@ -7,14 +8,17 @@ import {
78
UserStorage,
89
} from '@metamask/profile-sync-controller/sdk';
910
import {
10-
type Json,
11-
type JsonRpcParams,
12-
type OnRpcRequestHandler,
13-
type OnUserInputHandler,
1411
MethodNotFoundError,
1512
InvalidRequestError,
1613
InternalError,
1714
} from '@metamask/snaps-sdk';
15+
import type {
16+
OnInstallHandler,
17+
Json,
18+
JsonRpcParams,
19+
OnRpcRequestHandler,
20+
OnUserInputHandler,
21+
} from '@metamask/snaps-sdk';
1822

1923
import { AccountApiClient } from './clients/accountApiClient';
2024
import { BlockchainTokenMetadataClient } from './clients/blockchainMetadataClient';
@@ -228,3 +232,31 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
228232
*/
229233
export const onUserInput: OnUserInputHandler =
230234
userEventDispatcher.createUserInputEventHandler();
235+
236+
export const onInstall: OnInstallHandler = async () => {
237+
/**
238+
* Local Development Only
239+
*
240+
* The message signing snap must be installed and the gator permissions snap must
241+
* have permission to communicate with the message signing snap, or the request is rejected.
242+
*
243+
* Since the message signing snap is preinstalled in production, and has
244+
* initialConnections configured to automatically connect to the gator snap, this is not needed in production.
245+
* The following code will be tree-shaken out in production builds.
246+
*/
247+
// eslint-disable-next-line no-restricted-globals
248+
if (snapEnv === 'local' && isStorePermissionsFeatureEnabled) {
249+
const installedSnaps = (await snap.request({
250+
method: 'wallet_getSnaps',
251+
})) as unknown as GetSnapsResponse;
252+
if (!installedSnaps[messageSigningSnapId]) {
253+
logger.debug('Installing local message signing snap');
254+
await snap.request({
255+
method: 'wallet_requestSnaps',
256+
params: {
257+
[messageSigningSnapId]: {},
258+
},
259+
});
260+
}
261+
}
262+
};

packages/permissions-kernel-snap/snap.manifest.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
/* eslint-disable @typescript-eslint/naming-convention */
12
/* eslint-disable no-restricted-globals */
23
import type { SnapManifest } from '@metamask/7715-permissions-shared/types';
34

5+
// eslint-disable-next-line import/no-relative-packages
6+
import packageJson from './package.json' with { type: 'json' };
7+
48
const manifest: SnapManifest = {
5-
version: '0.2.0',
9+
version: packageJson.version,
610
description: 'Manage onchain 7715 permissions',
711
proposedName: 'MetaMask Permissions Kernel',
812
repository: {

packages/site/src/components/Buttons.tsx

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,6 @@ export const ConnectButton = (
9494
);
9595
};
9696

97-
export const InstallButton = (
98-
props: ComponentProps<typeof Button> & { $isInstalled?: boolean },
99-
) => {
100-
return (
101-
<Button {...props}>
102-
<FlaskFox />
103-
<ButtonText>{props.$isInstalled ? 'Installed' : 'Install'}</ButtonText>
104-
</Button>
105-
);
106-
};
107-
10897
export const CustomMessageButton = (
10998
props: ComponentProps<typeof Button> & { $text?: string },
11099
) => {

packages/site/src/pages/index.tsx

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import * as chains from 'viem/chains';
1414

1515
import {
1616
ConnectButton,
17-
InstallButton,
1817
InstallFlaskButton,
1918
CustomMessageButton,
2019
Card,
@@ -33,11 +32,7 @@ import type {
3332
NativeTokenPeriodicPermissionRequest,
3433
ERC20TokenPeriodicPermissionRequest,
3534
} from '../components/permissions/types';
36-
import {
37-
kernelSnapOrigin,
38-
gatorSnapOrigin,
39-
messageSigningSnapOrigin,
40-
} from '../config';
35+
import { kernelSnapOrigin, gatorSnapOrigin } from '../config';
4136
import {
4237
useMetaMask,
4338
useMetaMaskContext,
@@ -98,7 +93,6 @@ const Index = () => {
9893
const { isFlask, snapsDetected, installedSnaps, provider } = useMetaMask();
9994
const requestKernelSnap = useRequestSnap(kernelSnapOrigin);
10095
const requestPermissionSnap = useRequestSnap(gatorSnapOrigin);
101-
const requestMessageSigningSnap = useRequestSnap(messageSigningSnapOrigin);
10296

10397
const { delegateAccount } = useDelegateAccount({ chain: selectedChain });
10498
const { bundlerClient, getFeePerGas } = useBundlerClient({
@@ -122,9 +116,6 @@ const Index = () => {
122116

123117
const isKernelSnapReady = Boolean(installedSnaps[kernelSnapOrigin]);
124118
const isGatorSnapReady = Boolean(installedSnaps[gatorSnapOrigin]);
125-
const isMessageSigningSnapReady = Boolean(
126-
installedSnaps[messageSigningSnapOrigin],
127-
);
128119

129120
const chainId = selectedChain.id;
130121
const [permissionType, setPermissionType] = useState('native-token-stream');
@@ -496,23 +487,6 @@ const Index = () => {
496487
/>
497488
)}
498489

499-
<Card
500-
content={{
501-
title: 'Message Signing Snap',
502-
description:
503-
'Set up by installing and authorizing the message signing snap.',
504-
button: (
505-
<InstallButton
506-
onClick={requestMessageSigningSnap}
507-
disabled={!isMetaMaskReady || isMessageSigningSnapReady}
508-
$isInstalled={isMessageSigningSnapReady}
509-
/>
510-
),
511-
}}
512-
fullWidth
513-
disabled={!isMetaMaskReady}
514-
/>
515-
516490
<Card
517491
content={{
518492
title: `${isKernelSnapReady ? 'Reconnect' : 'Connect'}(kernel)`,

0 commit comments

Comments
 (0)