Skip to content

Commit 2fe6af6

Browse files
Add Snaps documentation for MetaMask Extension 12.6 updates (#1715)
* Add optional context param to snap_updateInterface This closes #1673 * Update API examples for interfaces to use JSX * Add Snaps Avatar component This closes #1701 * Update Address component This closes #1711 * Add 'valid' to avatar prop * Add min, max, and step props to Snaps Input component This fixes #1702 * Add size prop for Snaps Heading component This fixes #1703 * Add metamask scheme for Snaps Link component This fixes #1704 * Update Snaps Row component to include Link as a possible child Fixes #1705 * Add Address component to children of Snaps Link component Fixes #1706 * Update What's New Also fix a couple missing indents * Correct the metamask scheme URL for Snap home page Also clarify that it leads to the Snap's settings if it does not have a home page, and what to expect when testing. * Line breaks * Correct information for local metamask: URLs * edits --------- Co-authored-by: Alexandra Tran <[email protected]>
1 parent 6c7fe31 commit 2fe6af6

File tree

3 files changed

+150
-51
lines changed

3 files changed

+150
-51
lines changed

docs/whats-new.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ of the [MetaMask developer page](https://metamask.io/developer/).
1111

1212
## November 2024
1313

14+
- Updated Snaps [Custom UI documentation](/snaps/features/custom-ui/) for MetaMask Extension version 12.6.
15+
([#1715](https://github.com/MetaMask/metamask-docs/pull/1715))
1416
- Added tutorial for
1517
[creating a simple Starknet dapp](/wallet/how-to/use-non-evm-networks/starknet/create-a-simple-starknet-dapp).
1618
([#1656](https://github.com/MetaMask/metamask-docs/pull/1656))
1719
- Documented Snaps [`Card`](/snaps/features/custom-ui/#card) and [`Section`](/snaps/features/custom-ui/#section) UI components.
18-
([#1707](https://github.com/MetaMask/metamask-docs/pull/1707) and
19-
[#1700](https://github.com/MetaMask/metamask-docs/pull/1700))
20+
([#1707](https://github.com/MetaMask/metamask-docs/pull/1707)) ([#1700](https://github.com/MetaMask/metamask-docs/pull/1700))
2021

2122
## October 2024
2223

snaps/features/custom-ui/index.md

Lines changed: 124 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ description: Display custom user interface components using JSX.
33
sidebar_position: 4
44
---
55

6+
import Tabs from "@theme/Tabs";
7+
import TabItem from "@theme/TabItem";
8+
69
# Custom UI
710

811
You can display custom user interface (UI) JSX components using the
@@ -15,7 +18,9 @@ implementing the following features:
1518
- [Signature insights](../signature-insights.md)
1619

1720
:::note
18-
JSX is supported in the MetaMask extension and Flask version 12 and later. New UI components will be added as JSX components. The previous function-based library is deprecated.
21+
JSX is supported in the MetaMask extension and Flask version 12 and later.
22+
New UI components will be added as JSX components.
23+
The previous function-based library is deprecated.
1924
:::
2025

2126
To use custom UI, first install [`@metamask/snaps-sdk`](https://github.com/MetaMask/snaps/tree/main/packages/snaps-sdk)
@@ -27,7 +32,8 @@ yarn add @metamask/snaps-sdk
2732

2833
Then, whenever you're required to return a custom UI component, import the components from the
2934
SDK at `@metamask/snaps-sdk/jsx` and build your UI with them.
30-
For example, to display a [`Box`](#box) using [`snap_dialog`](../../reference/snaps-api.md#snap_dialog):
35+
For example, to display a [`Box`](#box) using
36+
[`snap_dialog`](../../reference/snaps-api.md#snap_dialog):
3137

3238
```javascript title="index.jsx"
3339
import { Box, Heading, Text } from "@metamask/snaps-sdk/jsx";
@@ -56,12 +62,21 @@ The following custom UI components are available:
5662

5763
### `Address`
5864

59-
Outputs a formatted text field for an Ethereum address.
60-
The address is automatically displayed with a jazzicon and truncated value.
61-
Hovering the address shows the full value in a tooltip.
65+
Outputs a formatted text field for a blockchain address.
66+
The address is automatically displayed with a [Jazzicon](https://www.npmjs.com/package/@metamask/jazzicon)
67+
and truncated value.
68+
Hovering over the address shows the full value in a tooltip.
69+
70+
#### Props
71+
72+
- `address`: `string` - A valid Ethereum address, starting with `0x`, or a valid
73+
[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
6274

6375
#### Example
6476

77+
<Tabs>
78+
<TabItem value="Ethereum address">
79+
6580
```javascript title="index.jsx"
6681
import { Box, Heading, Address } from "@metamask/snaps-sdk/jsx";
6782

@@ -88,6 +103,59 @@ await snap.request({
88103
</div>
89104
</div>
90105
106+
</TabItem>
107+
<TabItem value="CAIP-10 address">
108+
109+
```javascript title="index.jsx"
110+
import { Box, Heading, Address } from "@metamask/snaps-sdk/jsx";
111+
112+
await snap.request({
113+
method: "snap_dialog",
114+
params: {
115+
type: "alert",
116+
content: (
117+
<Box>
118+
<Heading>The following is an Ethereum address</Heading>
119+
<Address address="eip155:1:0x1234567890123456789012345678901234567890" />
120+
<Heading>The following is a Bitcoin address</Heading>
121+
<Address address="bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6" />
122+
</Box>
123+
),
124+
},
125+
});
126+
```
127+
128+
</TabItem>
129+
</Tabs>
130+
131+
### `Avatar`
132+
133+
Outputs a [Jazzicon](https://www.npmjs.com/package/@metamask/jazzicon) for an address.
134+
135+
:::note
136+
MetaMask automatically calculates checksums for EVM addresses (`eip155:`).
137+
Addresses for other namespaces are not validated; you should validate them in your Snap.
138+
:::
139+
140+
#### Props
141+
142+
- `address`: `string` - A valid [CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) address.
143+
144+
#### Example
145+
146+
```js
147+
export const onHomePage: OnHomePageHandler = async () => {
148+
return {
149+
content: (
150+
<Box>
151+
<Avatar address="eip155:1:0x1234567890123456789012345678901234567890" />
152+
<Avatar address="bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6" />
153+
</Box>
154+
),
155+
};
156+
};
157+
```
158+
91159
### `Bold`
92160
93161
Outputs bold text.
@@ -166,8 +234,8 @@ For use in [interactive UI](interactive-ui.md).
166234
- `type` - (Optional) The type of button.
167235
Possible values are `"button"` and `"submit"`.
168236
The default is `"button"`.
169-
- `name`: `string` - (Optional) The name that will be sent to [`onUserInput`](../../reference/entry-points.md#onuserinput)
170-
when a user selects the button.
237+
- `name`: `string` - (Optional) The name that will be sent to
238+
[`onUserInput`](../../reference/entry-points.md#onuserinput) when a user selects the button.
171239
- `variant` - (Optional) Determines the appearance of the button.
172240
Possible values are `"primary"` and `"destructive"`.
173241
The default is `"primary"`.
@@ -209,7 +277,8 @@ Outputs a card component which is used to display values in a card structure.
209277
210278
:::info
211279
Unlike many `Card` components from other UI libraries, the Snaps `Card` does not have any shape.
212-
It is only used for layout. To give a shape to a `Card`, wrap it in a [`Section`](#section) component.
280+
It is only used for layout. To give a shape to a `Card`, wrap it in a [`Section`](#section)
281+
component.
213282
:::
214283
215284
#### Props
@@ -305,7 +374,8 @@ Outputs a read-only text field with a copy-to-clipboard shortcut.
305374
#### Props
306375
307376
- `value`: `string` - The value to copy when the user clicks on the copyable element.
308-
- `sensitive`: `boolean` - (Optional) Indicates whether the value is sensitive. If `true`, the value will be hidden when the user is not interacting with the copyable element.
377+
- `sensitive`: `boolean` - (Optional) Indicates whether the value is sensitive. If `true`, the
378+
value will be hidden when the user is not interacting with the copyable element.
309379
310380
#### Example
311381
@@ -412,9 +482,11 @@ Outputs a form field, wrapping an element to give it a label and optional error.
412482
#### Props
413483
414484
- `label`: `string` - The label for the wrapped element.
415-
- `error`: `string` - (Optional) Any error for the wrapped element. Setting this changes the style of the wrapped element to show that there is an error.
485+
- `error`: `string` - (Optional) Any error for the wrapped element. Setting this changes the style
486+
of the wrapped element to show that there is an error.
416487
- `children` - The element to be wrapped.
417-
This can be a [`Dropdown`](#dropdown), [`Input`](#input), [`Selector`](#selector), or [`RadioGroup`](#radiogroup) component.
488+
This can be a [`Dropdown`](#dropdown), [`Input`](#input), [`Selector`](#selector), or
489+
[`RadioGroup`](#radiogroup) component.
418490
419491
#### Example
420492
@@ -508,8 +580,8 @@ Outputs a form for use in [interactive UI](interactive-ui.md).
508580
509581
#### Props
510582
511-
- `name`: `string` - The name that will be sent to [`onUserInput`](../../reference/entry-points.md#onuserinput)
512-
when a user interacts with the form.
583+
- `name`: `string` - The name that will be sent to
584+
[`onUserInput`](../../reference/entry-points.md#onuserinput) when a user interacts with the form.
513585
- `children`: `array` - An array of [`Input`](#input) or [`Button`](#button) components.
514586
515587
#### Example
@@ -549,6 +621,11 @@ await snap.request({
549621
Outputs a heading.
550622
This is useful for [`Box`](#box) titles.
551623
624+
#### Props
625+
626+
- `size`: `string` - (Optional) The size of the heading. Possible values are `"sm"`, `"md"`, and
627+
`"lg"`. The default is `"sm"`.
628+
552629
#### Example
553630
554631
```javascript title="index.jsx"
@@ -616,7 +693,8 @@ This component takes an inline SVG.
616693
It does not support remote URLs.
617694
618695
You can import SVG, PNG, and JPEG files using an import statement.
619-
These files are automatically imported as SVG strings, so you can pass them directly to the `Image` component.
696+
These files are automatically imported as SVG strings, so you can pass them directly to the
697+
`Image` component.
620698
621699
The SVG is rendered within an `<img>` tag, which prevents JavaScript or interaction events from
622700
being supported.
@@ -667,13 +745,20 @@ Outputs an input component for use in [interactive UI](interactive-ui.md).
667745
#### Props
668746
669747
- `name`: `string` - The name that will be used as a key to the event sent to
670-
[`onUserInput`](../../reference/entry-points.md#onuserinput) when the containing form is submitted.
748+
[`onUserInput`](../../reference/entry-points.md#onuserinput) when the containing form is
749+
submitted.
671750
- `type` - (Optional) The type of input.
672751
Possible values are `"text"`, `"number"`, and `"password"`.
673752
The default is `"text"`.
674753
- `placeholder`: `string` - (Optional) The text displayed when the input is empty.
675754
- `label`: `string` - (Optional) The text displayed alongside the input to label it.
676755
- `value`: `string` - (Optional) The default value of the input.
756+
- `min`: `string` - (Optional) The minimum value of the input field. Only applicable to the input
757+
type `"number"`.
758+
- `max`: `string` - (Optional) The maximum value of the input field. Only applicable to the input
759+
type `"number"`.
760+
- `step`: `string` - (Optional) The step value of the input field. Only applicable to the input
761+
type `"number"`.
677762
678763
#### Example
679764
@@ -738,8 +823,28 @@ Outputs a clickable link.
738823
739824
#### Props
740825
741-
- `href`: `string` - The URL to point to. Supported schemes are `https:` and `mailto:`. `http:` is not allowed.
742-
- `children`: `Array<string | Bold | Italic>` - The link text.
826+
- `href`: `string` - The URL to point to. Supported schemes are `https:`, `mailto:`, and
827+
`metamask:`. `http:` is not allowed.
828+
- `children`: `Array<string | Bold | Italic | Address>` - The link text, or an
829+
[`Address`](#address).
830+
831+
#### About `metamask:` URLs
832+
833+
A Snap can link to the following screens using the `metamask:` scheme:
834+
835+
- `metamask://client/` - Leads to the main screen of MetaMask.
836+
- `metamask://snap/[Snap ID]/home/` - Leads to the Snap's
837+
[home page](../custom-ui/home-pages.md), or the Snap's settings page if it does not have a home
838+
page. Valid Snap IDs are npm IDs beginning with `npm:`, such as
839+
`metamask://snap/npm:@consensys/starknet-snap/home`, or `local:`, such as
840+
`metamask://snap/local:http://localhost:8080/home`. Consider using
841+
[environment variables](../../how-to/use-environment-variables.md) so you can have different
842+
Snap IDs for local testing and production.
843+
844+
:::warning
845+
MetaMask will throw an error if the URL is not valid or if the URL leads to a Snap that is not
846+
installed.
847+
:::
743848

744849
#### Example
745850

@@ -813,8 +918,8 @@ Outputs a row with a label and value, which can be used for key-value data.
813918
- `variant` - (Optional) The variant of the label.
814919
Possible values are `"default"`, `"error"`, and `"warning"`.
815920
The default is `"default"`.
816-
- `children` - The value of the row, which can be a [`Text`](#text), [`Image`](#image), or
817-
[`Address`](#address) component.
921+
- `children` - The value of the row, which can be a [`Text`](#text), [`Image`](#image),
922+
[`Address`](#address), or [`Link`](#link) component.
818923

819924
#### Example
820925

snaps/reference/snaps-api.md

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -914,13 +914,12 @@ The interface's ID to be used in [`snap_dialog`](#snap_dialog), returned from
914914
const interfaceId = await snap.request({
915915
method: "snap_createInterface",
916916
params: {
917-
ui: panel([
918-
heading("Interactive interface"),
919-
button({
920-
value: "Click me",
921-
name: "interactive-button",
922-
}),
923-
]),
917+
ui: (
918+
<Box>
919+
<Heading>Interactive interface</Heading>
920+
<Button name="interactive-button">Click me</Button>
921+
</Box>
922+
)
924923
},
925924
})
926925

@@ -956,26 +955,16 @@ An object where each top-level property can be one of the following:
956955
const interfaceId = await snap.request({
957956
method: "snap_createInterface",
958957
params: {
959-
ui: panel([
960-
heading("Interactive UI Example Snap"),
961-
// A top-level input.
962-
input({
963-
name: "top-level-input",
964-
placeholder: "Enter something",
965-
}),
966-
// A top-level form...
967-
form({
968-
name: "example-form",
969-
children: [
970-
// ...with a nested input.
971-
input({
972-
name: "nested-input",
973-
placeholder: "Enter something",
974-
}),
975-
button("Submit", ButtonType.Submit, "submit"),
976-
],
977-
}),
978-
]),
958+
ui: (
959+
<Box>
960+
<Heading>Interactive UI Example Snap</Heading>
961+
<Input name="top-level-input" placeholder="Enter something"/>
962+
<Form name="example-form">
963+
<Input name="nested-input" placeholder="Enter something"/>
964+
<Button type="submit">Submit</Button>
965+
</Form>
966+
</Box>
967+
)
979968
},
980969
})
981970

@@ -1025,6 +1014,7 @@ An object containing:
10251014
- `id` - The ID of the interface to be updated, usually received in the
10261015
[`onUserInput`](./entry-points.md#onuserinput) entry point.
10271016
- `ui` - The [custom UI](../features/custom-ui/index.md) to create.
1017+
- `context` - (Optional) A custom context object that will be passed to [`onUserInput`](./entry-points.md#onuserinput) when the user interacts with the interface. Passing this parameter will update the context object for the interface.
10281018

10291019
#### Example
10301020

@@ -1036,9 +1026,12 @@ export function onUserInput({ id, event }) {
10361026
method: "snap_updateInterface",
10371027
params: {
10381028
id,
1039-
ui: panel([
1040-
heading("New interface"),
1041-
]),
1029+
ui: (
1030+
<Box>
1031+
<Heading>New interface</Heading>
1032+
<Text>This interface has been updated</Text>
1033+
</Box>
1034+
)
10421035
},
10431036
});
10441037
};

0 commit comments

Comments
 (0)