Skip to content

Commit 9d7ad4f

Browse files
committed
Enhance local development setup by adding lifecycle hooks permission and installing message signing snap if not present
1 parent 97e7056 commit 9d7ad4f

File tree

4 files changed

+36
-39
lines changed

4 files changed

+36
-39
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { SnapManifest } from '@metamask/7715-permissions-shared/types';
55

66
const kernelSnapId = process.env.KERNEL_SNAP_ID;
77
const messageSnapId = process.env.MESSAGE_SIGNING_SNAP_ID;
8-
8+
const snapEnv = process.env.SNAP_ENV;
99
const manifest: SnapManifest = {
1010
version: '0.2.1',
1111
description: 'Grants 7715 permissions from a DeleGator smart account',
@@ -47,4 +47,9 @@ if (kernelSnapId) {
4747
};
4848
}
4949

50+
if (snapEnv === 'local') {
51+
// Grant lifecycle hooks permission in local development environment
52+
manifest.initialPermissions['endowment:lifecycle-hooks'] = {};
53+
}
54+
5055
export default manifest;

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
MethodNotFoundError,
1515
InvalidRequestError,
1616
InternalError,
17+
OnInstallHandler,
1718
} from '@metamask/snaps-sdk';
1819

1920
import { AccountApiClient } from './clients/accountApiClient';
@@ -37,6 +38,7 @@ import { TokenMetadataService } from './services/tokenMetadataService';
3738
import { TokenPricesService } from './services/tokenPricesService';
3839
import { createStateManager } from './stateManagement';
3940
import { UserEventDispatcher } from './userEventDispatcher';
41+
import { GetSnapsResponse } from '@metamask/7715-permissions-shared/types';
4042

4143
const isStorePermissionsFeatureEnabled =
4244
process.env.STORE_PERMISSIONS_ENABLED === 'true';
@@ -228,3 +230,30 @@ export const onRpcRequest: OnRpcRequestHandler = async ({
228230
*/
229231
export const onUserInput: OnUserInputHandler =
230232
userEventDispatcher.createUserInputEventHandler();
233+
234+
export const onInstall: OnInstallHandler = async () => {
235+
/**
236+
* Local Development Only
237+
*
238+
* The message signing snap must be installed and the gator permissions snap must
239+
* have permission to communicate with the message signing snap, or the request is rejected.
240+
*
241+
* Since the message signing snap is preinstalled in production, and has
242+
* initialConnections configured to automatically connect to the gator snap, this is not needed in production.
243+
*/
244+
// eslint-disable-next-line no-restricted-globals
245+
if (snapEnv === 'local' && isStorePermissionsFeatureEnabled) {
246+
const installedSnaps = (await snap.request({
247+
method: 'wallet_getSnaps',
248+
})) as unknown as GetSnapsResponse;
249+
if (!installedSnaps[messageSigningSnapId]) {
250+
logger.debug('Installing local message signing snap');
251+
await snap.request({
252+
method: 'wallet_requestSnaps',
253+
params: {
254+
[messageSigningSnapId]: {},
255+
},
256+
});
257+
}
258+
}
259+
};

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)