Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@ export type CancelBackgroundEventMethodHooks = {
hasPermission: (permissionName: string) => boolean;
};

/**
* Cancel a background event created by
* [`snap_scheduleBackgroundEvent`](https://docs.metamask.io/snaps/reference/snaps-api/snap_schedulebackgroundevent).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these URLs guaranteed? I worry about them changing and we don't notice in this repo

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guaranteed in what sense? This is the format of the new URLs based on the schema. They could of course break if we make changes somewhere, but we should set up redirects in that case.

*
* @example
* ```ts
* const id = snap.request({
* method: 'snap_scheduleBackgroundEvent',
* params: {
* // ...
* },
* });
*
* // Later, when you want to cancel the background event:
* snap.request({
* method: 'snap_cancelBackgroundEvent',
* params: { id },
* });
* ```
*/
export const cancelBackgroundEventHandler = {
methodNames: [methodName] as const,
implementation: getCancelBackgroundEventImplementation,
Expand Down
12 changes: 11 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/clearState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,17 @@ const hookNames: MethodHooksObject<ClearStateHooks> = {
};

/**
* `snap_clearState` clears the state of the Snap.
* Clear the entire state of the Snap.
*
* @example
* ```ts
* await snap.request({
* method: 'snap_clearState',
* params: {
* encrypted: true, // Optional, defaults to true
* },
* });
* ```
*/
export const clearStateHandler = {
methodNames: [methodName] as const,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export type CloseWebSocketParameters = InferMatching<
>;

/**
* Handler for the `snap_closeWebSocket` method.
* Closes a WebSocket connection that was previously opened with
* [`snap_openWebSocket`](https://docs.metamask.io/snaps/reference/snaps-api/snap_openwebsocket).
*/
export const closeWebSocketHandler = {
methodNames: [methodName] as const,
Expand Down
21 changes: 21 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/createInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ export type CreateInterfaceMethodHooks = {
) => string;
};

/**
* Create an interactive interface for use in
* [interactive UI](https://docs.metamask.io/snaps/features/custom-ui/interactive-ui/).
*
* @example
* ```tsx
* import { Box, Heading, Text } from '@metamask/snaps-sdk/jsx';
*
* const interfaceId = snap.request({
* method: 'snap_createInterface',
* params: {
* ui: (
* <Box>
* <Heading>Example Interface</Heading>
* <Text>This is an example interface created by "snap_createInterface".</Text>
* </Box>
* ),
* },
* });
* ```
*/
export const createInterfaceHandler = {
methodNames: [methodName] as const,
implementation: getCreateInterfaceImplementation,
Expand Down
3 changes: 2 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/endTrace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ export type EndTraceParameters = InferMatching<
>;

/**
* Handler for the `snap_endTrace` method.
* End a performance trace in Sentry. This method is only available to
* preinstalled Snaps.
*
* @internal
*/
Expand Down
24 changes: 24 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/getBackgroundEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ export type GetBackgroundEventsMethodHooks = {
hasPermission: (permissionName: string) => boolean;
};

/**
* Get the scheduled background events for the Snap.
*
* @example
* ```ts
* const events = await snap.request({
* method: 'snap_getBackgroundEvents',
* });
* console.log(events);
* // [
* // {
* // id: 'event-1',
* // scheduledAt: 1672531200000,
* // snapId: 'npm:example-snap',
* // date: 1672531200000,
* // request: {
* // method: 'example_method',
* // params: { example: 'data' },
* // },
* // },
* // ...,
* // ]
* ```
*/
export const getBackgroundEventsHandler = {
methodNames: [methodName] as const,
implementation: getGetBackgroundEventsImplementation,
Expand Down
26 changes: 25 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/getClientStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,31 @@ const hookNames: MethodHooksObject<GetClientStatusHooks> = {
};

/**
* `snap_getClientStatus` returns useful information about the client running the snap.
* Get the status of the client running the Snap.
*
* @example
* ```ts
* import type { OnCronjobHandler } from '@metamask/snaps-sdk'
* import { MethodNotFoundError } from '@metamask/snaps-sdk'
*
* export const onCronjob: OnCronjobHandler = async ({ request }) => {
* switch (request.method) {
* case 'execute':
* // Find out if MetaMask is locked.
* const { locked } = await snap.request({
* method: 'snap_getClientStatus',
* })
*
* if (!locked) {
* // Do something that requires MetaMask to be unlocked, such as
* // accessing the encrypted state.
* }
*
* default:
* throw new MethodNotFoundError()
* }
* }
* ```
*/
export const getClientStatusHandler = {
methodNames: [methodName] as const,
Expand Down
26 changes: 26 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/getFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,32 @@ const hookNames: MethodHooksObject<GetFileHooks> = {
getSnapFile: true,
};

/**
* Gets a static file's content in UTF-8, Base64, or hexadecimal.
*
* The file must be specified in [the Snap's manifest file](https://docs.metamask.io/snaps/features/static-files/).
*
* @example
* ```json name="Manifest"
* {
* "source": {
* "files": ["./files/my-file.bin"]
* }
* }
* ```
* ```ts name="Usage"
* const contents = await snap.request({
* method: 'snap_getFile',
* params: {
* path: './files/myfile.bin',
* encoding: 'hex',
* },
* })
*
* // '0x...'
* console.log(contents)
* ```
*/
export const getFileHandler = {
methodNames: [methodName] as const,
implementation,
Expand Down
36 changes: 36 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/getInterfaceContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,42 @@ export type GetInterfaceContextMethodHooks = {
getInterfaceContext: (id: string) => InterfaceContext | null;
};

/**
* Get the context of an [interface](https://docs.metamask.io/snaps/features/custom-ui/interactive-ui/)
* created by [`snap_createInterface`](https://docs.metamask.io/snaps/reference/snaps-api/snap_createinterface).
*
* @example
* ```ts
* import { Box, Heading, Text } from '@metamask/snaps-sdk/jsx';
*
* const interfaceId = await snap.request({
* method: 'snap_createInterface',
* params: {
* ui: (
* <Box>
* <Heading>Hello, world!</Heading>
* <Text>Welcome to my Snap homepage!</Text>
* </Box>
* ),
* context: {
* key: 'value'
* }
* },
* })
*
* const context = await snap.request({
* method: 'snap_getInterfaceContext',
* params: {
* id: interfaceId,
* },
* })
*
* console.log(context)
* // {
* // key: 'value'
* // }
* ```
*/
export const getInterfaceContextHandler = {
methodNames: [methodName] as const,
implementation: getInterfaceContextImplementation,
Expand Down
14 changes: 14 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/getInterfaceState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ export type GetInterfaceStateMethodHooks = {
getInterfaceState: (id: string) => InterfaceState;
};

/**
* Get the form state of an [interface](https://docs.metamask.io/snaps/features/custom-ui/interactive-ui/)
* created by [`snap_createInterface`](https://docs.metamask.io/snaps/reference/snaps-api/snap_createinterface).
*
* @example
* ```ts
* const state = await snap.request({
* method: 'snap_getInterfaceState',
* params: {
* id: interfaceId,
* },
* });
* ```
*/
export const getInterfaceStateHandler = {
methodNames: [methodName] as const,
implementation: getGetInterfaceStateImplementation,
Expand Down
20 changes: 19 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/getSnaps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,25 @@ const hookNames: MethodHooksObject<GetSnapsHooks> = {
};

/**
* `wallet_getSnaps` gets the requester's permitted and installed Snaps.
* Get permitted and installed Snaps for the requesting origin.
*
* @example
* ```ts
* const snaps = await snap.request({
* method: 'wallet_getSnaps',
* });
* console.log(snaps);
* // {
* // 'npm:example-snap': {
* // id: 'npm:example-snap',
* // version: '1.0.0',
* // initialPermissions: { ... },
* // blocked: false,
* // enabled: true,
* // },
* // ...,
* // }
* ```
*/
export const getSnapsHandler = {
methodNames: [methodName] as const,
Expand Down
23 changes: 22 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/getState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,28 @@ const hookNames: MethodHooksObject<GetStateHooks> = {
};

/**
* `snap_getState` gets the state of the Snap.
* Get the state of the Snap, or a specific value within the state. By default,
* the data is automatically encrypted using a Snap-specific key and
* automatically decrypted when retrieved. You can set `encrypted` to `false` to
* use unencrypted storage (available when the client is locked).
*
* @example
* ```json name="Manifest"
* {
* "initialPermissions": {
* "snap_manageState": {}
* }
* }
* ```
* ```ts name="Usage"
* const state = await snap.request({
* method: 'snap_getState',
* params: {
* key: 'some.nested.value', // Optional, defaults to entire state
* encrypted: true, // Optional, defaults to `true`
* },
* });
* ```
*/
export const getStateHandler = {
methodNames: [methodName] as const,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export type GetWebSocketsMethodHooks = {
};

/**
* Handler for the `snap_getWebSockets` method.
* Get the connected WebSockets for the Snap.
*/
export const getWebSocketsHandler = {
methodNames: [methodName] as const,
Expand Down
7 changes: 6 additions & 1 deletion packages/snaps-rpc-methods/src/permitted/invokeKeyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ const hookNames: MethodHooksObject<InvokeKeyringHooks> = {
};

/**
* `wallet_invokeKeyring` gets the requester's permitted and installed Snaps.
* Invoke a keyring method of a Snap. This calls the `onKeyringRequest` handler
* of the Snap.
*
* The Snap must be installed and the dapp must have permission to communicate
* with the Snap, or the request is rejected. The dapp can install the Snap and
* request permission to communicate with it using [`wallet_requestSnaps`](https://docs.metamask.io/snaps/reference/snaps-api/wallet_requestsnaps).
*/
export const invokeKeyringHandler = {
methodNames: [methodName] as const,
Expand Down
28 changes: 25 additions & 3 deletions packages/snaps-rpc-methods/src/permitted/invokeSnapSugar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,33 @@ import type { InvokeSnapParams, InvokeSnapResult } from '@metamask/snaps-sdk';
import type { JsonRpcRequest, PendingJsonRpcResponse } from '@metamask/utils';
import { isObject } from '@metamask/utils';

/**
* `wallet_invokeSnap` attempts to invoke an RPC method of the specified Snap.
*/
const methodName = 'wallet_invokeSnap';

/**
* Invoke a method of a Snap, designated by the `snapId` parameter, with a
* JSON-RPC request specified in the `request` parameter. This is effectively a
* wrapper around [`wallet_snap`](https://docs.metamask.io/snaps/reference/snaps-api/wallet_snap)
* that allows for more convenient invocation of Snap methods without needing to
* specify the full `wallet_snap` parameters.
*
* The Snap must be installed and the dapp must have permission to communicate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically Snaps can call this too, not sure if we need to explain that too much though 😄

* with the Snap, or the request is rejected. The dapp can install the Snap and
* request permission to communicate with it using [`wallet_requestSnaps`](https://docs.metamask.io/snaps/reference/snaps-api/wallet_requestsnaps).
*
* @example
* ```ts
* const result = await snap.request({
* method: 'wallet_invokeSnap',
* params: {
* snapId: 'npm:@metamask/example-snap',
* request: {
* method: 'someMethod',
* params: { some: 'params' },
* },
* },
* });
* ```
*/
export const invokeSnapSugarHandler = {
methodNames: [methodName] as const,
implementation: invokeSnapSugar,
Expand Down
10 changes: 10 additions & 0 deletions packages/snaps-rpc-methods/src/permitted/listEntropySources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ export type ListEntropySourcesHooks = {
getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;
};

/**
* Get a list of entropy sources available to the Snap. The requesting origin
* must have at least one of the following permissions to access entropy source
* metadata:
*
* - `snap_getBip32Entropy`
* - `snap_getBip32PublicKey`
* - `snap_getBip44Entropy`
* - `snap_getEntropy`
*/
export const listEntropySourcesHandler = {
methodNames: [methodName] as const,
implementation: listEntropySourcesImplementation,
Expand Down
Loading
Loading