Skip to content

Commit b29dbc6

Browse files
committed
Decouple default permission offer from kernel snap
1 parent 4c8b5aa commit b29dbc6

22 files changed

Lines changed: 328 additions & 549 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://github.com/MetaMask/snap-7715-permissions.git"
88
},
99
"source": {
10-
"shasum": "B/45l1lyLyqYX2GkYxvKAmCCWOCSu030Do+IEMdQV+c=",
10+
"shasum": "rBYfwKftRHT6Ubb97mXlM4mpyS5QuNDEiRnoo7jUpAo=",
1111
"location": {
1212
"npm": {
1313
"filePath": "dist/bundle.js",

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ const boundRpcHandlers: {
137137
} = {
138138
[RpcMethod.PermissionProviderGrantAttenuatedPermissions]:
139139
rpcHandler.grantPermission.bind(rpcHandler),
140+
[RpcMethod.PermissionProviderGetPermissionOffers]:
141+
rpcHandler.getPermissionOffers.bind(rpcHandler),
140142
};
141143

142144
/**

packages/shared/src/utils/snap-permission-registry.ts renamed to packages/gator-permissions-snap/src/permissions/permission-offers.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
import type { GatorPermission } from '../types';
1+
import { zTypeDescriptor } from '@metamask/7715-permissions-shared/types';
2+
import { z } from 'zod';
3+
4+
export const zGatorPermission = z.object({
5+
// A type used for matching requests:
6+
type: zTypeDescriptor,
7+
8+
// Used to represent the permission to the user:
9+
proposedName: z.string(),
10+
});
11+
12+
export type GatorPermission = z.infer<typeof zGatorPermission>;
213

314
/**
415
* The default permission offers that the Gator snap will offer to the kernel snap
516
*/
6-
export const DEFAULT_OFFERS: GatorPermission[] = [
17+
export const DEFAULT_GATOR_PERMISSION_TO_OFFER: GatorPermission[] = [
718
{
819
type: 'native-token-stream',
920
proposedName: 'Native Token Stream',

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { KERNEL_SNAP_ID } from '@metamask/7715-permissions-shared/constants';
33
import { RpcMethod } from './rpcMethod';
44

55
const allowedPermissionsByOrigin: { [origin: string]: string[] } = {
6-
[KERNEL_SNAP_ID]: [RpcMethod.PermissionProviderGrantAttenuatedPermissions],
6+
[KERNEL_SNAP_ID]: [
7+
RpcMethod.PermissionProviderGrantAttenuatedPermissions,
8+
RpcMethod.PermissionProviderGetPermissionOffers,
9+
],
710
};
811

912
/**

packages/gator-permissions-snap/src/rpc/rpcHandler.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
import type { PermissionOffer } from '@metamask/7715-permissions-shared/types';
12
import { logger } from '@metamask/7715-permissions-shared/utils';
23
import type { Json } from '@metamask/snaps-sdk';
34

45
import type { PermissionHandlerFactory } from '../core/permissionHandlerFactory';
6+
import {
7+
DEFAULT_GATOR_PERMISSION_TO_OFFER,
8+
getIdFor,
9+
} from '../permissions/permission-offers';
510
import type { ProfileSyncManager } from '../profileSync';
611
import { validatePermissionRequestParam } from '../utils/validate';
712

@@ -16,6 +21,13 @@ export type RpcHandler = {
1621
* @returns The result of the grant permission request.
1722
*/
1823
grantPermission(params?: Json): Promise<Json>;
24+
25+
/**
26+
* Handles get permission offers requests.
27+
*
28+
* @returns The permission offers.
29+
*/
30+
getPermissionOffers(): Promise<Json>;
1931
};
2032

2133
/**
@@ -69,7 +81,28 @@ export function createRpcHandler(config: {
6981
return responses as Json[];
7082
};
7183

84+
/**
85+
* Handles get permission offers requests.
86+
*
87+
* @returns The permission offers.
88+
*/
89+
const getPermissionOffers = async (): Promise<Json> => {
90+
logger.debug('getPermissionOffers()');
91+
const gatorSnapDefaultsOffers = await Promise.all(
92+
DEFAULT_GATOR_PERMISSION_TO_OFFER.map(async (per) => {
93+
const id = await getIdFor(per);
94+
return {
95+
type: per.type,
96+
id,
97+
proposedName: per.proposedName,
98+
} as PermissionOffer;
99+
}),
100+
);
101+
return gatorSnapDefaultsOffers;
102+
};
103+
72104
return {
73105
grantPermission,
106+
getPermissionOffers,
74107
};
75108
}

packages/gator-permissions-snap/src/rpc/rpcMethod.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,9 @@
33
*/
44
export enum RpcMethod {
55
/**
6-
* This method is used by snaps to offer its cryptographic abilities as permissions to kernel.
6+
* This method is used by the kernel to request a permissions provider to get its permission offers.
77
*/
8-
WalletOfferOnchainPermission = 'wallet_offerOnchainPermission',
9-
10-
/**
11-
* This method is used by permissions provider to request the kernel to get the registered onchain permission offers.
12-
*/
13-
WalletGetRegisteredOnchainPermissionOffers = 'wallet_getRegisteredOnchainPermissionOffers',
8+
PermissionProviderGetPermissionOffers = 'permissionProvider_getPermissionOffers',
149

1510
/**
1611
* This method is used by the kernel to request a permissions provider to grant attenuated permissions to a site.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if (!process.env.SNAP_ENV) {
1111

1212
const config: SnapConfig = {
1313
bundler: 'webpack',
14-
input: resolve(__dirname, 'src/index.tsx'),
14+
input: resolve(__dirname, 'src/index.ts'),
1515
server: {
1616
port: 8081,
1717
},

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://github.com/MetaMask/snap-7715-permissions.git"
88
},
99
"source": {
10-
"shasum": "VvmzRf0CQohjyCGxQipja9d4Ghoq1q9w5kAJryTTw/8=",
10+
"shasum": "HdcS9CdcQhLxR01pW6ReMNEspjGyKj15XtUzagTt+Us=",
1111
"location": {
1212
"npm": {
1313
"filePath": "dist/bundle.js",
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { logger } from '@metamask/7715-permissions-shared/utils';
2+
import type {
3+
Json,
4+
JsonRpcParams,
5+
OnHomePageHandler,
6+
} from '@metamask/snaps-sdk';
7+
import { type OnRpcRequestHandler } from '@metamask/snaps-sdk';
8+
9+
import { createRegistry } from './registry';
10+
import { createRpcHandler } from './rpc/rpcHandler';
11+
import { RpcMethod } from './rpc/rpcMethod';
12+
import { createStateManager } from './stateManagement';
13+
import { HomePageContent } from './ui';
14+
15+
// set up dependencies
16+
const stateManager = createStateManager();
17+
const registry = createRegistry(snap);
18+
19+
const rpcHandler = createRpcHandler({
20+
stateManager,
21+
registry,
22+
snapsProvider: snap,
23+
});
24+
25+
// configure RPC methods bindings
26+
const boundRpcHandlers: {
27+
[RpcMethod: string]: (
28+
siteOrigin: string,
29+
params?: JsonRpcParams,
30+
) => Promise<Json>;
31+
} = {
32+
[RpcMethod.WalletGrantPermissions]:
33+
rpcHandler.grantPermissions.bind(rpcHandler),
34+
};
35+
36+
/**
37+
* Handle incoming JSON-RPC requests, sent through `wallet_invokeSnap`.
38+
*
39+
* @param args - The request handler args as object.
40+
* @param args.origin - The origin of the request, e.g., the website that
41+
* invoked the snap.
42+
* @param args.request - A validated JSON-RPC request object.
43+
* @returns The result of `snap_dialog`.
44+
* @throws If the request method is not valid for this snap.
45+
*/
46+
export const onRpcRequest: OnRpcRequestHandler = async ({
47+
origin,
48+
request,
49+
}) => {
50+
logger.info(
51+
`Custom request (origin="${origin}"):`,
52+
JSON.stringify(request, undefined, 2),
53+
);
54+
55+
const handler = boundRpcHandlers[request.method];
56+
57+
if (!handler) {
58+
throw new Error(`Method ${request.method} not found.`);
59+
}
60+
61+
const result = await handler(origin, request.params);
62+
63+
return result;
64+
};
65+
66+
/**
67+
* Handle the onHomePage event.
68+
* @returns The content to display on the home page.
69+
*/
70+
export const onHomePage: OnHomePageHandler = async () => {
71+
const { permissionOfferRegistry } = await stateManager.getState();
72+
return HomePageContent(permissionOfferRegistry);
73+
};

packages/permissions-kernel-snap/src/index.tsx

Lines changed: 0 additions & 166 deletions
This file was deleted.

0 commit comments

Comments
 (0)