Skip to content

Commit 0dc7ae6

Browse files
committed
Move onSettingsPage example to Preinstalled example snap
1 parent e1621d8 commit 0dc7ae6

File tree

26 files changed

+143
-712
lines changed

26 files changed

+143
-712
lines changed

packages/examples/README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,6 @@ The following is a list of the snaps in this directory.
6666
- [**`packages/notifications`**](./packages/notifications): This snap
6767
demonstrates how to use the `snap_notify` method to display notifications to
6868
the user, either as a MetaMask notification or as a desktop notification.
69-
- [**`packages/settings-page`**](./packages/settings-page):
70-
This snap demonstrates how to use `endowment:page-settings` permission,
71-
showing a settings page to the user.
7269
- [**`packages/transaction-insights`**](./packages/transaction-insights):
7370
This snap demonstrates how to use `endowment:transaction-insights` permission,
7471
and provide transaction insights to the user.
@@ -90,7 +87,8 @@ The following is a list of the snaps in this directory.
9087
how the Snaps platform handles errors thrown by snaps.
9188
- [**`packages/preinstalled`**](./packages/preinstalled): This snap demonstrates
9289
preinstalled snaps, i.e., snaps that are installed in the MetaMask extension
93-
by default.
90+
by default. It also demonstrates the use of the `endowment:page-settings` permission,
91+
showing a settings page to the user.
9492
- [**`packages/send-flow`**](./packages/send-flow): This snap demonstrates
9593
a simple send flow using custom UI.
9694
- [**`packages/wasm`**](./packages/wasm): This snap demonstrates how

packages/examples/packages/preinstalled/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,26 @@ MetaMask extension by default.
55

66
> [!NOTE]
77
> Preinstalled Snaps are primarily for internal use by MetaMask.
8+
9+
This snap also demonstrates how to use the `endowment:page-settings` permission to show a settings page that leverages custom UI components.
10+
11+
> [!NOTE]
12+
> This endowment is initially restricted to preinstalled snaps only.
13+
14+
## Snap manifest
15+
16+
The manifest of this snap includes the `endowment:page-settings` permission:
17+
18+
```json
19+
{
20+
"initialPermissions": {
21+
"endowment:page-settings": {}
22+
}
23+
}
24+
```
25+
26+
This permission does not require any additional configuration.
27+
28+
## Snap usage
29+
30+
This snap exposes an `onSettingsPage` handler, which returns the UI to be shown.

packages/examples/packages/preinstalled/snap.manifest.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"url": "https://github.com/MetaMask/snaps.git"
88
},
99
"source": {
10-
"shasum": "WF9+BfnWRznf3otVkb8p0M38ULIIPywefZdHiAAk7jM=",
10+
"shasum": "uDEC4wnc/rEN1OKqXidpOvejRN3h3dR85cvQLnLmJB8=",
1111
"location": {
1212
"npm": {
1313
"filePath": "dist/bundle.js",
@@ -20,7 +20,9 @@
2020
"endowment:rpc": {
2121
"dapps": true
2222
},
23-
"snap_dialog": {}
23+
"snap_dialog": {},
24+
"endowment:page-settings": {},
25+
"snap_manageState": {}
2426
},
2527
"platformVersion": "6.13.0",
2628
"manifestVersion": "0.1"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './dialog';
22
export * from './result';
3+
export * from './settings';

packages/examples/packages/settings-page/src/components/SettingsPage.tsx renamed to packages/examples/packages/preinstalled/src/components/settings.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
type SnapComponent,
1111
} from '@metamask/snaps-sdk/jsx';
1212

13-
export type SettingsPageProps = {
13+
export type SettingsProps = {
1414
setting1?: boolean;
1515
setting2?: 'option1' | 'option2';
1616
setting3?: 'option1' | 'option2';
@@ -25,7 +25,7 @@ export type SettingsPageProps = {
2525
* @param param.setting3 - The third setting.
2626
* @returns The settings page component.
2727
*/
28-
export const SettingsPage: SnapComponent<SettingsPageProps> = ({
28+
export const Settings: SnapComponent<SettingsProps> = ({
2929
setting1,
3030
setting2,
3131
setting3,

packages/examples/packages/preinstalled/src/index.tsx

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
1-
import { MethodNotFoundError } from '@metamask/snaps-sdk';
1+
import { MethodNotFoundError, UserInputEventType } from '@metamask/snaps-sdk';
22
import type {
33
OnRpcRequestHandler,
4+
OnSettingsPageHandler,
45
OnUserInputHandler,
56
} from '@metamask/snaps-sdk';
67

7-
import { Dialog, Result } from './components';
8+
import { Dialog, Result, Settings } from './components';
9+
10+
type SnapState = {
11+
setting1?: boolean;
12+
setting2?: 'option1' | 'option2';
13+
setting3?: 'option1' | 'option2';
14+
};
815

916
/**
1017
* Handle incoming JSON-RPC requests from the dapp, sent through the
1118
* `wallet_invokeSnap` method. This handler handles a single method:
1219
*
1320
* - `showDialog` - Opens a dialog.
21+
* - `getSettings`: Get the settings state from the snap state.
1422
*
1523
* @param params - The request parameters.
1624
* @param params.request - The JSON-RPC request object.
1725
* @returns The JSON-RPC response.
1826
* @see https://docs.metamask.io/snaps/reference/exports/#onrpcrequest
1927
* @see https://docs.metamask.io/snaps/reference/rpc-api/#wallet_invokesnap
20-
* @see https://docs.metamask.io/snaps/reference/rpc-api/#snap_notify
28+
* @see https://docs.metamask.io/snaps/reference/snaps-api/#snap_managestate
2129
*/
2230
export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
2331
switch (request.method) {
@@ -29,18 +37,62 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
2937
},
3038
});
3139

40+
case 'getSettings':
41+
return await snap.request({
42+
method: 'snap_manageState',
43+
params: {
44+
operation: 'get',
45+
encrypted: false,
46+
},
47+
});
48+
3249
default:
3350
// eslint-disable-next-line @typescript-eslint/no-throw-literal
3451
throw new MethodNotFoundError({ method: request.method });
3552
}
3653
};
3754

55+
/**
56+
* Handle incoming settings page requests from the MetaMask clients.
57+
*
58+
* @returns A static panel rendered with custom UI.
59+
* @see https://docs.metamask.io/snaps/reference/exports/#onsettingspage
60+
*/
61+
export const onSettingsPage: OnSettingsPageHandler = async () => {
62+
const state: SnapState | null = await snap.request({
63+
method: 'snap_manageState',
64+
params: {
65+
operation: 'get',
66+
encrypted: false,
67+
},
68+
});
69+
70+
return {
71+
content: (
72+
<Settings
73+
setting1={state?.setting1}
74+
setting2={state?.setting2}
75+
setting3={state?.setting3}
76+
/>
77+
),
78+
};
79+
};
80+
81+
/**
82+
* Handle incoming user events coming from the MetaMask clients open interfaces.
83+
*
84+
* @param params - The event parameters.
85+
* @param params.event - The event object containing the event type, name and value.
86+
* @param params.id - The unique identifier of the open interface.
87+
* @param params.context - The context object containing the current state of the open interface.
88+
* @see https://docs.metamask.io/snaps/reference/exports/#onuserinput
89+
*/
3890
export const onUserInput: OnUserInputHandler = async ({
3991
event,
4092
id,
4193
context,
4294
}) => {
43-
if (event.type === 'ButtonClickEvent') {
95+
if (event.type === UserInputEventType.ButtonClickEvent) {
4496
if (event.name === 'cancel') {
4597
await snap.request({
4698
method: 'snap_resolveInterface',
@@ -62,7 +114,7 @@ export const onUserInput: OnUserInputHandler = async ({
62114
}
63115
}
64116

65-
if (event.type === 'FormSubmitEvent') {
117+
if (event.type === UserInputEventType.FormSubmitEvent) {
66118
if (event.name === 'form') {
67119
const value = String(event.value['custom-input']);
68120
await snap.request({
@@ -75,4 +127,31 @@ export const onUserInput: OnUserInputHandler = async ({
75127
});
76128
}
77129
}
130+
131+
if (
132+
event.type === UserInputEventType.InputChangeEvent &&
133+
(event.name === 'setting1' ||
134+
event.name === 'setting2' ||
135+
event.name === 'setting3')
136+
) {
137+
const state = await snap.request({
138+
method: 'snap_manageState',
139+
params: {
140+
operation: 'get',
141+
encrypted: false,
142+
},
143+
});
144+
145+
await snap.request({
146+
method: 'snap_manageState',
147+
params: {
148+
operation: 'update',
149+
encrypted: false,
150+
newState: {
151+
...state,
152+
[event.name]: event.value,
153+
},
154+
},
155+
});
156+
}
78157
};

packages/examples/packages/settings-page/.depcheckrc.json

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

packages/examples/packages/settings-page/.eslintrc.js

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

packages/examples/packages/settings-page/CHANGELOG.md

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

0 commit comments

Comments
 (0)