@metamask/snaps-utils 11.6.2 → 11.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -1
- package/dist/handlers/home-page.d.cts +6 -0
- package/dist/handlers/home-page.d.cts.map +1 -1
- package/dist/handlers/home-page.d.mts +6 -0
- package/dist/handlers/home-page.d.mts.map +1 -1
- package/dist/handlers/settings-page.d.cts +2 -0
- package/dist/handlers/settings-page.d.cts.map +1 -1
- package/dist/handlers/settings-page.d.mts +2 -0
- package/dist/handlers/settings-page.d.mts.map +1 -1
- package/dist/handlers/signature.d.cts +2 -0
- package/dist/handlers/signature.d.cts.map +1 -1
- package/dist/handlers/signature.d.mts +2 -0
- package/dist/handlers/signature.d.mts.map +1 -1
- package/dist/handlers/transaction.d.cts +6 -0
- package/dist/handlers/transaction.d.cts.map +1 -1
- package/dist/handlers/transaction.d.mts +6 -0
- package/dist/handlers/transaction.d.mts.map +1 -1
- package/dist/types.cjs +3 -16
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +11 -19
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +11 -19
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +3 -16
- package/dist/types.mjs.map +1 -1
- package/dist/ui.cjs +9 -1
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.d.cts +3 -1
- package/dist/ui.d.cts.map +1 -1
- package/dist/ui.d.mts +3 -1
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +9 -1
- package/dist/ui.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [11.7.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add support for external images ([#3769](https://github.com/MetaMask/snaps/pull/3769))
|
|
15
|
+
|
|
16
|
+
## [11.6.3]
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Bump `@metamask/snaps-registry` from `3.3.0` to `4.0.0` ([#3770](https://github.com/MetaMask/snaps/pull/3770))
|
|
21
|
+
|
|
10
22
|
## [11.6.2]
|
|
11
23
|
|
|
12
24
|
### Changed
|
|
@@ -730,7 +742,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
730
742
|
- The version of the package no longer needs to match the version of all other
|
|
731
743
|
MetaMask Snaps packages.
|
|
732
744
|
|
|
733
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.
|
|
745
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.7.0...HEAD
|
|
746
|
+
[11.7.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.6.3...@metamask/snaps-utils@11.7.0
|
|
747
|
+
[11.6.3]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.6.2...@metamask/snaps-utils@11.6.3
|
|
734
748
|
[11.6.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.6.1...@metamask/snaps-utils@11.6.2
|
|
735
749
|
[11.6.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.6.0...@metamask/snaps-utils@11.6.1
|
|
736
750
|
[11.6.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@11.5.0...@metamask/snaps-utils@11.6.0
|
|
@@ -71,6 +71,8 @@ export declare const OnHomePageResponseWithContentStruct: import("@metamask/supe
|
|
|
71
71
|
src: string;
|
|
72
72
|
alt?: string | undefined;
|
|
73
73
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
74
|
+
height?: number | undefined;
|
|
75
|
+
width?: number | undefined;
|
|
74
76
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
75
77
|
name: string;
|
|
76
78
|
value?: string | undefined;
|
|
@@ -157,6 +159,8 @@ export declare const OnHomePageResponseWithContentStruct: import("@metamask/supe
|
|
|
157
159
|
src: string;
|
|
158
160
|
alt?: string | undefined;
|
|
159
161
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
162
|
+
height?: number | undefined;
|
|
163
|
+
width?: number | undefined;
|
|
160
164
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
161
165
|
name: string;
|
|
162
166
|
value?: string | undefined;
|
|
@@ -249,6 +253,8 @@ export declare const OnHomePageResponseStruct: import("@metamask/superstruct").S
|
|
|
249
253
|
src: string;
|
|
250
254
|
alt?: string | undefined;
|
|
251
255
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
256
|
+
height?: number | undefined;
|
|
257
|
+
width?: number | undefined;
|
|
252
258
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
253
259
|
name: string;
|
|
254
260
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home-page.d.cts","sourceRoot":"","sources":["../../src/handlers/home-page.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mCAAmC
|
|
1
|
+
{"version":3,"file":"home-page.d.cts","sourceRoot":"","sources":["../../src/handlers/home-page.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;EAEzC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAGnC,CAAC"}
|
|
@@ -71,6 +71,8 @@ export declare const OnHomePageResponseWithContentStruct: import("@metamask/supe
|
|
|
71
71
|
src: string;
|
|
72
72
|
alt?: string | undefined;
|
|
73
73
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
74
|
+
height?: number | undefined;
|
|
75
|
+
width?: number | undefined;
|
|
74
76
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
75
77
|
name: string;
|
|
76
78
|
value?: string | undefined;
|
|
@@ -157,6 +159,8 @@ export declare const OnHomePageResponseWithContentStruct: import("@metamask/supe
|
|
|
157
159
|
src: string;
|
|
158
160
|
alt?: string | undefined;
|
|
159
161
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
162
|
+
height?: number | undefined;
|
|
163
|
+
width?: number | undefined;
|
|
160
164
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
161
165
|
name: string;
|
|
162
166
|
value?: string | undefined;
|
|
@@ -249,6 +253,8 @@ export declare const OnHomePageResponseStruct: import("@metamask/superstruct").S
|
|
|
249
253
|
src: string;
|
|
250
254
|
alt?: string | undefined;
|
|
251
255
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
256
|
+
height?: number | undefined;
|
|
257
|
+
width?: number | undefined;
|
|
252
258
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
253
259
|
name: string;
|
|
254
260
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"home-page.d.mts","sourceRoot":"","sources":["../../src/handlers/home-page.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mCAAmC
|
|
1
|
+
{"version":3,"file":"home-page.d.mts","sourceRoot":"","sources":["../../src/handlers/home-page.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,8BAA8B;;;;EAEzC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAGnC,CAAC"}
|
|
@@ -71,6 +71,8 @@ export declare const OnSettingsPageResponseStruct: import("@metamask/superstruct
|
|
|
71
71
|
src: string;
|
|
72
72
|
alt?: string | undefined;
|
|
73
73
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
74
|
+
height?: number | undefined;
|
|
75
|
+
width?: number | undefined;
|
|
74
76
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
75
77
|
name: string;
|
|
76
78
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-page.d.cts","sourceRoot":"","sources":["../../src/handlers/settings-page.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"settings-page.d.cts","sourceRoot":"","sources":["../../src/handlers/settings-page.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAA2B,CAAC"}
|
|
@@ -71,6 +71,8 @@ export declare const OnSettingsPageResponseStruct: import("@metamask/superstruct
|
|
|
71
71
|
src: string;
|
|
72
72
|
alt?: string | undefined;
|
|
73
73
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
74
|
+
height?: number | undefined;
|
|
75
|
+
width?: number | undefined;
|
|
74
76
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
75
77
|
name: string;
|
|
76
78
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-page.d.mts","sourceRoot":"","sources":["../../src/handlers/settings-page.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B
|
|
1
|
+
{"version":3,"file":"settings-page.d.mts","sourceRoot":"","sources":["../../src/handlers/settings-page.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAA2B,CAAC"}
|
|
@@ -74,6 +74,8 @@ export declare const OnSignatureResponseStruct: import("@metamask/superstruct").
|
|
|
74
74
|
src: string;
|
|
75
75
|
alt?: string | undefined;
|
|
76
76
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
77
|
+
height?: number | undefined;
|
|
78
|
+
width?: number | undefined;
|
|
77
79
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
78
80
|
name: string;
|
|
79
81
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature.d.cts","sourceRoot":"","sources":["../../src/handlers/signature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"signature.d.cts","sourceRoot":"","sources":["../../src/handlers/signature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA8B,CAAC"}
|
|
@@ -74,6 +74,8 @@ export declare const OnSignatureResponseStruct: import("@metamask/superstruct").
|
|
|
74
74
|
src: string;
|
|
75
75
|
alt?: string | undefined;
|
|
76
76
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
77
|
+
height?: number | undefined;
|
|
78
|
+
width?: number | undefined;
|
|
77
79
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
78
80
|
name: string;
|
|
79
81
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signature.d.mts","sourceRoot":"","sources":["../../src/handlers/signature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"signature.d.mts","sourceRoot":"","sources":["../../src/handlers/signature.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAA8B,CAAC"}
|
|
@@ -84,6 +84,8 @@ export declare const OnTransactionResponseWithContentStruct: import("@metamask/s
|
|
|
84
84
|
src: string;
|
|
85
85
|
alt?: string | undefined;
|
|
86
86
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
87
|
+
height?: number | undefined;
|
|
88
|
+
width?: number | undefined;
|
|
87
89
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
88
90
|
name: string;
|
|
89
91
|
value?: string | undefined;
|
|
@@ -171,6 +173,8 @@ export declare const OnTransactionResponseWithContentStruct: import("@metamask/s
|
|
|
171
173
|
src: string;
|
|
172
174
|
alt?: string | undefined;
|
|
173
175
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
176
|
+
height?: number | undefined;
|
|
177
|
+
width?: number | undefined;
|
|
174
178
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
175
179
|
name: string;
|
|
176
180
|
value?: string | undefined;
|
|
@@ -262,6 +266,8 @@ export declare const OnTransactionResponseStruct: import("@metamask/superstruct"
|
|
|
262
266
|
src: string;
|
|
263
267
|
alt?: string | undefined;
|
|
264
268
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
269
|
+
height?: number | undefined;
|
|
270
|
+
width?: number | undefined;
|
|
265
271
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
266
272
|
name: string;
|
|
267
273
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/handlers/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,aAAa,EAAE,4BAA4B;AAW9E,eAAO,MAAM,mCAAmC;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;EAK7C,CAAC;AAEF,eAAO,MAAM,sCAAsC
|
|
1
|
+
{"version":3,"file":"transaction.d.cts","sourceRoot":"","sources":["../../src/handlers/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,aAAa,EAAE,4BAA4B;AAW9E,eAAO,MAAM,mCAAmC;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;EAK7C,CAAC;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKlD,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAKvC,CAAC"}
|
|
@@ -84,6 +84,8 @@ export declare const OnTransactionResponseWithContentStruct: import("@metamask/s
|
|
|
84
84
|
src: string;
|
|
85
85
|
alt?: string | undefined;
|
|
86
86
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
87
|
+
height?: number | undefined;
|
|
88
|
+
width?: number | undefined;
|
|
87
89
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
88
90
|
name: string;
|
|
89
91
|
value?: string | undefined;
|
|
@@ -171,6 +173,8 @@ export declare const OnTransactionResponseWithContentStruct: import("@metamask/s
|
|
|
171
173
|
src: string;
|
|
172
174
|
alt?: string | undefined;
|
|
173
175
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
176
|
+
height?: number | undefined;
|
|
177
|
+
width?: number | undefined;
|
|
174
178
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
175
179
|
name: string;
|
|
176
180
|
value?: string | undefined;
|
|
@@ -262,6 +266,8 @@ export declare const OnTransactionResponseStruct: import("@metamask/superstruct"
|
|
|
262
266
|
src: string;
|
|
263
267
|
alt?: string | undefined;
|
|
264
268
|
borderRadius?: import("@metamask/snaps-sdk/jsx").BorderRadius;
|
|
269
|
+
height?: number | undefined;
|
|
270
|
+
width?: number | undefined;
|
|
265
271
|
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ButtonProps, "Button"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CheckboxProps, "Checkbox"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DateTimePickerProps, "DateTimePicker"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").InputProps, "Input"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").DropdownProps, "Dropdown"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
266
272
|
name: string;
|
|
267
273
|
value?: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/handlers/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,aAAa,EAAE,4BAA4B;AAW9E,eAAO,MAAM,mCAAmC;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;EAK7C,CAAC;AAEF,eAAO,MAAM,sCAAsC
|
|
1
|
+
{"version":3,"file":"transaction.d.mts","sourceRoot":"","sources":["../../src/handlers/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,aAAa,EAAE,4BAA4B;AAW9E,eAAO,MAAM,mCAAmC;;;;EAE9C,CAAC;AAEH,eAAO,MAAM,iCAAiC;;;;;;EAK7C,CAAC;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKlD,CAAC;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAKvC,CAAC"}
|
package/dist/types.cjs
CHANGED
|
@@ -37,21 +37,8 @@ var SNAP_STREAM_NAMES;
|
|
|
37
37
|
SNAP_STREAM_NAMES["JSON_RPC"] = "jsonRpc";
|
|
38
38
|
SNAP_STREAM_NAMES["COMMAND"] = "command";
|
|
39
39
|
})(SNAP_STREAM_NAMES || (exports.SNAP_STREAM_NAMES = SNAP_STREAM_NAMES = {}));
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const url = new URL(value);
|
|
43
|
-
const UrlStruct = (0, superstruct_1.type)(opts);
|
|
44
|
-
(0, superstruct_1.assert)(url, UrlStruct);
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
if (error instanceof superstruct_1.StructError) {
|
|
49
|
-
return (0, snaps_sdk_1.getErrorMessage)(error);
|
|
50
|
-
}
|
|
51
|
-
return `Expected URL, got "${value.toString()}"`;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
exports.uri = uri;
|
|
40
|
+
var snaps_sdk_2 = require("@metamask/snaps-sdk");
|
|
41
|
+
Object.defineProperty(exports, "uri", { enumerable: true, get: function () { return snaps_sdk_2.uri; } });
|
|
55
42
|
/**
|
|
56
43
|
* Returns whether a given value is a valid URL.
|
|
57
44
|
*
|
|
@@ -60,7 +47,7 @@ exports.uri = uri;
|
|
|
60
47
|
* @returns Whether `url` is valid URL or not.
|
|
61
48
|
*/
|
|
62
49
|
function isValidUrl(url, opts = {}) {
|
|
63
|
-
return (0, superstruct_1.is)(url, (0,
|
|
50
|
+
return (0, superstruct_1.is)(url, (0, snaps_sdk_1.uri)(opts));
|
|
64
51
|
}
|
|
65
52
|
exports.isValidUrl = isValidUrl;
|
|
66
53
|
// redefining here to avoid circular dependency
|
package/dist/types.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.cjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AACA,mDAA0C;AAC1C,uDAAyE;AAGzE,2CAA+D;AAQ/D,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,gDAA4B,CAAA;IAC5B,mDAA+B,CAAA;AACjC,CAAC,EAHW,gBAAgB,gCAAhB,gBAAgB,QAG3B;AAEY,QAAA,UAAU,GAAG,IAAA,kBAAI,EAC5B,IAAA,qBAAa,EACX,WAAW,EACX,6DAA6D,CAC9D,EACD,CAAC,EACD,GAAG,CACJ,CAAC;AAEF,2EAA2E;AAC3E,sBAAsB;AACT,QAAA,wBAAwB,GAAG,IAAA,kBAAI,EAAC;IAC3C,OAAO,EAAE,qBAAa;IACtB,IAAI,EAAE,kBAAU;IAChB,IAAI,EAAE,IAAA,sBAAQ,EAAC,IAAA,kBAAI,EAAC,IAAA,oBAAM,GAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3C,UAAU,EAAE,IAAA,sBAAQ,EAClB,IAAA,kBAAI,EAAC;QACH,IAAI,EAAE,IAAA,kBAAI,EAAC,IAAA,oBAAM,GAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;QACjC,GAAG,EAAE,IAAA,kBAAI,EAAC,IAAA,oBAAM,GAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;KACjC,CAAC,CACH;CACF,CAAC,CAAC;AAsCH;;GAEG;AACH,yDAAyD;AACzD,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,8BAAY,CAAA;IACZ,kCAAgB,CAAA;AAClB,CAAC,EAHW,cAAc,8BAAd,cAAc,QAGzB;AACD,wDAAwD;AAExD,yDAAyD;AACzD,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,yCAAoB,CAAA;IACpB,wCAAmB,CAAA;AACrB,CAAC,EAHW,iBAAiB,iCAAjB,iBAAiB,QAG5B;AAYD,iDAA0C;AAAjC,gGAAA,GAAG,OAAA;AAEZ;;;;;;GAMG;AACH,SAAgB,UAAU,CACxB,GAAY,EACZ,OAAwB,EAAE;IAE1B,OAAO,IAAA,gBAAE,EAAC,GAAG,EAAE,IAAA,eAAG,EAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,CAAC;AALD,gCAKC;AAED,+CAA+C;AAClC,QAAA,0BAA0B,GAAG,aAAa,CAAC","sourcesContent":["import type { UriOptions } from '@metamask/snaps-sdk';\nimport { uri } from '@metamask/snaps-sdk';\nimport { is, optional, size, string, type } from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { definePattern, VersionStruct } from '@metamask/utils';\n\nimport type { SnapCaveatType } from './caveats';\nimport type { SnapFunctionExports, SnapRpcHookArgs } from './handlers';\nimport type { LocalizationFile } from './localization';\nimport type { SnapManifest } from './manifest';\nimport type { VirtualFile } from './virtual-file';\n\nexport enum NpmSnapFileNames {\n PackageJson = 'package.json',\n Manifest = 'snap.manifest.json',\n}\n\nexport const NameStruct = size(\n definePattern(\n 'Snap Name',\n /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/u,\n ),\n 1,\n 214,\n);\n\n// Note we use `type` instead of `object` here, because the latter does not\n// allow unknown keys.\nexport const NpmSnapPackageJsonStruct = type({\n version: VersionStruct,\n name: NameStruct,\n main: optional(size(string(), 1, Infinity)),\n repository: optional(\n type({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n});\n\nexport type NpmSnapPackageJson = Infer<typeof NpmSnapPackageJsonStruct> &\n Record<string, any>;\n\n/**\n * An object for storing parsed but unvalidated Snap file contents.\n */\nexport type UnvalidatedSnapFiles = {\n manifest?: VirtualFile<Json>;\n packageJson?: VirtualFile<Json>;\n sourceCode?: VirtualFile;\n svgIcon?: VirtualFile;\n auxiliaryFiles: VirtualFile[];\n localizationFiles: VirtualFile[];\n};\n\n/**\n * An object for storing the contents of Snap files that have passed JSON\n * Schema validation, or are non-empty if they are strings.\n */\nexport type SnapFiles = {\n manifest: VirtualFile<SnapManifest>;\n packageJson: VirtualFile<NpmSnapPackageJson>;\n sourceCode: VirtualFile;\n svgIcon?: VirtualFile;\n auxiliaryFiles: VirtualFile[];\n localizationFiles: VirtualFile<LocalizationFile>[];\n};\n\n/**\n * A subset of snap files extracted from a fetched snap.\n */\nexport type FetchedSnapFiles = Pick<\n SnapFiles,\n 'manifest' | 'sourceCode' | 'svgIcon' | 'auxiliaryFiles' | 'localizationFiles'\n>;\n\n/**\n * The possible prefixes for snap ids.\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nexport enum SnapIdPrefixes {\n npm = 'npm:',\n local = 'local:',\n}\n/* eslint-enable @typescript-eslint/naming-convention */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport enum SNAP_STREAM_NAMES {\n JSON_RPC = 'jsonRpc',\n COMMAND = 'command',\n}\n/* eslint-enable @typescript-eslint/naming-convention */\n\n// The snap is the callee\nexport type SnapRpcHook = (options: SnapRpcHookArgs) => Promise<unknown>;\n\ntype ObjectParameters<\n Type extends Record<string, (...args: any[]) => unknown>,\n> = Parameters<Type[keyof Type]>;\n\nexport type SnapExportsParameters = ObjectParameters<SnapFunctionExports>;\n\nexport { uri } from '@metamask/snaps-sdk';\n\n/**\n * Returns whether a given value is a valid URL.\n *\n * @param url - The value to check.\n * @param opts - Optional constraints for url checking.\n * @returns Whether `url` is valid URL or not.\n */\nexport function isValidUrl(\n url: unknown,\n opts: UriOptions<any> = {},\n): url is string {\n return is(url, uri(opts));\n}\n\n// redefining here to avoid circular dependency\nexport const WALLET_SNAP_PERMISSION_KEY = 'wallet_snap';\n\nexport type SnapsPermissionRequest = {\n [WALLET_SNAP_PERMISSION_KEY]: {\n caveats: [\n {\n type: SnapCaveatType.SnapIds;\n value: Record<string, Json>;\n },\n ];\n };\n};\n"]}
|
package/dist/types.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UriOptions } from "@metamask/snaps-sdk";
|
|
2
|
+
import type { Infer } from "@metamask/superstruct";
|
|
2
3
|
import type { Json } from "@metamask/utils";
|
|
3
4
|
import type { SnapCaveatType } from "./caveats.cjs";
|
|
4
5
|
import type { SnapFunctionExports, SnapRpcHookArgs } from "./handlers/index.cjs";
|
|
@@ -9,8 +10,8 @@ export declare enum NpmSnapFileNames {
|
|
|
9
10
|
PackageJson = "package.json",
|
|
10
11
|
Manifest = "snap.manifest.json"
|
|
11
12
|
}
|
|
12
|
-
export declare const NameStruct: Struct<string, null>;
|
|
13
|
-
export declare const NpmSnapPackageJsonStruct: Struct<{
|
|
13
|
+
export declare const NameStruct: import("@metamask/superstruct").Struct<string, null>;
|
|
14
|
+
export declare const NpmSnapPackageJsonStruct: import("@metamask/superstruct").Struct<{
|
|
14
15
|
name: string;
|
|
15
16
|
version: import("@metamask/utils").SemVerVersion;
|
|
16
17
|
main?: string | undefined;
|
|
@@ -19,15 +20,15 @@ export declare const NpmSnapPackageJsonStruct: Struct<{
|
|
|
19
20
|
url: string;
|
|
20
21
|
} | undefined;
|
|
21
22
|
}, {
|
|
22
|
-
version: Struct<import("@metamask/utils").SemVerVersion, null>;
|
|
23
|
-
name: Struct<string, null>;
|
|
24
|
-
main: Struct<string | undefined, null>;
|
|
25
|
-
repository: Struct<{
|
|
23
|
+
version: import("@metamask/superstruct").Struct<import("@metamask/utils").SemVerVersion, null>;
|
|
24
|
+
name: import("@metamask/superstruct").Struct<string, null>;
|
|
25
|
+
main: import("@metamask/superstruct").Struct<string | undefined, null>;
|
|
26
|
+
repository: import("@metamask/superstruct").Struct<{
|
|
26
27
|
type: string;
|
|
27
28
|
url: string;
|
|
28
29
|
} | undefined, {
|
|
29
|
-
type: Struct<string, null>;
|
|
30
|
-
url: Struct<string, null>;
|
|
30
|
+
type: import("@metamask/superstruct").Struct<string, null>;
|
|
31
|
+
url: import("@metamask/superstruct").Struct<string, null>;
|
|
31
32
|
}>;
|
|
32
33
|
}>;
|
|
33
34
|
export type NpmSnapPackageJson = Infer<typeof NpmSnapPackageJsonStruct> & Record<string, any>;
|
|
@@ -72,15 +73,7 @@ export declare enum SNAP_STREAM_NAMES {
|
|
|
72
73
|
export type SnapRpcHook = (options: SnapRpcHookArgs) => Promise<unknown>;
|
|
73
74
|
type ObjectParameters<Type extends Record<string, (...args: any[]) => unknown>> = Parameters<Type[keyof Type]>;
|
|
74
75
|
export type SnapExportsParameters = ObjectParameters<SnapFunctionExports>;
|
|
75
|
-
|
|
76
|
-
protocol?: Struct<Type>;
|
|
77
|
-
hash?: Struct<Type>;
|
|
78
|
-
port?: Struct<Type>;
|
|
79
|
-
hostname?: Struct<Type>;
|
|
80
|
-
pathname?: Struct<Type>;
|
|
81
|
-
search?: Struct<Type>;
|
|
82
|
-
};
|
|
83
|
-
export declare const uri: (opts?: UriOptions<any>) => Struct<string, null>;
|
|
76
|
+
export { uri } from "@metamask/snaps-sdk";
|
|
84
77
|
/**
|
|
85
78
|
* Returns whether a given value is a valid URL.
|
|
86
79
|
*
|
|
@@ -100,5 +93,4 @@ export type SnapsPermissionRequest = {
|
|
|
100
93
|
];
|
|
101
94
|
};
|
|
102
95
|
};
|
|
103
|
-
export {};
|
|
104
96
|
//# sourceMappingURL=types.d.cts.map
|
package/dist/types.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.cts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,4BAA4B;AAGtD,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAkB;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,6BAAmB;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAAuB;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,6BAAmB;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,iCAAuB;AAElD,oBAAY,gBAAgB;IAC1B,WAAW,iBAAiB;IAC5B,QAAQ,uBAAuB;CAChC;AAED,eAAO,MAAM,UAAU,sDAOtB,CAAC;AAIF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;EAUnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,wBAAwB,CAAC,GACrE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,iBAAiB,EAAE,WAAW,EAAE,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC7C,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,iBAAiB,EAAE,WAAW,CAAC,gBAAgB,CAAC,EAAE,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,SAAS,EACT,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,mBAAmB,CAC/E,CAAC;AAEF;;GAEG;AAEH,oBAAY,cAAc;IACxB,GAAG,SAAS;IACZ,KAAK,WAAW;CACjB;AAID,oBAAY,iBAAiB;IAC3B,QAAQ,YAAY;IACpB,OAAO,YAAY;CACpB;AAID,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEzE,KAAK,gBAAgB,CACnB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,IACtD,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;AAEjC,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;AAE1E,OAAO,EAAE,GAAG,EAAE,4BAA4B;AAE1C;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,UAAU,CAAC,GAAG,CAAM,GACzB,GAAG,IAAI,MAAM,CAEf;AAGD,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AAExD,MAAM,MAAM,sBAAsB,GAAG;IACnC,CAAC,0BAA0B,CAAC,EAAE;QAC5B,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC;gBAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;aAC7B;SACF,CAAC;KACH,CAAC;CACH,CAAC"}
|
package/dist/types.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { UriOptions } from "@metamask/snaps-sdk";
|
|
2
|
+
import type { Infer } from "@metamask/superstruct";
|
|
2
3
|
import type { Json } from "@metamask/utils";
|
|
3
4
|
import type { SnapCaveatType } from "./caveats.mjs";
|
|
4
5
|
import type { SnapFunctionExports, SnapRpcHookArgs } from "./handlers/index.mjs";
|
|
@@ -9,8 +10,8 @@ export declare enum NpmSnapFileNames {
|
|
|
9
10
|
PackageJson = "package.json",
|
|
10
11
|
Manifest = "snap.manifest.json"
|
|
11
12
|
}
|
|
12
|
-
export declare const NameStruct: Struct<string, null>;
|
|
13
|
-
export declare const NpmSnapPackageJsonStruct: Struct<{
|
|
13
|
+
export declare const NameStruct: import("@metamask/superstruct").Struct<string, null>;
|
|
14
|
+
export declare const NpmSnapPackageJsonStruct: import("@metamask/superstruct").Struct<{
|
|
14
15
|
name: string;
|
|
15
16
|
version: import("@metamask/utils").SemVerVersion;
|
|
16
17
|
main?: string | undefined;
|
|
@@ -19,15 +20,15 @@ export declare const NpmSnapPackageJsonStruct: Struct<{
|
|
|
19
20
|
url: string;
|
|
20
21
|
} | undefined;
|
|
21
22
|
}, {
|
|
22
|
-
version: Struct<import("@metamask/utils").SemVerVersion, null>;
|
|
23
|
-
name: Struct<string, null>;
|
|
24
|
-
main: Struct<string | undefined, null>;
|
|
25
|
-
repository: Struct<{
|
|
23
|
+
version: import("@metamask/superstruct").Struct<import("@metamask/utils").SemVerVersion, null>;
|
|
24
|
+
name: import("@metamask/superstruct").Struct<string, null>;
|
|
25
|
+
main: import("@metamask/superstruct").Struct<string | undefined, null>;
|
|
26
|
+
repository: import("@metamask/superstruct").Struct<{
|
|
26
27
|
type: string;
|
|
27
28
|
url: string;
|
|
28
29
|
} | undefined, {
|
|
29
|
-
type: Struct<string, null>;
|
|
30
|
-
url: Struct<string, null>;
|
|
30
|
+
type: import("@metamask/superstruct").Struct<string, null>;
|
|
31
|
+
url: import("@metamask/superstruct").Struct<string, null>;
|
|
31
32
|
}>;
|
|
32
33
|
}>;
|
|
33
34
|
export type NpmSnapPackageJson = Infer<typeof NpmSnapPackageJsonStruct> & Record<string, any>;
|
|
@@ -72,15 +73,7 @@ export declare enum SNAP_STREAM_NAMES {
|
|
|
72
73
|
export type SnapRpcHook = (options: SnapRpcHookArgs) => Promise<unknown>;
|
|
73
74
|
type ObjectParameters<Type extends Record<string, (...args: any[]) => unknown>> = Parameters<Type[keyof Type]>;
|
|
74
75
|
export type SnapExportsParameters = ObjectParameters<SnapFunctionExports>;
|
|
75
|
-
|
|
76
|
-
protocol?: Struct<Type>;
|
|
77
|
-
hash?: Struct<Type>;
|
|
78
|
-
port?: Struct<Type>;
|
|
79
|
-
hostname?: Struct<Type>;
|
|
80
|
-
pathname?: Struct<Type>;
|
|
81
|
-
search?: Struct<Type>;
|
|
82
|
-
};
|
|
83
|
-
export declare const uri: (opts?: UriOptions<any>) => Struct<string, null>;
|
|
76
|
+
export { uri } from "@metamask/snaps-sdk";
|
|
84
77
|
/**
|
|
85
78
|
* Returns whether a given value is a valid URL.
|
|
86
79
|
*
|
|
@@ -100,5 +93,4 @@ export type SnapsPermissionRequest = {
|
|
|
100
93
|
];
|
|
101
94
|
};
|
|
102
95
|
};
|
|
103
|
-
export {};
|
|
104
96
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,4BAA4B;AAGtD,OAAO,KAAK,EAAE,KAAK,EAAE,8BAA8B;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAG5C,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAkB;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,6BAAmB;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAAuB;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,6BAAmB;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,iCAAuB;AAElD,oBAAY,gBAAgB;IAC1B,WAAW,iBAAiB;IAC5B,QAAQ,uBAAuB;CAChC;AAED,eAAO,MAAM,UAAU,sDAOtB,CAAC;AAIF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;EAUnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,wBAAwB,CAAC,GACrE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEtB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,iBAAiB,EAAE,WAAW,EAAE,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACpC,WAAW,EAAE,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAC7C,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,cAAc,EAAE,WAAW,EAAE,CAAC;IAC9B,iBAAiB,EAAE,WAAW,CAAC,gBAAgB,CAAC,EAAE,CAAC;CACpD,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,IAAI,CACjC,SAAS,EACT,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,gBAAgB,GAAG,mBAAmB,CAC/E,CAAC;AAEF;;GAEG;AAEH,oBAAY,cAAc;IACxB,GAAG,SAAS;IACZ,KAAK,WAAW;CACjB;AAID,oBAAY,iBAAiB;IAC3B,QAAQ,YAAY;IACpB,OAAO,YAAY;CACpB;AAID,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEzE,KAAK,gBAAgB,CACnB,IAAI,SAAS,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,IACtD,UAAU,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;AAEjC,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,mBAAmB,CAAC,CAAC;AAE1E,OAAO,EAAE,GAAG,EAAE,4BAA4B;AAE1C;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,UAAU,CAAC,GAAG,CAAM,GACzB,GAAG,IAAI,MAAM,CAEf;AAGD,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AAExD,MAAM,MAAM,sBAAsB,GAAG;IACnC,CAAC,0BAA0B,CAAC,EAAE;QAC5B,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,cAAc,CAAC,OAAO,CAAC;gBAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;aAC7B;SACF,CAAC;KACH,CAAC;CACH,CAAC"}
|
package/dist/types.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { is, optional,
|
|
1
|
+
import { uri } from "@metamask/snaps-sdk";
|
|
2
|
+
import { is, optional, size, string, type } from "@metamask/superstruct";
|
|
3
3
|
import { definePattern, VersionStruct } from "@metamask/utils";
|
|
4
4
|
export var NpmSnapFileNames;
|
|
5
5
|
(function (NpmSnapFileNames) {
|
|
@@ -34,20 +34,7 @@ export var SNAP_STREAM_NAMES;
|
|
|
34
34
|
SNAP_STREAM_NAMES["JSON_RPC"] = "jsonRpc";
|
|
35
35
|
SNAP_STREAM_NAMES["COMMAND"] = "command";
|
|
36
36
|
})(SNAP_STREAM_NAMES || (SNAP_STREAM_NAMES = {}));
|
|
37
|
-
export
|
|
38
|
-
try {
|
|
39
|
-
const url = new URL(value);
|
|
40
|
-
const UrlStruct = type(opts);
|
|
41
|
-
assertSuperstruct(url, UrlStruct);
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
if (error instanceof StructError) {
|
|
46
|
-
return getErrorMessage(error);
|
|
47
|
-
}
|
|
48
|
-
return `Expected URL, got "${value.toString()}"`;
|
|
49
|
-
}
|
|
50
|
-
});
|
|
37
|
+
export { uri } from "@metamask/snaps-sdk";
|
|
51
38
|
/**
|
|
52
39
|
* Returns whether a given value is a valid URL.
|
|
53
40
|
*
|
package/dist/types.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,4BAA4B;AAC1C,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B;AAGzE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB;AAQ/D,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,gDAA4B,CAAA;IAC5B,mDAA+B,CAAA;AACjC,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAC5B,aAAa,CACX,WAAW,EACX,6DAA6D,CAC9D,EACD,CAAC,EACD,GAAG,CACJ,CAAC;AAEF,2EAA2E;AAC3E,sBAAsB;AACtB,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;IAC3C,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3C,UAAU,EAAE,QAAQ,CAClB,IAAI,CAAC;QACH,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;QACjC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;KACjC,CAAC,CACH;CACF,CAAC,CAAC;AAsCH;;GAEG;AACH,yDAAyD;AACzD,MAAM,CAAN,IAAY,cAGX;AAHD,WAAY,cAAc;IACxB,8BAAY,CAAA;IACZ,kCAAgB,CAAA;AAClB,CAAC,EAHW,cAAc,KAAd,cAAc,QAGzB;AACD,wDAAwD;AAExD,yDAAyD;AACzD,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,yCAAoB,CAAA;IACpB,wCAAmB,CAAA;AACrB,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B;AAYD,OAAO,EAAE,GAAG,EAAE,4BAA4B;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,GAAY,EACZ,OAAwB,EAAE;IAE1B,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,+CAA+C;AAC/C,MAAM,CAAC,MAAM,0BAA0B,GAAG,aAAa,CAAC","sourcesContent":["import type { UriOptions } from '@metamask/snaps-sdk';\nimport { uri } from '@metamask/snaps-sdk';\nimport { is, optional, size, string, type } from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\nimport type { Json } from '@metamask/utils';\nimport { definePattern, VersionStruct } from '@metamask/utils';\n\nimport type { SnapCaveatType } from './caveats';\nimport type { SnapFunctionExports, SnapRpcHookArgs } from './handlers';\nimport type { LocalizationFile } from './localization';\nimport type { SnapManifest } from './manifest';\nimport type { VirtualFile } from './virtual-file';\n\nexport enum NpmSnapFileNames {\n PackageJson = 'package.json',\n Manifest = 'snap.manifest.json',\n}\n\nexport const NameStruct = size(\n definePattern(\n 'Snap Name',\n /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\\/)?[a-z0-9-~][a-z0-9-._~]*$/u,\n ),\n 1,\n 214,\n);\n\n// Note we use `type` instead of `object` here, because the latter does not\n// allow unknown keys.\nexport const NpmSnapPackageJsonStruct = type({\n version: VersionStruct,\n name: NameStruct,\n main: optional(size(string(), 1, Infinity)),\n repository: optional(\n type({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n});\n\nexport type NpmSnapPackageJson = Infer<typeof NpmSnapPackageJsonStruct> &\n Record<string, any>;\n\n/**\n * An object for storing parsed but unvalidated Snap file contents.\n */\nexport type UnvalidatedSnapFiles = {\n manifest?: VirtualFile<Json>;\n packageJson?: VirtualFile<Json>;\n sourceCode?: VirtualFile;\n svgIcon?: VirtualFile;\n auxiliaryFiles: VirtualFile[];\n localizationFiles: VirtualFile[];\n};\n\n/**\n * An object for storing the contents of Snap files that have passed JSON\n * Schema validation, or are non-empty if they are strings.\n */\nexport type SnapFiles = {\n manifest: VirtualFile<SnapManifest>;\n packageJson: VirtualFile<NpmSnapPackageJson>;\n sourceCode: VirtualFile;\n svgIcon?: VirtualFile;\n auxiliaryFiles: VirtualFile[];\n localizationFiles: VirtualFile<LocalizationFile>[];\n};\n\n/**\n * A subset of snap files extracted from a fetched snap.\n */\nexport type FetchedSnapFiles = Pick<\n SnapFiles,\n 'manifest' | 'sourceCode' | 'svgIcon' | 'auxiliaryFiles' | 'localizationFiles'\n>;\n\n/**\n * The possible prefixes for snap ids.\n */\n/* eslint-disable @typescript-eslint/naming-convention */\nexport enum SnapIdPrefixes {\n npm = 'npm:',\n local = 'local:',\n}\n/* eslint-enable @typescript-eslint/naming-convention */\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport enum SNAP_STREAM_NAMES {\n JSON_RPC = 'jsonRpc',\n COMMAND = 'command',\n}\n/* eslint-enable @typescript-eslint/naming-convention */\n\n// The snap is the callee\nexport type SnapRpcHook = (options: SnapRpcHookArgs) => Promise<unknown>;\n\ntype ObjectParameters<\n Type extends Record<string, (...args: any[]) => unknown>,\n> = Parameters<Type[keyof Type]>;\n\nexport type SnapExportsParameters = ObjectParameters<SnapFunctionExports>;\n\nexport { uri } from '@metamask/snaps-sdk';\n\n/**\n * Returns whether a given value is a valid URL.\n *\n * @param url - The value to check.\n * @param opts - Optional constraints for url checking.\n * @returns Whether `url` is valid URL or not.\n */\nexport function isValidUrl(\n url: unknown,\n opts: UriOptions<any> = {},\n): url is string {\n return is(url, uri(opts));\n}\n\n// redefining here to avoid circular dependency\nexport const WALLET_SNAP_PERMISSION_KEY = 'wallet_snap';\n\nexport type SnapsPermissionRequest = {\n [WALLET_SNAP_PERMISSION_KEY]: {\n caveats: [\n {\n type: SnapCaveatType.SnapIds;\n value: Record<string, Json>;\n },\n ];\n };\n};\n"]}
|
package/dist/ui.cjs
CHANGED
|
@@ -6,6 +6,7 @@ const snaps_sdk_1 = require("@metamask/snaps-sdk");
|
|
|
6
6
|
const jsx_1 = require("@metamask/snaps-sdk/jsx");
|
|
7
7
|
const utils_1 = require("@metamask/utils");
|
|
8
8
|
const marked_1 = require("marked");
|
|
9
|
+
const types_1 = require("./types.cjs");
|
|
9
10
|
const url_1 = require("./url.cjs");
|
|
10
11
|
const MAX_TEXT_LENGTH = 50000; // 50 kb
|
|
11
12
|
const ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];
|
|
@@ -276,8 +277,9 @@ exports.validateAssetSelector = validateAssetSelector;
|
|
|
276
277
|
* phishing list.
|
|
277
278
|
* @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.
|
|
278
279
|
* @param hooks.getAccountByAddress - The function that returns an account by address.
|
|
280
|
+
* @param hooks.hasPermission - A function that checks whether the Snap has a given permission.
|
|
279
281
|
*/
|
|
280
|
-
function validateJsxElements(node, { isOnPhishingList, getSnap, getAccountByAddress, }) {
|
|
282
|
+
function validateJsxElements(node, { isOnPhishingList, getSnap, getAccountByAddress, hasPermission, }) {
|
|
281
283
|
walkJsx(node, (childNode) => {
|
|
282
284
|
switch (childNode.type) {
|
|
283
285
|
case 'Link':
|
|
@@ -289,6 +291,12 @@ function validateJsxElements(node, { isOnPhishingList, getSnap, getAccountByAddr
|
|
|
289
291
|
// that is already validated in the struct.
|
|
290
292
|
childNode.props.addresses[0], getAccountByAddress);
|
|
291
293
|
break;
|
|
294
|
+
case 'Image': {
|
|
295
|
+
const { src } = childNode.props;
|
|
296
|
+
const isUrl = (0, types_1.isValidUrl)(src);
|
|
297
|
+
(0, utils_1.assert)(!isUrl || (isUrl && hasPermission('endowment:network-access')), 'Using external images is only permitted with the `endowment:network-access` permission.');
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
292
300
|
default:
|
|
293
301
|
break;
|
|
294
302
|
}
|
package/dist/ui.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.cjs","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { CaipAccountId, Component } from '@metamask/snaps-sdk';\nimport { NodeType } from '@metamask/snaps-sdk';\nimport type {\n BoldChildren,\n GenericSnapElement,\n ItalicChildren,\n JSXElement,\n LinkElement,\n Nestable,\n RowChildren,\n SnapNode,\n StandardFormattingElement,\n TextChildren,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n Italic,\n Link,\n Bold,\n Row,\n Text,\n Field,\n Image,\n Input,\n Heading,\n Form,\n Divider,\n Spinner,\n Copyable,\n Box,\n Button,\n Address,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n assert,\n assertExhaustive,\n hasProperty,\n isPlainObject,\n} from '@metamask/utils';\nimport { lexer, walkTokens } from 'marked';\nimport type { Token, Tokens } from 'marked';\n\nimport type { InternalAccount } from './account';\nimport type { Snap } from './snaps';\nimport { parseMetaMaskUrl } from './url';\n\nconst MAX_TEXT_LENGTH = 50_000; // 50 kb\nconst ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];\n\n/**\n * Get the button variant from a legacy button component variant.\n *\n * @param variant - The legacy button component variant.\n * @returns The button variant.\n */\nfunction getButtonVariant(variant?: 'primary' | 'secondary' | undefined) {\n switch (variant) {\n case 'primary':\n return 'primary';\n case 'secondary':\n return 'destructive';\n default:\n return undefined;\n }\n}\n\n/**\n * Get the children of a JSX element. If there is only one child, the child is\n * returned directly. Otherwise, the children are returned as an array.\n *\n * @param elements - The JSX elements.\n * @returns The child or children.\n */\nfunction getChildren<Type>(elements: Type[]) {\n if (elements.length === 1) {\n return elements[0];\n }\n\n return elements;\n}\n\n/**\n * Get the text of a link token.\n *\n * @param token - The link token.\n * @returns The text of the link token.\n */\nfunction getLinkText(token: Tokens.Link | Tokens.Generic) {\n if (token.tokens && token.tokens.length > 0) {\n return getChildren(token.tokens.flatMap(getTextChildFromToken));\n }\n\n return token.href;\n}\n\n/**\n * Get the text child from a list of markdown tokens.\n *\n * @param tokens - The markdown tokens.\n * @returns The text child.\n */\nfunction getTextChildFromTokens(tokens: Token[]) {\n return getChildren(tokens.flatMap(getTextChildFromToken));\n}\n\n/**\n * Get the text child from a markdown token.\n *\n * @param token - The markdown token.\n * @returns The text child.\n */\nfunction getTextChildFromToken(token: Token): TextChildren {\n switch (token.type) {\n case 'link': {\n return <Link href={token.href} children={getLinkText(token)} />;\n }\n\n case 'text':\n return token.text;\n\n case 'strong':\n return (\n <Bold>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as BoldChildren\n }\n </Bold>\n );\n\n case 'em':\n return (\n <Italic>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as ItalicChildren\n }\n </Italic>\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get all text children from a markdown string.\n *\n * @param value - The markdown string.\n * @returns The text children.\n */\nexport function getTextChildren(\n value: string,\n): (string | StandardFormattingElement | LinkElement)[] {\n const rootTokens = lexer(value, { gfm: false });\n const children: (string | StandardFormattingElement | LinkElement | null)[] =\n [];\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(rootTokens, (token) => {\n if (token.type === 'paragraph') {\n if (children.length > 0) {\n children.push('\\n\\n');\n }\n\n const { tokens } = token as Tokens.Paragraph;\n // We do not need to consider nesting deeper than 1 level here and we can therefore cast.\n children.push(\n ...(tokens.flatMap(getTextChildFromToken) as (\n | string\n | StandardFormattingElement\n | LinkElement\n | null\n )[]),\n );\n }\n });\n\n return children.filter((child) => child !== null) as (\n | string\n | StandardFormattingElement\n | LinkElement\n )[];\n}\n\n/**\n * Validate the text size of a component. The text size is the total length of\n * all text in the component.\n *\n * @param component - The component to validate.\n * @throws An error if the text size exceeds the maximum allowed size.\n */\nfunction validateComponentTextSize(component: Component) {\n const textSize = getTotalTextLength(component);\n assert(\n textSize <= MAX_TEXT_LENGTH,\n `The text in a Snap UI may not be larger than ${\n MAX_TEXT_LENGTH / 1000\n } kB.`,\n );\n}\n\n/**\n * Get a JSX element from a legacy UI component. This supports all legacy UI\n * components, and maps them to their JSX equivalents where possible.\n *\n * This function validates the text size of the component, but does not validate\n * the total size. The total size of the component should be validated before\n * calling this function.\n *\n * @param legacyComponent - The legacy UI component.\n * @returns The JSX element.\n */\nexport function getJsxElementFromComponent(\n legacyComponent: Component,\n): JSXElement {\n validateComponentTextSize(legacyComponent);\n\n /**\n * Get the JSX element for a component. This function is recursive and will\n * call itself for child components.\n *\n * @param component - The component to convert to a JSX element.\n * @returns The JSX element.\n */\n function getElement(component: Component) {\n switch (component.type) {\n case NodeType.Address:\n return <Address address={component.value} />;\n\n case NodeType.Button:\n return (\n <Button\n name={component.name}\n variant={getButtonVariant(component.variant)}\n type={component.buttonType}\n >\n {component.value}\n </Button>\n );\n\n case NodeType.Copyable:\n return (\n <Copyable value={component.value} sensitive={component.sensitive} />\n );\n\n case NodeType.Divider:\n return <Divider />;\n\n case NodeType.Form:\n return (\n <Form name={component.name}>\n {getChildren(component.children.map(getElement))}\n </Form>\n );\n\n case NodeType.Heading:\n return <Heading children={component.value} />;\n\n case NodeType.Image:\n // `Image` supports `alt`, but the legacy `Image` component does not.\n return <Image src={component.value} />;\n\n case NodeType.Input:\n return (\n <Field label={component.label} error={component.error}>\n <Input\n name={component.name}\n type={component.inputType}\n value={component.value}\n placeholder={component.placeholder}\n />\n </Field>\n );\n\n case NodeType.Panel:\n // `Panel` is renamed to `Box` in JSX.\n return (\n <Box children={getChildren(component.children.map(getElement))} />\n );\n\n case NodeType.Row:\n return (\n <Row label={component.label} variant={component.variant}>\n {getElement(component.value) as RowChildren}\n </Row>\n );\n\n case NodeType.Spinner:\n return <Spinner />;\n\n case NodeType.Text:\n return <Text>{getChildren(getTextChildren(component.value))}</Text>;\n\n /* istanbul ignore next 2 */\n default:\n return assertExhaustive(component);\n }\n }\n\n return getElement(legacyComponent);\n}\n\n/**\n * Extract all links from a Markdown text string using the `marked` lexer.\n *\n * @param text - The markdown text string.\n * @returns A list of URLs linked to in the string.\n */\nfunction getMarkdownLinks(text: string) {\n const tokens = lexer(text, { gfm: false });\n const links: Tokens.Link[] = [];\n\n // Walk the lexed tokens and collect all link tokens\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(tokens, (token) => {\n if (token.type === 'link') {\n links.push(token as Tokens.Link);\n }\n });\n\n return links;\n}\n\n/**\n * Validate a link against the phishing list.\n *\n * @param link - The link to validate.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the link is invalid.\n */\nexport function validateLink(\n link: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n try {\n const url = new URL(link);\n assert(\n ALLOWED_PROTOCOLS.includes(url.protocol),\n `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`,\n );\n\n if (url.protocol === 'metamask:') {\n const linkData = parseMetaMaskUrl(link);\n if (linkData.snapId) {\n assert(\n getSnap(linkData.snapId),\n 'The Snap being navigated to is not installed.',\n );\n }\n } else if (url.protocol === 'mailto:') {\n const emails = url.pathname.split(',');\n for (const email of emails) {\n const hostname = email.split('@')[1];\n assert(!hostname.includes(':'));\n const href = `https://${hostname}`;\n assert(!isOnPhishingList(href), 'The specified URL is not allowed.');\n }\n\n return;\n }\n\n assert(!isOnPhishingList(url.href), 'The specified URL is not allowed.');\n } catch (error) {\n throw new Error(\n `Invalid URL: ${\n error?.code === 'ERR_ASSERTION' ? error.message : 'Unable to parse URL.'\n }`,\n );\n }\n}\n\n/**\n * Search for Markdown links in a string and checks them against the phishing\n * list.\n *\n * @param text - The text to verify.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the text contains a link that is not allowed.\n */\nexport function validateTextLinks(\n text: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n const links = getMarkdownLinks(text);\n\n for (const link of links) {\n validateLink(link.href, isOnPhishingList, getSnap);\n }\n}\n\n/**\n * Validate the asset selector component.\n *\n * @param address - The address of the account to pull the assets from.\n * @param getAccountByAddress - A function to get an account by its address.\n *\n * @throws If the asset selector is invalid.\n */\nexport function validateAssetSelector(\n address: CaipAccountId,\n getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined,\n) {\n const account = getAccountByAddress(address);\n\n assert(account, `Could not find account for address: ${address}`);\n}\n\n/**\n * Walk a JSX tree and validate elements.\n * This function validates Links and AssetSelectors.\n *\n * @param node - The JSX node to walk.\n * @param hooks - The hooks to use for validation.\n * @param hooks.isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.\n * @param hooks.getAccountByAddress - The function that returns an account by address.\n */\nexport function validateJsxElements(\n node: JSXElement,\n {\n isOnPhishingList,\n getSnap,\n getAccountByAddress,\n }: {\n isOnPhishingList: (url: string) => boolean;\n getSnap: (id: string) => Snap | undefined;\n getAccountByAddress: (\n address: CaipAccountId,\n ) => InternalAccount | undefined;\n },\n) {\n walkJsx(node, (childNode) => {\n switch (childNode.type) {\n case 'Link':\n validateLink(childNode.props.href, isOnPhishingList, getSnap);\n break;\n case 'AssetSelector':\n validateAssetSelector(\n // We assume that the address part of the CAIP-10 account ID are the same, as\n // that is already validated in the struct.\n childNode.props.addresses[0],\n getAccountByAddress,\n );\n break;\n default:\n break;\n }\n });\n}\n\n/**\n * Calculate the total length of all text in the component.\n *\n * @param component - A custom UI component.\n * @returns The total length of all text components in the component.\n */\nexport function getTotalTextLength(component: Component): number {\n const { type } = component;\n\n switch (type) {\n case NodeType.Panel:\n return component.children.reduce<number>(\n (sum, node) => sum + getTotalTextLength(node),\n 0,\n );\n\n case NodeType.Row:\n return getTotalTextLength(component.value);\n\n case NodeType.Text:\n return component.value.length;\n\n default:\n return 0;\n }\n}\n\n/**\n * Check if a JSX element has children.\n *\n * @param element - A JSX element.\n * @returns `true` if the element has children, `false` otherwise.\n */\nexport function hasChildren<Element extends JSXElement>(\n element: Element,\n): element is Element & {\n props: { children: Nestable<JSXElement | string> };\n} {\n return hasProperty(element.props, 'children');\n}\n\n/**\n * Filter a JSX child to remove `null`, `undefined`, plain booleans, and empty\n * strings.\n *\n * @param child - The JSX child to filter.\n * @returns `true` if the child is not `null`, `undefined`, a plain boolean, or\n * an empty string, `false` otherwise.\n */\nfunction filterJsxChild(child: JSXElement | string | boolean | null): boolean {\n return Boolean(child) && child !== true;\n}\n\n/**\n * Get the children of a JSX element as an array. If the element has only one\n * child, the child is returned as an array.\n *\n * @param element - A JSX element.\n * @returns The children of the element.\n */\nexport function getJsxChildren(element: JSXElement): (JSXElement | string)[] {\n if (hasChildren(element)) {\n if (Array.isArray(element.props.children)) {\n // @ts-expect-error - Each member of the union type has signatures, but\n // none of those signatures are compatible with each other.\n return element.props.children.filter(filterJsxChild).flat(Infinity);\n }\n\n if (element.props.children) {\n return [element.props.children];\n }\n }\n\n return [];\n}\n\n/**\n * Walk a JSX tree and call a callback on each node.\n *\n * @param node - The JSX node to walk.\n * @param callback - The callback to call on each node.\n * @param depth - The current depth in the JSX tree for a walk.\n * @returns The result of the callback, if any.\n */\nexport function walkJsx<Value>(\n node: JSXElement | JSXElement[],\n callback: (node: JSXElement, depth: number) => Value | undefined,\n depth = 0,\n): Value | undefined {\n if (Array.isArray(node)) {\n for (const child of node) {\n const childResult = walkJsx(child, callback, depth);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n\n return undefined;\n }\n\n const result = callback(node, depth);\n if (result !== undefined) {\n return result;\n }\n\n if (\n hasProperty(node, 'props') &&\n isPlainObject(node.props) &&\n hasProperty(node.props, 'children')\n ) {\n const children = getJsxChildren(node);\n for (const child of children) {\n if (isPlainObject(child)) {\n const childResult = walkJsx(child, callback, depth + 1);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Serialise a JSX prop to a string.\n *\n * @param prop - The JSX prop.\n * @returns The serialised JSX prop.\n */\nfunction serialiseProp(prop: unknown): string {\n if (typeof prop === 'string') {\n return `\"${prop}\"`;\n }\n\n return `{${JSON.stringify(prop)}}`;\n}\n\n/**\n * Serialise JSX props to a string.\n *\n * @param props - The JSX props.\n * @returns The serialised JSX props.\n */\nfunction serialiseProps(props: Record<string, unknown>): string {\n return Object.entries(props)\n .filter(([key]) => key !== 'children')\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => ` ${key}=${serialiseProp(value)}`)\n .join('');\n}\n\n/**\n * Serialise a JSX node to a string.\n *\n * @param node - The JSX node.\n * @param indentation - The indentation level. Defaults to `0`. This should not\n * be set by the caller, as it is used for recursion.\n * @returns The serialised JSX node.\n */\nexport function serialiseJsx(node: SnapNode, indentation = 0): string {\n if (Array.isArray(node)) {\n return node.map((child) => serialiseJsx(child, indentation)).join('');\n }\n\n const indent = ' '.repeat(indentation);\n if (typeof node === 'string') {\n return `${indent}${node}\\n`;\n }\n\n if (!node) {\n return '';\n }\n\n const { type, props } = node as GenericSnapElement;\n const trailingNewline = indentation > 0 ? '\\n' : '';\n\n if (hasProperty(props, 'children')) {\n const children = serialiseJsx(props.children as SnapNode, indentation + 1);\n return `${indent}<${type}${serialiseProps(\n props,\n )}>\\n${children}${indent}</${type}>${trailingNewline}`;\n }\n\n return `${indent}<${type}${serialiseProps(props)} />${trailingNewline}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ui.cjs","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":";;;;AACA,mDAA+C;AAa/C,iDAiBiC;AACjC,2CAKyB;AACzB,mCAA2C;AAK3C,uCAAqC;AACrC,mCAAyC;AAEzC,MAAM,eAAe,GAAG,KAAM,CAAC,CAAC,QAAQ;AACxC,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,OAA6C;IACrE,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,aAAa,CAAC;QACvB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAO,QAAgB;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,KAAmC;IACtD,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,MAAe;IAC7C,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,KAAY;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,uBAAC,UAAI,IAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,GAAI,CAAC;QAClE,CAAC;QAED,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,CAAC;QAEpB,KAAK,QAAQ;YACX,OAAO,CACL,uBAAC,UAAI,cAED,sBAAsB;gBACpB,0DAA0D;gBAC1D,iEAAiE;gBACjE,mCAAmC;gBACnC,KAAK,CAAC,MAAiB,CACR,GAEd,CACR,CAAC;QAEJ,KAAK,IAAI;YACP,OAAO,CACL,uBAAC,YAAM,cAEH,sBAAsB;gBACpB,0DAA0D;gBAC1D,iEAAiE;gBACjE,mCAAmC;gBACnC,KAAK,CAAC,MAAiB,CACN,GAEd,CACV,CAAC;QAEJ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAC7B,KAAa;IAEb,MAAM,UAAU,GAAG,IAAA,cAAK,EAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,MAAM,QAAQ,GACZ,EAAE,CAAC;IAEL,wEAAwE;IACxE,WAAW;IACX,mEAAmE;IACnE,IAAA,mBAAU,EAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,GAAG,KAAyB,CAAC;YAC7C,yFAAyF;YACzF,QAAQ,CAAC,IAAI,CACX,GAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAKpC,CACL,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAI7C,CAAC;AACN,CAAC;AAlCD,0CAkCC;AAED;;;;;;GAMG;AACH,SAAS,yBAAyB,CAAC,SAAoB;IACrD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAA,cAAM,EACJ,QAAQ,IAAI,eAAe,EAC3B,gDACE,eAAe,GAAG,IACpB,MAAM,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,0BAA0B,CACxC,eAA0B;IAE1B,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAE3C;;;;;;OAMG;IACH,SAAS,UAAU,CAAC,SAAoB;QACtC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,oBAAQ,CAAC,OAAO;gBACnB,OAAO,uBAAC,aAAO,IAAC,OAAO,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAE/C,KAAK,oBAAQ,CAAC,MAAM;gBAClB,OAAO,CACL,uBAAC,YAAM,IACL,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,EAC5C,IAAI,EAAE,SAAS,CAAC,UAAU,YAEzB,SAAS,CAAC,KAAK,GACT,CACV,CAAC;YAEJ,KAAK,oBAAQ,CAAC,QAAQ;gBACpB,OAAO,CACL,uBAAC,cAAQ,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,GAAI,CACrE,CAAC;YAEJ,KAAK,oBAAQ,CAAC,OAAO;gBACnB,OAAO,uBAAC,aAAO,KAAG,CAAC;YAErB,KAAK,oBAAQ,CAAC,IAAI;gBAChB,OAAO,CACL,uBAAC,UAAI,IAAC,IAAI,EAAE,SAAS,CAAC,IAAI,YACvB,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAC3C,CACR,CAAC;YAEJ,KAAK,oBAAQ,CAAC,OAAO;gBACnB,OAAO,uBAAC,aAAO,IAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAEhD,KAAK,oBAAQ,CAAC,KAAK;gBACjB,qEAAqE;gBACrE,OAAO,uBAAC,WAAK,IAAC,GAAG,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAEzC,KAAK,oBAAQ,CAAC,KAAK;gBACjB,OAAO,CACL,uBAAC,WAAK,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,YACnD,uBAAC,WAAK,IACJ,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,IAAI,EAAE,SAAS,CAAC,SAAS,EACzB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,WAAW,EAAE,SAAS,CAAC,WAAW,GAClC,GACI,CACT,CAAC;YAEJ,KAAK,oBAAQ,CAAC,KAAK;gBACjB,sCAAsC;gBACtC,OAAO,CACL,uBAAC,SAAG,IAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAI,CACnE,CAAC;YAEJ,KAAK,oBAAQ,CAAC,GAAG;gBACf,OAAO,CACL,uBAAC,SAAG,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,YACpD,UAAU,CAAC,SAAS,CAAC,KAAK,CAAgB,GACvC,CACP,CAAC;YAEJ,KAAK,oBAAQ,CAAC,OAAO;gBACnB,OAAO,uBAAC,aAAO,KAAG,CAAC;YAErB,KAAK,oBAAQ,CAAC,IAAI;gBAChB,OAAO,uBAAC,UAAI,cAAE,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAQ,CAAC;YAEtE,4BAA4B;YAC5B;gBACE,OAAO,IAAA,wBAAgB,EAAC,SAAS,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC,eAAe,CAAC,CAAC;AACrC,CAAC;AAxFD,gEAwFC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,IAAA,cAAK,EAAC,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,oDAAoD;IACpD,wEAAwE;IACxE,WAAW;IACX,mEAAmE;IACnE,IAAA,mBAAU,EAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,KAAoB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAC1B,IAAY,EACZ,gBAA0C,EAC1C,OAAyC;IAEzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAA,cAAM,EACJ,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EACxC,4BAA4B,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5D,CAAC;QAEF,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAA,sBAAgB,EAAC,IAAI,CAAC,CAAC;YACxC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpB,IAAA,cAAM,EACJ,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACxB,+CAA+C,CAChD,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrC,IAAA,cAAM,EAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,MAAM,IAAI,GAAG,WAAW,QAAQ,EAAE,CAAC;gBACnC,IAAA,cAAM,EAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;YACvE,CAAC;YAED,OAAO;QACT,CAAC;QAED,IAAA,cAAM,EAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,gBACE,KAAK,EAAE,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBACpD,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAxCD,oCAwCC;AAED;;;;;;;;;GASG;AACH,SAAgB,iBAAiB,CAC/B,IAAY,EACZ,gBAA0C,EAC1C,OAAyC;IAEzC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAVD,8CAUC;AAED;;;;;;;GAOG;AACH,SAAgB,qBAAqB,CACnC,OAAsB,EACtB,mBAA4E;IAE5E,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7C,IAAA,cAAM,EAAC,OAAO,EAAE,uCAAuC,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAPD,sDAOC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,mBAAmB,CACjC,IAAgB,EAChB,EACE,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,aAAa,GAQd;IAED,OAAO,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE;QAC1B,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,MAAM;gBACT,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;gBAC9D,MAAM;YACR,KAAK,eAAe;gBAClB,qBAAqB;gBACnB,6EAA6E;gBAC7E,2CAA2C;gBAC3C,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAC5B,mBAAmB,CACpB,CAAC;gBACF,MAAM;YACR,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAA,kBAAU,EAAC,GAAG,CAAC,CAAC;gBAC9B,IAAA,cAAM,EACJ,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC,0BAA0B,CAAC,CAAC,EAC9D,yFAAyF,CAC1F,CAAC;gBACF,MAAM;YACR,CAAC;YACD;gBACE,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AA1CD,kDA0CC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAC,SAAoB;IACrD,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAE3B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,oBAAQ,CAAC,KAAK;YACjB,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAC7C,CAAC,CACF,CAAC;QAEJ,KAAK,oBAAQ,CAAC,GAAG;YACf,OAAO,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE7C,KAAK,oBAAQ,CAAC,IAAI;YAChB,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAEhC;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAnBD,gDAmBC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,OAAgB;IAIhB,OAAO,IAAA,mBAAW,EAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAND,kCAMC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,KAA2C;IACjE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAAC,OAAmB;IAChD,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,uEAAuE;YACvE,2DAA2D;YAC3D,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAdD,wCAcC;AAED;;;;;;;GAOG;AACH,SAAgB,OAAO,CACrB,IAA+B,EAC/B,QAAgE,EAChE,KAAK,GAAG,CAAC;IAET,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO,WAAW,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IACE,IAAA,mBAAW,EAAC,IAAI,EAAE,OAAO,CAAC;QAC1B,IAAA,qBAAa,EAAC,IAAI,CAAC,KAAK,CAAC;QACzB,IAAA,mBAAW,EAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EACnC,CAAC;QACD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,IAAA,qBAAa,EAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACxD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,OAAO,WAAW,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAtCD,0BAsCC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,IAAa;IAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,IAAI,GAAG,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAA8B;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACzB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC;SACrC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;SACxD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,YAAY,CAAC,IAAc,EAAE,WAAW,GAAG,CAAC;IAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,GAAG,MAAM,GAAG,IAAI,IAAI,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAA0B,CAAC;IACnD,MAAM,eAAe,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpD,IAAI,IAAA,mBAAW,EAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,QAAoB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;QAC3E,OAAO,GAAG,MAAM,IAAI,IAAI,GAAG,cAAc,CACvC,KAAK,CACN,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,IAAI,eAAe,EAAE,CAAC;IACzD,CAAC;IAED,OAAO,GAAG,MAAM,IAAI,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,eAAe,EAAE,CAAC;AAC1E,CAAC;AAzBD,oCAyBC","sourcesContent":["import type { CaipAccountId, Component } from '@metamask/snaps-sdk';\nimport { NodeType } from '@metamask/snaps-sdk';\nimport type {\n BoldChildren,\n GenericSnapElement,\n ItalicChildren,\n JSXElement,\n LinkElement,\n Nestable,\n RowChildren,\n SnapNode,\n StandardFormattingElement,\n TextChildren,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n Italic,\n Link,\n Bold,\n Row,\n Text,\n Field,\n Image,\n Input,\n Heading,\n Form,\n Divider,\n Spinner,\n Copyable,\n Box,\n Button,\n Address,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n assert,\n assertExhaustive,\n hasProperty,\n isPlainObject,\n} from '@metamask/utils';\nimport { lexer, walkTokens } from 'marked';\nimport type { Token, Tokens } from 'marked';\n\nimport type { InternalAccount } from './account';\nimport type { Snap } from './snaps';\nimport { isValidUrl } from './types';\nimport { parseMetaMaskUrl } from './url';\n\nconst MAX_TEXT_LENGTH = 50_000; // 50 kb\nconst ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];\n\n/**\n * Get the button variant from a legacy button component variant.\n *\n * @param variant - The legacy button component variant.\n * @returns The button variant.\n */\nfunction getButtonVariant(variant?: 'primary' | 'secondary' | undefined) {\n switch (variant) {\n case 'primary':\n return 'primary';\n case 'secondary':\n return 'destructive';\n default:\n return undefined;\n }\n}\n\n/**\n * Get the children of a JSX element. If there is only one child, the child is\n * returned directly. Otherwise, the children are returned as an array.\n *\n * @param elements - The JSX elements.\n * @returns The child or children.\n */\nfunction getChildren<Type>(elements: Type[]) {\n if (elements.length === 1) {\n return elements[0];\n }\n\n return elements;\n}\n\n/**\n * Get the text of a link token.\n *\n * @param token - The link token.\n * @returns The text of the link token.\n */\nfunction getLinkText(token: Tokens.Link | Tokens.Generic) {\n if (token.tokens && token.tokens.length > 0) {\n return getChildren(token.tokens.flatMap(getTextChildFromToken));\n }\n\n return token.href;\n}\n\n/**\n * Get the text child from a list of markdown tokens.\n *\n * @param tokens - The markdown tokens.\n * @returns The text child.\n */\nfunction getTextChildFromTokens(tokens: Token[]) {\n return getChildren(tokens.flatMap(getTextChildFromToken));\n}\n\n/**\n * Get the text child from a markdown token.\n *\n * @param token - The markdown token.\n * @returns The text child.\n */\nfunction getTextChildFromToken(token: Token): TextChildren {\n switch (token.type) {\n case 'link': {\n return <Link href={token.href} children={getLinkText(token)} />;\n }\n\n case 'text':\n return token.text;\n\n case 'strong':\n return (\n <Bold>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as BoldChildren\n }\n </Bold>\n );\n\n case 'em':\n return (\n <Italic>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as ItalicChildren\n }\n </Italic>\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get all text children from a markdown string.\n *\n * @param value - The markdown string.\n * @returns The text children.\n */\nexport function getTextChildren(\n value: string,\n): (string | StandardFormattingElement | LinkElement)[] {\n const rootTokens = lexer(value, { gfm: false });\n const children: (string | StandardFormattingElement | LinkElement | null)[] =\n [];\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(rootTokens, (token) => {\n if (token.type === 'paragraph') {\n if (children.length > 0) {\n children.push('\\n\\n');\n }\n\n const { tokens } = token as Tokens.Paragraph;\n // We do not need to consider nesting deeper than 1 level here and we can therefore cast.\n children.push(\n ...(tokens.flatMap(getTextChildFromToken) as (\n | string\n | StandardFormattingElement\n | LinkElement\n | null\n )[]),\n );\n }\n });\n\n return children.filter((child) => child !== null) as (\n | string\n | StandardFormattingElement\n | LinkElement\n )[];\n}\n\n/**\n * Validate the text size of a component. The text size is the total length of\n * all text in the component.\n *\n * @param component - The component to validate.\n * @throws An error if the text size exceeds the maximum allowed size.\n */\nfunction validateComponentTextSize(component: Component) {\n const textSize = getTotalTextLength(component);\n assert(\n textSize <= MAX_TEXT_LENGTH,\n `The text in a Snap UI may not be larger than ${\n MAX_TEXT_LENGTH / 1000\n } kB.`,\n );\n}\n\n/**\n * Get a JSX element from a legacy UI component. This supports all legacy UI\n * components, and maps them to their JSX equivalents where possible.\n *\n * This function validates the text size of the component, but does not validate\n * the total size. The total size of the component should be validated before\n * calling this function.\n *\n * @param legacyComponent - The legacy UI component.\n * @returns The JSX element.\n */\nexport function getJsxElementFromComponent(\n legacyComponent: Component,\n): JSXElement {\n validateComponentTextSize(legacyComponent);\n\n /**\n * Get the JSX element for a component. This function is recursive and will\n * call itself for child components.\n *\n * @param component - The component to convert to a JSX element.\n * @returns The JSX element.\n */\n function getElement(component: Component) {\n switch (component.type) {\n case NodeType.Address:\n return <Address address={component.value} />;\n\n case NodeType.Button:\n return (\n <Button\n name={component.name}\n variant={getButtonVariant(component.variant)}\n type={component.buttonType}\n >\n {component.value}\n </Button>\n );\n\n case NodeType.Copyable:\n return (\n <Copyable value={component.value} sensitive={component.sensitive} />\n );\n\n case NodeType.Divider:\n return <Divider />;\n\n case NodeType.Form:\n return (\n <Form name={component.name}>\n {getChildren(component.children.map(getElement))}\n </Form>\n );\n\n case NodeType.Heading:\n return <Heading children={component.value} />;\n\n case NodeType.Image:\n // `Image` supports `alt`, but the legacy `Image` component does not.\n return <Image src={component.value} />;\n\n case NodeType.Input:\n return (\n <Field label={component.label} error={component.error}>\n <Input\n name={component.name}\n type={component.inputType}\n value={component.value}\n placeholder={component.placeholder}\n />\n </Field>\n );\n\n case NodeType.Panel:\n // `Panel` is renamed to `Box` in JSX.\n return (\n <Box children={getChildren(component.children.map(getElement))} />\n );\n\n case NodeType.Row:\n return (\n <Row label={component.label} variant={component.variant}>\n {getElement(component.value) as RowChildren}\n </Row>\n );\n\n case NodeType.Spinner:\n return <Spinner />;\n\n case NodeType.Text:\n return <Text>{getChildren(getTextChildren(component.value))}</Text>;\n\n /* istanbul ignore next 2 */\n default:\n return assertExhaustive(component);\n }\n }\n\n return getElement(legacyComponent);\n}\n\n/**\n * Extract all links from a Markdown text string using the `marked` lexer.\n *\n * @param text - The markdown text string.\n * @returns A list of URLs linked to in the string.\n */\nfunction getMarkdownLinks(text: string) {\n const tokens = lexer(text, { gfm: false });\n const links: Tokens.Link[] = [];\n\n // Walk the lexed tokens and collect all link tokens\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(tokens, (token) => {\n if (token.type === 'link') {\n links.push(token as Tokens.Link);\n }\n });\n\n return links;\n}\n\n/**\n * Validate a link against the phishing list.\n *\n * @param link - The link to validate.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the link is invalid.\n */\nexport function validateLink(\n link: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n try {\n const url = new URL(link);\n assert(\n ALLOWED_PROTOCOLS.includes(url.protocol),\n `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`,\n );\n\n if (url.protocol === 'metamask:') {\n const linkData = parseMetaMaskUrl(link);\n if (linkData.snapId) {\n assert(\n getSnap(linkData.snapId),\n 'The Snap being navigated to is not installed.',\n );\n }\n } else if (url.protocol === 'mailto:') {\n const emails = url.pathname.split(',');\n for (const email of emails) {\n const hostname = email.split('@')[1];\n assert(!hostname.includes(':'));\n const href = `https://${hostname}`;\n assert(!isOnPhishingList(href), 'The specified URL is not allowed.');\n }\n\n return;\n }\n\n assert(!isOnPhishingList(url.href), 'The specified URL is not allowed.');\n } catch (error) {\n throw new Error(\n `Invalid URL: ${\n error?.code === 'ERR_ASSERTION' ? error.message : 'Unable to parse URL.'\n }`,\n );\n }\n}\n\n/**\n * Search for Markdown links in a string and checks them against the phishing\n * list.\n *\n * @param text - The text to verify.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the text contains a link that is not allowed.\n */\nexport function validateTextLinks(\n text: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n const links = getMarkdownLinks(text);\n\n for (const link of links) {\n validateLink(link.href, isOnPhishingList, getSnap);\n }\n}\n\n/**\n * Validate the asset selector component.\n *\n * @param address - The address of the account to pull the assets from.\n * @param getAccountByAddress - A function to get an account by its address.\n *\n * @throws If the asset selector is invalid.\n */\nexport function validateAssetSelector(\n address: CaipAccountId,\n getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined,\n) {\n const account = getAccountByAddress(address);\n\n assert(account, `Could not find account for address: ${address}`);\n}\n\n/**\n * Walk a JSX tree and validate elements.\n * This function validates Links and AssetSelectors.\n *\n * @param node - The JSX node to walk.\n * @param hooks - The hooks to use for validation.\n * @param hooks.isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.\n * @param hooks.getAccountByAddress - The function that returns an account by address.\n * @param hooks.hasPermission - A function that checks whether the Snap has a given permission.\n */\nexport function validateJsxElements(\n node: JSXElement,\n {\n isOnPhishingList,\n getSnap,\n getAccountByAddress,\n hasPermission,\n }: {\n isOnPhishingList: (url: string) => boolean;\n getSnap: (id: string) => Snap | undefined;\n getAccountByAddress: (\n address: CaipAccountId,\n ) => InternalAccount | undefined;\n hasPermission: (permission: string) => boolean;\n },\n) {\n walkJsx(node, (childNode) => {\n switch (childNode.type) {\n case 'Link':\n validateLink(childNode.props.href, isOnPhishingList, getSnap);\n break;\n case 'AssetSelector':\n validateAssetSelector(\n // We assume that the address part of the CAIP-10 account ID are the same, as\n // that is already validated in the struct.\n childNode.props.addresses[0],\n getAccountByAddress,\n );\n break;\n case 'Image': {\n const { src } = childNode.props;\n const isUrl = isValidUrl(src);\n assert(\n !isUrl || (isUrl && hasPermission('endowment:network-access')),\n 'Using external images is only permitted with the `endowment:network-access` permission.',\n );\n break;\n }\n default:\n break;\n }\n });\n}\n\n/**\n * Calculate the total length of all text in the component.\n *\n * @param component - A custom UI component.\n * @returns The total length of all text components in the component.\n */\nexport function getTotalTextLength(component: Component): number {\n const { type } = component;\n\n switch (type) {\n case NodeType.Panel:\n return component.children.reduce<number>(\n (sum, node) => sum + getTotalTextLength(node),\n 0,\n );\n\n case NodeType.Row:\n return getTotalTextLength(component.value);\n\n case NodeType.Text:\n return component.value.length;\n\n default:\n return 0;\n }\n}\n\n/**\n * Check if a JSX element has children.\n *\n * @param element - A JSX element.\n * @returns `true` if the element has children, `false` otherwise.\n */\nexport function hasChildren<Element extends JSXElement>(\n element: Element,\n): element is Element & {\n props: { children: Nestable<JSXElement | string> };\n} {\n return hasProperty(element.props, 'children');\n}\n\n/**\n * Filter a JSX child to remove `null`, `undefined`, plain booleans, and empty\n * strings.\n *\n * @param child - The JSX child to filter.\n * @returns `true` if the child is not `null`, `undefined`, a plain boolean, or\n * an empty string, `false` otherwise.\n */\nfunction filterJsxChild(child: JSXElement | string | boolean | null): boolean {\n return Boolean(child) && child !== true;\n}\n\n/**\n * Get the children of a JSX element as an array. If the element has only one\n * child, the child is returned as an array.\n *\n * @param element - A JSX element.\n * @returns The children of the element.\n */\nexport function getJsxChildren(element: JSXElement): (JSXElement | string)[] {\n if (hasChildren(element)) {\n if (Array.isArray(element.props.children)) {\n // @ts-expect-error - Each member of the union type has signatures, but\n // none of those signatures are compatible with each other.\n return element.props.children.filter(filterJsxChild).flat(Infinity);\n }\n\n if (element.props.children) {\n return [element.props.children];\n }\n }\n\n return [];\n}\n\n/**\n * Walk a JSX tree and call a callback on each node.\n *\n * @param node - The JSX node to walk.\n * @param callback - The callback to call on each node.\n * @param depth - The current depth in the JSX tree for a walk.\n * @returns The result of the callback, if any.\n */\nexport function walkJsx<Value>(\n node: JSXElement | JSXElement[],\n callback: (node: JSXElement, depth: number) => Value | undefined,\n depth = 0,\n): Value | undefined {\n if (Array.isArray(node)) {\n for (const child of node) {\n const childResult = walkJsx(child, callback, depth);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n\n return undefined;\n }\n\n const result = callback(node, depth);\n if (result !== undefined) {\n return result;\n }\n\n if (\n hasProperty(node, 'props') &&\n isPlainObject(node.props) &&\n hasProperty(node.props, 'children')\n ) {\n const children = getJsxChildren(node);\n for (const child of children) {\n if (isPlainObject(child)) {\n const childResult = walkJsx(child, callback, depth + 1);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Serialise a JSX prop to a string.\n *\n * @param prop - The JSX prop.\n * @returns The serialised JSX prop.\n */\nfunction serialiseProp(prop: unknown): string {\n if (typeof prop === 'string') {\n return `\"${prop}\"`;\n }\n\n return `{${JSON.stringify(prop)}}`;\n}\n\n/**\n * Serialise JSX props to a string.\n *\n * @param props - The JSX props.\n * @returns The serialised JSX props.\n */\nfunction serialiseProps(props: Record<string, unknown>): string {\n return Object.entries(props)\n .filter(([key]) => key !== 'children')\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => ` ${key}=${serialiseProp(value)}`)\n .join('');\n}\n\n/**\n * Serialise a JSX node to a string.\n *\n * @param node - The JSX node.\n * @param indentation - The indentation level. Defaults to `0`. This should not\n * be set by the caller, as it is used for recursion.\n * @returns The serialised JSX node.\n */\nexport function serialiseJsx(node: SnapNode, indentation = 0): string {\n if (Array.isArray(node)) {\n return node.map((child) => serialiseJsx(child, indentation)).join('');\n }\n\n const indent = ' '.repeat(indentation);\n if (typeof node === 'string') {\n return `${indent}${node}\\n`;\n }\n\n if (!node) {\n return '';\n }\n\n const { type, props } = node as GenericSnapElement;\n const trailingNewline = indentation > 0 ? '\\n' : '';\n\n if (hasProperty(props, 'children')) {\n const children = serialiseJsx(props.children as SnapNode, indentation + 1);\n return `${indent}<${type}${serialiseProps(\n props,\n )}>\\n${children}${indent}</${type}>${trailingNewline}`;\n }\n\n return `${indent}<${type}${serialiseProps(props)} />${trailingNewline}`;\n}\n"]}
|
package/dist/ui.d.cts
CHANGED
|
@@ -61,11 +61,13 @@ export declare function validateAssetSelector(address: CaipAccountId, getAccount
|
|
|
61
61
|
* phishing list.
|
|
62
62
|
* @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.
|
|
63
63
|
* @param hooks.getAccountByAddress - The function that returns an account by address.
|
|
64
|
+
* @param hooks.hasPermission - A function that checks whether the Snap has a given permission.
|
|
64
65
|
*/
|
|
65
|
-
export declare function validateJsxElements(node: JSXElement, { isOnPhishingList, getSnap, getAccountByAddress, }: {
|
|
66
|
+
export declare function validateJsxElements(node: JSXElement, { isOnPhishingList, getSnap, getAccountByAddress, hasPermission, }: {
|
|
66
67
|
isOnPhishingList: (url: string) => boolean;
|
|
67
68
|
getSnap: (id: string) => Snap | undefined;
|
|
68
69
|
getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined;
|
|
70
|
+
hasPermission: (permission: string) => boolean;
|
|
69
71
|
}): void;
|
|
70
72
|
/**
|
|
71
73
|
* Calculate the total length of all text in the component.
|
package/dist/ui.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.cts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,4BAA4B;AAEpE,OAAO,KAAK,EAIV,UAAU,EACV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,yBAAyB,EAE1B,gCAAgC;AA4BjC,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAkB;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAgB;
|
|
1
|
+
{"version":3,"file":"ui.d.cts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,4BAA4B;AAEpE,OAAO,KAAK,EAIV,UAAU,EACV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,yBAAyB,EAE1B,gCAAgC;AA4BjC,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAkB;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAgB;AA+GpC;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GACZ,CAAC,MAAM,GAAG,yBAAyB,GAAG,WAAW,CAAC,EAAE,CAgCtD;AAmBD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,SAAS,GACzB,UAAU,CAsFZ;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC1C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,QAqC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC1C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,QAO1C;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,eAAe,GAAG,SAAS,QAK7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,EACE,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;IAC1C,mBAAmB,EAAE,CACnB,OAAO,EAAE,aAAa,KACnB,eAAe,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAChD,QA4BF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAmB/D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,SAAS,UAAU,EACpD,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,OAAO,GAAG;IACtB,KAAK,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,CAAA;KAAE,CAAC;CACpD,CAEA;AAcD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAc3E;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAC3B,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,EAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,EAChE,KAAK,SAAI,GACR,KAAK,GAAG,SAAS,CAkCnB;AA8BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,SAAI,GAAG,MAAM,CAyBpE"}
|
package/dist/ui.d.mts
CHANGED
|
@@ -61,11 +61,13 @@ export declare function validateAssetSelector(address: CaipAccountId, getAccount
|
|
|
61
61
|
* phishing list.
|
|
62
62
|
* @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.
|
|
63
63
|
* @param hooks.getAccountByAddress - The function that returns an account by address.
|
|
64
|
+
* @param hooks.hasPermission - A function that checks whether the Snap has a given permission.
|
|
64
65
|
*/
|
|
65
|
-
export declare function validateJsxElements(node: JSXElement, { isOnPhishingList, getSnap, getAccountByAddress, }: {
|
|
66
|
+
export declare function validateJsxElements(node: JSXElement, { isOnPhishingList, getSnap, getAccountByAddress, hasPermission, }: {
|
|
66
67
|
isOnPhishingList: (url: string) => boolean;
|
|
67
68
|
getSnap: (id: string) => Snap | undefined;
|
|
68
69
|
getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined;
|
|
70
|
+
hasPermission: (permission: string) => boolean;
|
|
69
71
|
}): void;
|
|
70
72
|
/**
|
|
71
73
|
* Calculate the total length of all text in the component.
|
package/dist/ui.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.mts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,4BAA4B;AAEpE,OAAO,KAAK,EAIV,UAAU,EACV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,yBAAyB,EAE1B,gCAAgC;AA4BjC,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAkB;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAgB;
|
|
1
|
+
{"version":3,"file":"ui.d.mts","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,4BAA4B;AAEpE,OAAO,KAAK,EAIV,UAAU,EACV,WAAW,EACX,QAAQ,EAER,QAAQ,EACR,yBAAyB,EAE1B,gCAAgC;AA4BjC,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAkB;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,oBAAgB;AA+GpC;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,GACZ,CAAC,MAAM,GAAG,yBAAyB,GAAG,WAAW,CAAC,EAAE,CAgCtD;AAmBD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,SAAS,GACzB,UAAU,CAsFZ;AAyBD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC1C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,QAqC1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC1C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,QAO1C;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,aAAa,EACtB,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,eAAe,GAAG,SAAS,QAK7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,EACE,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,aAAa,GACd,EAAE;IACD,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;IAC1C,mBAAmB,EAAE,CACnB,OAAO,EAAE,aAAa,KACnB,eAAe,GAAG,SAAS,CAAC;IACjC,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAChD,QA4BF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAmB/D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,SAAS,UAAU,EACpD,OAAO,EAAE,OAAO,GACf,OAAO,IAAI,OAAO,GAAG;IACtB,KAAK,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,CAAA;KAAE,CAAC;CACpD,CAEA;AAcD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAc3E;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAC3B,IAAI,EAAE,UAAU,GAAG,UAAU,EAAE,EAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,KAAK,GAAG,SAAS,EAChE,KAAK,SAAI,GACR,KAAK,GAAG,SAAS,CAkCnB;AA8BD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,SAAI,GAAG,MAAM,CAyBpE"}
|
package/dist/ui.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { NodeType } from "@metamask/snaps-sdk";
|
|
|
3
3
|
import { Italic, Link, Bold, Row, Text, Field, Image, Input, Heading, Form, Divider, Spinner, Copyable, Box, Button, Address } from "@metamask/snaps-sdk/jsx";
|
|
4
4
|
import { assert, assertExhaustive, hasProperty, isPlainObject } from "@metamask/utils";
|
|
5
5
|
import { lexer, walkTokens } from "marked";
|
|
6
|
+
import { isValidUrl } from "./types.mjs";
|
|
6
7
|
import { parseMetaMaskUrl } from "./url.mjs";
|
|
7
8
|
const MAX_TEXT_LENGTH = 50000; // 50 kb
|
|
8
9
|
const ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];
|
|
@@ -268,8 +269,9 @@ export function validateAssetSelector(address, getAccountByAddress) {
|
|
|
268
269
|
* phishing list.
|
|
269
270
|
* @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.
|
|
270
271
|
* @param hooks.getAccountByAddress - The function that returns an account by address.
|
|
272
|
+
* @param hooks.hasPermission - A function that checks whether the Snap has a given permission.
|
|
271
273
|
*/
|
|
272
|
-
export function validateJsxElements(node, { isOnPhishingList, getSnap, getAccountByAddress, }) {
|
|
274
|
+
export function validateJsxElements(node, { isOnPhishingList, getSnap, getAccountByAddress, hasPermission, }) {
|
|
273
275
|
walkJsx(node, (childNode) => {
|
|
274
276
|
switch (childNode.type) {
|
|
275
277
|
case 'Link':
|
|
@@ -281,6 +283,12 @@ export function validateJsxElements(node, { isOnPhishingList, getSnap, getAccoun
|
|
|
281
283
|
// that is already validated in the struct.
|
|
282
284
|
childNode.props.addresses[0], getAccountByAddress);
|
|
283
285
|
break;
|
|
286
|
+
case 'Image': {
|
|
287
|
+
const { src } = childNode.props;
|
|
288
|
+
const isUrl = isValidUrl(src);
|
|
289
|
+
assert(!isUrl || (isUrl && hasPermission('endowment:network-access')), 'Using external images is only permitted with the `endowment:network-access` permission.');
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
284
292
|
default:
|
|
285
293
|
break;
|
|
286
294
|
}
|
package/dist/ui.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.mjs","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { CaipAccountId, Component } from '@metamask/snaps-sdk';\nimport { NodeType } from '@metamask/snaps-sdk';\nimport type {\n BoldChildren,\n GenericSnapElement,\n ItalicChildren,\n JSXElement,\n LinkElement,\n Nestable,\n RowChildren,\n SnapNode,\n StandardFormattingElement,\n TextChildren,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n Italic,\n Link,\n Bold,\n Row,\n Text,\n Field,\n Image,\n Input,\n Heading,\n Form,\n Divider,\n Spinner,\n Copyable,\n Box,\n Button,\n Address,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n assert,\n assertExhaustive,\n hasProperty,\n isPlainObject,\n} from '@metamask/utils';\nimport { lexer, walkTokens } from 'marked';\nimport type { Token, Tokens } from 'marked';\n\nimport type { InternalAccount } from './account';\nimport type { Snap } from './snaps';\nimport { parseMetaMaskUrl } from './url';\n\nconst MAX_TEXT_LENGTH = 50_000; // 50 kb\nconst ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];\n\n/**\n * Get the button variant from a legacy button component variant.\n *\n * @param variant - The legacy button component variant.\n * @returns The button variant.\n */\nfunction getButtonVariant(variant?: 'primary' | 'secondary' | undefined) {\n switch (variant) {\n case 'primary':\n return 'primary';\n case 'secondary':\n return 'destructive';\n default:\n return undefined;\n }\n}\n\n/**\n * Get the children of a JSX element. If there is only one child, the child is\n * returned directly. Otherwise, the children are returned as an array.\n *\n * @param elements - The JSX elements.\n * @returns The child or children.\n */\nfunction getChildren<Type>(elements: Type[]) {\n if (elements.length === 1) {\n return elements[0];\n }\n\n return elements;\n}\n\n/**\n * Get the text of a link token.\n *\n * @param token - The link token.\n * @returns The text of the link token.\n */\nfunction getLinkText(token: Tokens.Link | Tokens.Generic) {\n if (token.tokens && token.tokens.length > 0) {\n return getChildren(token.tokens.flatMap(getTextChildFromToken));\n }\n\n return token.href;\n}\n\n/**\n * Get the text child from a list of markdown tokens.\n *\n * @param tokens - The markdown tokens.\n * @returns The text child.\n */\nfunction getTextChildFromTokens(tokens: Token[]) {\n return getChildren(tokens.flatMap(getTextChildFromToken));\n}\n\n/**\n * Get the text child from a markdown token.\n *\n * @param token - The markdown token.\n * @returns The text child.\n */\nfunction getTextChildFromToken(token: Token): TextChildren {\n switch (token.type) {\n case 'link': {\n return <Link href={token.href} children={getLinkText(token)} />;\n }\n\n case 'text':\n return token.text;\n\n case 'strong':\n return (\n <Bold>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as BoldChildren\n }\n </Bold>\n );\n\n case 'em':\n return (\n <Italic>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as ItalicChildren\n }\n </Italic>\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get all text children from a markdown string.\n *\n * @param value - The markdown string.\n * @returns The text children.\n */\nexport function getTextChildren(\n value: string,\n): (string | StandardFormattingElement | LinkElement)[] {\n const rootTokens = lexer(value, { gfm: false });\n const children: (string | StandardFormattingElement | LinkElement | null)[] =\n [];\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(rootTokens, (token) => {\n if (token.type === 'paragraph') {\n if (children.length > 0) {\n children.push('\\n\\n');\n }\n\n const { tokens } = token as Tokens.Paragraph;\n // We do not need to consider nesting deeper than 1 level here and we can therefore cast.\n children.push(\n ...(tokens.flatMap(getTextChildFromToken) as (\n | string\n | StandardFormattingElement\n | LinkElement\n | null\n )[]),\n );\n }\n });\n\n return children.filter((child) => child !== null) as (\n | string\n | StandardFormattingElement\n | LinkElement\n )[];\n}\n\n/**\n * Validate the text size of a component. The text size is the total length of\n * all text in the component.\n *\n * @param component - The component to validate.\n * @throws An error if the text size exceeds the maximum allowed size.\n */\nfunction validateComponentTextSize(component: Component) {\n const textSize = getTotalTextLength(component);\n assert(\n textSize <= MAX_TEXT_LENGTH,\n `The text in a Snap UI may not be larger than ${\n MAX_TEXT_LENGTH / 1000\n } kB.`,\n );\n}\n\n/**\n * Get a JSX element from a legacy UI component. This supports all legacy UI\n * components, and maps them to their JSX equivalents where possible.\n *\n * This function validates the text size of the component, but does not validate\n * the total size. The total size of the component should be validated before\n * calling this function.\n *\n * @param legacyComponent - The legacy UI component.\n * @returns The JSX element.\n */\nexport function getJsxElementFromComponent(\n legacyComponent: Component,\n): JSXElement {\n validateComponentTextSize(legacyComponent);\n\n /**\n * Get the JSX element for a component. This function is recursive and will\n * call itself for child components.\n *\n * @param component - The component to convert to a JSX element.\n * @returns The JSX element.\n */\n function getElement(component: Component) {\n switch (component.type) {\n case NodeType.Address:\n return <Address address={component.value} />;\n\n case NodeType.Button:\n return (\n <Button\n name={component.name}\n variant={getButtonVariant(component.variant)}\n type={component.buttonType}\n >\n {component.value}\n </Button>\n );\n\n case NodeType.Copyable:\n return (\n <Copyable value={component.value} sensitive={component.sensitive} />\n );\n\n case NodeType.Divider:\n return <Divider />;\n\n case NodeType.Form:\n return (\n <Form name={component.name}>\n {getChildren(component.children.map(getElement))}\n </Form>\n );\n\n case NodeType.Heading:\n return <Heading children={component.value} />;\n\n case NodeType.Image:\n // `Image` supports `alt`, but the legacy `Image` component does not.\n return <Image src={component.value} />;\n\n case NodeType.Input:\n return (\n <Field label={component.label} error={component.error}>\n <Input\n name={component.name}\n type={component.inputType}\n value={component.value}\n placeholder={component.placeholder}\n />\n </Field>\n );\n\n case NodeType.Panel:\n // `Panel` is renamed to `Box` in JSX.\n return (\n <Box children={getChildren(component.children.map(getElement))} />\n );\n\n case NodeType.Row:\n return (\n <Row label={component.label} variant={component.variant}>\n {getElement(component.value) as RowChildren}\n </Row>\n );\n\n case NodeType.Spinner:\n return <Spinner />;\n\n case NodeType.Text:\n return <Text>{getChildren(getTextChildren(component.value))}</Text>;\n\n /* istanbul ignore next 2 */\n default:\n return assertExhaustive(component);\n }\n }\n\n return getElement(legacyComponent);\n}\n\n/**\n * Extract all links from a Markdown text string using the `marked` lexer.\n *\n * @param text - The markdown text string.\n * @returns A list of URLs linked to in the string.\n */\nfunction getMarkdownLinks(text: string) {\n const tokens = lexer(text, { gfm: false });\n const links: Tokens.Link[] = [];\n\n // Walk the lexed tokens and collect all link tokens\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(tokens, (token) => {\n if (token.type === 'link') {\n links.push(token as Tokens.Link);\n }\n });\n\n return links;\n}\n\n/**\n * Validate a link against the phishing list.\n *\n * @param link - The link to validate.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the link is invalid.\n */\nexport function validateLink(\n link: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n try {\n const url = new URL(link);\n assert(\n ALLOWED_PROTOCOLS.includes(url.protocol),\n `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`,\n );\n\n if (url.protocol === 'metamask:') {\n const linkData = parseMetaMaskUrl(link);\n if (linkData.snapId) {\n assert(\n getSnap(linkData.snapId),\n 'The Snap being navigated to is not installed.',\n );\n }\n } else if (url.protocol === 'mailto:') {\n const emails = url.pathname.split(',');\n for (const email of emails) {\n const hostname = email.split('@')[1];\n assert(!hostname.includes(':'));\n const href = `https://${hostname}`;\n assert(!isOnPhishingList(href), 'The specified URL is not allowed.');\n }\n\n return;\n }\n\n assert(!isOnPhishingList(url.href), 'The specified URL is not allowed.');\n } catch (error) {\n throw new Error(\n `Invalid URL: ${\n error?.code === 'ERR_ASSERTION' ? error.message : 'Unable to parse URL.'\n }`,\n );\n }\n}\n\n/**\n * Search for Markdown links in a string and checks them against the phishing\n * list.\n *\n * @param text - The text to verify.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the text contains a link that is not allowed.\n */\nexport function validateTextLinks(\n text: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n const links = getMarkdownLinks(text);\n\n for (const link of links) {\n validateLink(link.href, isOnPhishingList, getSnap);\n }\n}\n\n/**\n * Validate the asset selector component.\n *\n * @param address - The address of the account to pull the assets from.\n * @param getAccountByAddress - A function to get an account by its address.\n *\n * @throws If the asset selector is invalid.\n */\nexport function validateAssetSelector(\n address: CaipAccountId,\n getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined,\n) {\n const account = getAccountByAddress(address);\n\n assert(account, `Could not find account for address: ${address}`);\n}\n\n/**\n * Walk a JSX tree and validate elements.\n * This function validates Links and AssetSelectors.\n *\n * @param node - The JSX node to walk.\n * @param hooks - The hooks to use for validation.\n * @param hooks.isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.\n * @param hooks.getAccountByAddress - The function that returns an account by address.\n */\nexport function validateJsxElements(\n node: JSXElement,\n {\n isOnPhishingList,\n getSnap,\n getAccountByAddress,\n }: {\n isOnPhishingList: (url: string) => boolean;\n getSnap: (id: string) => Snap | undefined;\n getAccountByAddress: (\n address: CaipAccountId,\n ) => InternalAccount | undefined;\n },\n) {\n walkJsx(node, (childNode) => {\n switch (childNode.type) {\n case 'Link':\n validateLink(childNode.props.href, isOnPhishingList, getSnap);\n break;\n case 'AssetSelector':\n validateAssetSelector(\n // We assume that the address part of the CAIP-10 account ID are the same, as\n // that is already validated in the struct.\n childNode.props.addresses[0],\n getAccountByAddress,\n );\n break;\n default:\n break;\n }\n });\n}\n\n/**\n * Calculate the total length of all text in the component.\n *\n * @param component - A custom UI component.\n * @returns The total length of all text components in the component.\n */\nexport function getTotalTextLength(component: Component): number {\n const { type } = component;\n\n switch (type) {\n case NodeType.Panel:\n return component.children.reduce<number>(\n (sum, node) => sum + getTotalTextLength(node),\n 0,\n );\n\n case NodeType.Row:\n return getTotalTextLength(component.value);\n\n case NodeType.Text:\n return component.value.length;\n\n default:\n return 0;\n }\n}\n\n/**\n * Check if a JSX element has children.\n *\n * @param element - A JSX element.\n * @returns `true` if the element has children, `false` otherwise.\n */\nexport function hasChildren<Element extends JSXElement>(\n element: Element,\n): element is Element & {\n props: { children: Nestable<JSXElement | string> };\n} {\n return hasProperty(element.props, 'children');\n}\n\n/**\n * Filter a JSX child to remove `null`, `undefined`, plain booleans, and empty\n * strings.\n *\n * @param child - The JSX child to filter.\n * @returns `true` if the child is not `null`, `undefined`, a plain boolean, or\n * an empty string, `false` otherwise.\n */\nfunction filterJsxChild(child: JSXElement | string | boolean | null): boolean {\n return Boolean(child) && child !== true;\n}\n\n/**\n * Get the children of a JSX element as an array. If the element has only one\n * child, the child is returned as an array.\n *\n * @param element - A JSX element.\n * @returns The children of the element.\n */\nexport function getJsxChildren(element: JSXElement): (JSXElement | string)[] {\n if (hasChildren(element)) {\n if (Array.isArray(element.props.children)) {\n // @ts-expect-error - Each member of the union type has signatures, but\n // none of those signatures are compatible with each other.\n return element.props.children.filter(filterJsxChild).flat(Infinity);\n }\n\n if (element.props.children) {\n return [element.props.children];\n }\n }\n\n return [];\n}\n\n/**\n * Walk a JSX tree and call a callback on each node.\n *\n * @param node - The JSX node to walk.\n * @param callback - The callback to call on each node.\n * @param depth - The current depth in the JSX tree for a walk.\n * @returns The result of the callback, if any.\n */\nexport function walkJsx<Value>(\n node: JSXElement | JSXElement[],\n callback: (node: JSXElement, depth: number) => Value | undefined,\n depth = 0,\n): Value | undefined {\n if (Array.isArray(node)) {\n for (const child of node) {\n const childResult = walkJsx(child, callback, depth);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n\n return undefined;\n }\n\n const result = callback(node, depth);\n if (result !== undefined) {\n return result;\n }\n\n if (\n hasProperty(node, 'props') &&\n isPlainObject(node.props) &&\n hasProperty(node.props, 'children')\n ) {\n const children = getJsxChildren(node);\n for (const child of children) {\n if (isPlainObject(child)) {\n const childResult = walkJsx(child, callback, depth + 1);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Serialise a JSX prop to a string.\n *\n * @param prop - The JSX prop.\n * @returns The serialised JSX prop.\n */\nfunction serialiseProp(prop: unknown): string {\n if (typeof prop === 'string') {\n return `\"${prop}\"`;\n }\n\n return `{${JSON.stringify(prop)}}`;\n}\n\n/**\n * Serialise JSX props to a string.\n *\n * @param props - The JSX props.\n * @returns The serialised JSX props.\n */\nfunction serialiseProps(props: Record<string, unknown>): string {\n return Object.entries(props)\n .filter(([key]) => key !== 'children')\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => ` ${key}=${serialiseProp(value)}`)\n .join('');\n}\n\n/**\n * Serialise a JSX node to a string.\n *\n * @param node - The JSX node.\n * @param indentation - The indentation level. Defaults to `0`. This should not\n * be set by the caller, as it is used for recursion.\n * @returns The serialised JSX node.\n */\nexport function serialiseJsx(node: SnapNode, indentation = 0): string {\n if (Array.isArray(node)) {\n return node.map((child) => serialiseJsx(child, indentation)).join('');\n }\n\n const indent = ' '.repeat(indentation);\n if (typeof node === 'string') {\n return `${indent}${node}\\n`;\n }\n\n if (!node) {\n return '';\n }\n\n const { type, props } = node as GenericSnapElement;\n const trailingNewline = indentation > 0 ? '\\n' : '';\n\n if (hasProperty(props, 'children')) {\n const children = serialiseJsx(props.children as SnapNode, indentation + 1);\n return `${indent}<${type}${serialiseProps(\n props,\n )}>\\n${children}${indent}</${type}>${trailingNewline}`;\n }\n\n return `${indent}<${type}${serialiseProps(props)} />${trailingNewline}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ui.mjs","sourceRoot":"","sources":["../src/ui.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,4BAA4B;AAa/C,OAAO,EACL,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,IAAI,EACJ,OAAO,EACP,OAAO,EACP,QAAQ,EACR,GAAG,EACH,MAAM,EACN,OAAO,EACR,gCAAgC;AACjC,OAAO,EACL,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,aAAa,EACd,wBAAwB;AACzB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,eAAe;AAK3C,OAAO,EAAE,UAAU,EAAE,oBAAgB;AACrC,OAAO,EAAE,gBAAgB,EAAE,kBAAc;AAEzC,MAAM,eAAe,GAAG,KAAM,CAAC,CAAC,QAAQ;AACxC,MAAM,iBAAiB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,OAA6C;IACrE,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,aAAa,CAAC;QACvB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,WAAW,CAAO,QAAgB;IACzC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,KAAmC;IACtD,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,MAAe;IAC7C,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,KAAY;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,OAAO,KAAC,IAAI,IAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,GAAI,CAAC;QAClE,CAAC;QAED,KAAK,MAAM;YACT,OAAO,KAAK,CAAC,IAAI,CAAC;QAEpB,KAAK,QAAQ;YACX,OAAO,CACL,KAAC,IAAI,cAED,sBAAsB;gBACpB,0DAA0D;gBAC1D,iEAAiE;gBACjE,mCAAmC;gBACnC,KAAK,CAAC,MAAiB,CACR,GAEd,CACR,CAAC;QAEJ,KAAK,IAAI;YACP,OAAO,CACL,KAAC,MAAM,cAEH,sBAAsB;gBACpB,0DAA0D;gBAC1D,iEAAiE;gBACjE,mCAAmC;gBACnC,KAAK,CAAC,MAAiB,CACN,GAEd,CACV,CAAC;QAEJ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa;IAEb,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAChD,MAAM,QAAQ,GACZ,EAAE,CAAC;IAEL,wEAAwE;IACxE,WAAW;IACX,mEAAmE;IACnE,UAAU,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;QAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC;YAED,MAAM,EAAE,MAAM,EAAE,GAAG,KAAyB,CAAC;YAC7C,yFAAyF;YACzF,QAAQ,CAAC,IAAI,CACX,GAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,CAKpC,CACL,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,CAI7C,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,SAAS,yBAAyB,CAAC,SAAoB;IACrD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,CACJ,QAAQ,IAAI,eAAe,EAC3B,gDACE,eAAe,GAAG,IACpB,MAAM,CACP,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,0BAA0B,CACxC,eAA0B;IAE1B,yBAAyB,CAAC,eAAe,CAAC,CAAC;IAE3C;;;;;;OAMG;IACH,SAAS,UAAU,CAAC,SAAoB;QACtC,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,KAAC,OAAO,IAAC,OAAO,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAE/C,KAAK,QAAQ,CAAC,MAAM;gBAClB,OAAO,CACL,KAAC,MAAM,IACL,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,EAC5C,IAAI,EAAE,SAAS,CAAC,UAAU,YAEzB,SAAS,CAAC,KAAK,GACT,CACV,CAAC;YAEJ,KAAK,QAAQ,CAAC,QAAQ;gBACpB,OAAO,CACL,KAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,GAAI,CACrE,CAAC;YAEJ,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,KAAC,OAAO,KAAG,CAAC;YAErB,KAAK,QAAQ,CAAC,IAAI;gBAChB,OAAO,CACL,KAAC,IAAI,IAAC,IAAI,EAAE,SAAS,CAAC,IAAI,YACvB,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAC3C,CACR,CAAC;YAEJ,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,KAAC,OAAO,IAAC,QAAQ,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAEhD,KAAK,QAAQ,CAAC,KAAK;gBACjB,qEAAqE;gBACrE,OAAO,KAAC,KAAK,IAAC,GAAG,EAAE,SAAS,CAAC,KAAK,GAAI,CAAC;YAEzC,KAAK,QAAQ,CAAC,KAAK;gBACjB,OAAO,CACL,KAAC,KAAK,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,YACnD,KAAC,KAAK,IACJ,IAAI,EAAE,SAAS,CAAC,IAAI,EACpB,IAAI,EAAE,SAAS,CAAC,SAAS,EACzB,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,WAAW,EAAE,SAAS,CAAC,WAAW,GAClC,GACI,CACT,CAAC;YAEJ,KAAK,QAAQ,CAAC,KAAK;gBACjB,sCAAsC;gBACtC,OAAO,CACL,KAAC,GAAG,IAAC,QAAQ,EAAE,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,GAAI,CACnE,CAAC;YAEJ,KAAK,QAAQ,CAAC,GAAG;gBACf,OAAO,CACL,KAAC,GAAG,IAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,YACpD,UAAU,CAAC,SAAS,CAAC,KAAK,CAAgB,GACvC,CACP,CAAC;YAEJ,KAAK,QAAQ,CAAC,OAAO;gBACnB,OAAO,KAAC,OAAO,KAAG,CAAC;YAErB,KAAK,QAAQ,CAAC,IAAI;gBAChB,OAAO,KAAC,IAAI,cAAE,WAAW,CAAC,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,GAAQ,CAAC;YAEtE,4BAA4B;YAC5B;gBACE,OAAO,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC,eAAe,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,oDAAoD;IACpD,wEAAwE;IACxE,WAAW;IACX,mEAAmE;IACnE,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,KAAoB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,gBAA0C,EAC1C,OAAyC;IAEzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CACJ,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EACxC,4BAA4B,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC5D,CAAC;QAEF,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACpB,MAAM,CACJ,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EACxB,+CAA+C,CAChD,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrC,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,MAAM,IAAI,GAAG,WAAW,QAAQ,EAAE,CAAC;gBACnC,MAAM,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;YACvE,CAAC;YAED,OAAO;QACT,CAAC;QAED,MAAM,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,gBACE,KAAK,EAAE,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,sBACpD,EAAE,CACH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,gBAA0C,EAC1C,OAAyC;IAEzC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAsB,EACtB,mBAA4E;IAE5E,MAAM,OAAO,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7C,MAAM,CAAC,OAAO,EAAE,uCAAuC,OAAO,EAAE,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAgB,EAChB,EACE,gBAAgB,EAChB,OAAO,EACP,mBAAmB,EACnB,aAAa,GAQd;IAED,OAAO,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,EAAE;QAC1B,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;YACvB,KAAK,MAAM;gBACT,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;gBAC9D,MAAM;YACR,KAAK,eAAe;gBAClB,qBAAqB;gBACnB,6EAA6E;gBAC7E,2CAA2C;gBAC3C,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAC5B,mBAAmB,CACpB,CAAC;gBACF,MAAM;YACR,KAAK,OAAO,CAAC,CAAC,CAAC;gBACb,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC;gBAChC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,CACJ,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,aAAa,CAAC,0BAA0B,CAAC,CAAC,EAC9D,yFAAyF,CAC1F,CAAC;gBACF,MAAM;YACR,CAAC;YACD;gBACE,MAAM;QACV,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,SAAoB;IACrD,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;IAE3B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC,KAAK;YACjB,OAAO,SAAS,CAAC,QAAQ,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,EAC7C,CAAC,CACF,CAAC;QAEJ,KAAK,QAAQ,CAAC,GAAG;YACf,OAAO,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE7C,KAAK,QAAQ,CAAC,IAAI;YAChB,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;QAEhC;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,OAAgB;IAIhB,OAAO,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,KAA2C;IACjE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC;AAC1C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,OAAmB;IAChD,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1C,uEAAuE;YACvE,2DAA2D;YAC3D,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CACrB,IAA+B,EAC/B,QAAgE,EAChE,KAAK,GAAG,CAAC;IAET,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,IAAI,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,OAAO,WAAW,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IACE,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC;QAC1B,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;QACzB,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,EACnC,CAAC;QACD,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;QACtC,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;gBACxD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC9B,OAAO,WAAW,CAAC;gBACrB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAS,aAAa,CAAC,IAAa;IAClC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,IAAI,IAAI,GAAG,CAAC;IACrB,CAAC;IAED,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,KAA8B;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACzB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,UAAU,CAAC;SACrC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;SACxD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAc,EAAE,WAAW,GAAG,CAAC;IAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,GAAG,MAAM,GAAG,IAAI,IAAI,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAA0B,CAAC;IACnD,MAAM,eAAe,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAEpD,IAAI,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,QAAoB,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;QAC3E,OAAO,GAAG,MAAM,IAAI,IAAI,GAAG,cAAc,CACvC,KAAK,CACN,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,IAAI,eAAe,EAAE,CAAC;IACzD,CAAC;IAED,OAAO,GAAG,MAAM,IAAI,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,eAAe,EAAE,CAAC;AAC1E,CAAC","sourcesContent":["import type { CaipAccountId, Component } from '@metamask/snaps-sdk';\nimport { NodeType } from '@metamask/snaps-sdk';\nimport type {\n BoldChildren,\n GenericSnapElement,\n ItalicChildren,\n JSXElement,\n LinkElement,\n Nestable,\n RowChildren,\n SnapNode,\n StandardFormattingElement,\n TextChildren,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n Italic,\n Link,\n Bold,\n Row,\n Text,\n Field,\n Image,\n Input,\n Heading,\n Form,\n Divider,\n Spinner,\n Copyable,\n Box,\n Button,\n Address,\n} from '@metamask/snaps-sdk/jsx';\nimport {\n assert,\n assertExhaustive,\n hasProperty,\n isPlainObject,\n} from '@metamask/utils';\nimport { lexer, walkTokens } from 'marked';\nimport type { Token, Tokens } from 'marked';\n\nimport type { InternalAccount } from './account';\nimport type { Snap } from './snaps';\nimport { isValidUrl } from './types';\nimport { parseMetaMaskUrl } from './url';\n\nconst MAX_TEXT_LENGTH = 50_000; // 50 kb\nconst ALLOWED_PROTOCOLS = ['https:', 'mailto:', 'metamask:'];\n\n/**\n * Get the button variant from a legacy button component variant.\n *\n * @param variant - The legacy button component variant.\n * @returns The button variant.\n */\nfunction getButtonVariant(variant?: 'primary' | 'secondary' | undefined) {\n switch (variant) {\n case 'primary':\n return 'primary';\n case 'secondary':\n return 'destructive';\n default:\n return undefined;\n }\n}\n\n/**\n * Get the children of a JSX element. If there is only one child, the child is\n * returned directly. Otherwise, the children are returned as an array.\n *\n * @param elements - The JSX elements.\n * @returns The child or children.\n */\nfunction getChildren<Type>(elements: Type[]) {\n if (elements.length === 1) {\n return elements[0];\n }\n\n return elements;\n}\n\n/**\n * Get the text of a link token.\n *\n * @param token - The link token.\n * @returns The text of the link token.\n */\nfunction getLinkText(token: Tokens.Link | Tokens.Generic) {\n if (token.tokens && token.tokens.length > 0) {\n return getChildren(token.tokens.flatMap(getTextChildFromToken));\n }\n\n return token.href;\n}\n\n/**\n * Get the text child from a list of markdown tokens.\n *\n * @param tokens - The markdown tokens.\n * @returns The text child.\n */\nfunction getTextChildFromTokens(tokens: Token[]) {\n return getChildren(tokens.flatMap(getTextChildFromToken));\n}\n\n/**\n * Get the text child from a markdown token.\n *\n * @param token - The markdown token.\n * @returns The text child.\n */\nfunction getTextChildFromToken(token: Token): TextChildren {\n switch (token.type) {\n case 'link': {\n return <Link href={token.href} children={getLinkText(token)} />;\n }\n\n case 'text':\n return token.text;\n\n case 'strong':\n return (\n <Bold>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as BoldChildren\n }\n </Bold>\n );\n\n case 'em':\n return (\n <Italic>\n {\n getTextChildFromTokens(\n // Due to the way `marked` is typed, `token.tokens` can be\n // `undefined`, but it's a required field of `Tokens.Bold`, so we\n // can safely cast it to `Token[]`.\n token.tokens as Token[],\n ) as ItalicChildren\n }\n </Italic>\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get all text children from a markdown string.\n *\n * @param value - The markdown string.\n * @returns The text children.\n */\nexport function getTextChildren(\n value: string,\n): (string | StandardFormattingElement | LinkElement)[] {\n const rootTokens = lexer(value, { gfm: false });\n const children: (string | StandardFormattingElement | LinkElement | null)[] =\n [];\n\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(rootTokens, (token) => {\n if (token.type === 'paragraph') {\n if (children.length > 0) {\n children.push('\\n\\n');\n }\n\n const { tokens } = token as Tokens.Paragraph;\n // We do not need to consider nesting deeper than 1 level here and we can therefore cast.\n children.push(\n ...(tokens.flatMap(getTextChildFromToken) as (\n | string\n | StandardFormattingElement\n | LinkElement\n | null\n )[]),\n );\n }\n });\n\n return children.filter((child) => child !== null) as (\n | string\n | StandardFormattingElement\n | LinkElement\n )[];\n}\n\n/**\n * Validate the text size of a component. The text size is the total length of\n * all text in the component.\n *\n * @param component - The component to validate.\n * @throws An error if the text size exceeds the maximum allowed size.\n */\nfunction validateComponentTextSize(component: Component) {\n const textSize = getTotalTextLength(component);\n assert(\n textSize <= MAX_TEXT_LENGTH,\n `The text in a Snap UI may not be larger than ${\n MAX_TEXT_LENGTH / 1000\n } kB.`,\n );\n}\n\n/**\n * Get a JSX element from a legacy UI component. This supports all legacy UI\n * components, and maps them to their JSX equivalents where possible.\n *\n * This function validates the text size of the component, but does not validate\n * the total size. The total size of the component should be validated before\n * calling this function.\n *\n * @param legacyComponent - The legacy UI component.\n * @returns The JSX element.\n */\nexport function getJsxElementFromComponent(\n legacyComponent: Component,\n): JSXElement {\n validateComponentTextSize(legacyComponent);\n\n /**\n * Get the JSX element for a component. This function is recursive and will\n * call itself for child components.\n *\n * @param component - The component to convert to a JSX element.\n * @returns The JSX element.\n */\n function getElement(component: Component) {\n switch (component.type) {\n case NodeType.Address:\n return <Address address={component.value} />;\n\n case NodeType.Button:\n return (\n <Button\n name={component.name}\n variant={getButtonVariant(component.variant)}\n type={component.buttonType}\n >\n {component.value}\n </Button>\n );\n\n case NodeType.Copyable:\n return (\n <Copyable value={component.value} sensitive={component.sensitive} />\n );\n\n case NodeType.Divider:\n return <Divider />;\n\n case NodeType.Form:\n return (\n <Form name={component.name}>\n {getChildren(component.children.map(getElement))}\n </Form>\n );\n\n case NodeType.Heading:\n return <Heading children={component.value} />;\n\n case NodeType.Image:\n // `Image` supports `alt`, but the legacy `Image` component does not.\n return <Image src={component.value} />;\n\n case NodeType.Input:\n return (\n <Field label={component.label} error={component.error}>\n <Input\n name={component.name}\n type={component.inputType}\n value={component.value}\n placeholder={component.placeholder}\n />\n </Field>\n );\n\n case NodeType.Panel:\n // `Panel` is renamed to `Box` in JSX.\n return (\n <Box children={getChildren(component.children.map(getElement))} />\n );\n\n case NodeType.Row:\n return (\n <Row label={component.label} variant={component.variant}>\n {getElement(component.value) as RowChildren}\n </Row>\n );\n\n case NodeType.Spinner:\n return <Spinner />;\n\n case NodeType.Text:\n return <Text>{getChildren(getTextChildren(component.value))}</Text>;\n\n /* istanbul ignore next 2 */\n default:\n return assertExhaustive(component);\n }\n }\n\n return getElement(legacyComponent);\n}\n\n/**\n * Extract all links from a Markdown text string using the `marked` lexer.\n *\n * @param text - The markdown text string.\n * @returns A list of URLs linked to in the string.\n */\nfunction getMarkdownLinks(text: string) {\n const tokens = lexer(text, { gfm: false });\n const links: Tokens.Link[] = [];\n\n // Walk the lexed tokens and collect all link tokens\n // TODO: Either fix this lint violation or explain why it's necessary to\n // ignore.\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n walkTokens(tokens, (token) => {\n if (token.type === 'link') {\n links.push(token as Tokens.Link);\n }\n });\n\n return links;\n}\n\n/**\n * Validate a link against the phishing list.\n *\n * @param link - The link to validate.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the link is invalid.\n */\nexport function validateLink(\n link: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n try {\n const url = new URL(link);\n assert(\n ALLOWED_PROTOCOLS.includes(url.protocol),\n `Protocol must be one of: ${ALLOWED_PROTOCOLS.join(', ')}.`,\n );\n\n if (url.protocol === 'metamask:') {\n const linkData = parseMetaMaskUrl(link);\n if (linkData.snapId) {\n assert(\n getSnap(linkData.snapId),\n 'The Snap being navigated to is not installed.',\n );\n }\n } else if (url.protocol === 'mailto:') {\n const emails = url.pathname.split(',');\n for (const email of emails) {\n const hostname = email.split('@')[1];\n assert(!hostname.includes(':'));\n const href = `https://${hostname}`;\n assert(!isOnPhishingList(href), 'The specified URL is not allowed.');\n }\n\n return;\n }\n\n assert(!isOnPhishingList(url.href), 'The specified URL is not allowed.');\n } catch (error) {\n throw new Error(\n `Invalid URL: ${\n error?.code === 'ERR_ASSERTION' ? error.message : 'Unable to parse URL.'\n }`,\n );\n }\n}\n\n/**\n * Search for Markdown links in a string and checks them against the phishing\n * list.\n *\n * @param text - The text to verify.\n * @param isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param getSnap - The function that returns a snap if installed, undefined otherwise.\n * @throws If the text contains a link that is not allowed.\n */\nexport function validateTextLinks(\n text: string,\n isOnPhishingList: (url: string) => boolean,\n getSnap: (id: string) => Snap | undefined,\n) {\n const links = getMarkdownLinks(text);\n\n for (const link of links) {\n validateLink(link.href, isOnPhishingList, getSnap);\n }\n}\n\n/**\n * Validate the asset selector component.\n *\n * @param address - The address of the account to pull the assets from.\n * @param getAccountByAddress - A function to get an account by its address.\n *\n * @throws If the asset selector is invalid.\n */\nexport function validateAssetSelector(\n address: CaipAccountId,\n getAccountByAddress: (address: CaipAccountId) => InternalAccount | undefined,\n) {\n const account = getAccountByAddress(address);\n\n assert(account, `Could not find account for address: ${address}`);\n}\n\n/**\n * Walk a JSX tree and validate elements.\n * This function validates Links and AssetSelectors.\n *\n * @param node - The JSX node to walk.\n * @param hooks - The hooks to use for validation.\n * @param hooks.isOnPhishingList - The function that checks the link against the\n * phishing list.\n * @param hooks.getSnap - The function that returns a snap if installed, undefined otherwise.\n * @param hooks.getAccountByAddress - The function that returns an account by address.\n * @param hooks.hasPermission - A function that checks whether the Snap has a given permission.\n */\nexport function validateJsxElements(\n node: JSXElement,\n {\n isOnPhishingList,\n getSnap,\n getAccountByAddress,\n hasPermission,\n }: {\n isOnPhishingList: (url: string) => boolean;\n getSnap: (id: string) => Snap | undefined;\n getAccountByAddress: (\n address: CaipAccountId,\n ) => InternalAccount | undefined;\n hasPermission: (permission: string) => boolean;\n },\n) {\n walkJsx(node, (childNode) => {\n switch (childNode.type) {\n case 'Link':\n validateLink(childNode.props.href, isOnPhishingList, getSnap);\n break;\n case 'AssetSelector':\n validateAssetSelector(\n // We assume that the address part of the CAIP-10 account ID are the same, as\n // that is already validated in the struct.\n childNode.props.addresses[0],\n getAccountByAddress,\n );\n break;\n case 'Image': {\n const { src } = childNode.props;\n const isUrl = isValidUrl(src);\n assert(\n !isUrl || (isUrl && hasPermission('endowment:network-access')),\n 'Using external images is only permitted with the `endowment:network-access` permission.',\n );\n break;\n }\n default:\n break;\n }\n });\n}\n\n/**\n * Calculate the total length of all text in the component.\n *\n * @param component - A custom UI component.\n * @returns The total length of all text components in the component.\n */\nexport function getTotalTextLength(component: Component): number {\n const { type } = component;\n\n switch (type) {\n case NodeType.Panel:\n return component.children.reduce<number>(\n (sum, node) => sum + getTotalTextLength(node),\n 0,\n );\n\n case NodeType.Row:\n return getTotalTextLength(component.value);\n\n case NodeType.Text:\n return component.value.length;\n\n default:\n return 0;\n }\n}\n\n/**\n * Check if a JSX element has children.\n *\n * @param element - A JSX element.\n * @returns `true` if the element has children, `false` otherwise.\n */\nexport function hasChildren<Element extends JSXElement>(\n element: Element,\n): element is Element & {\n props: { children: Nestable<JSXElement | string> };\n} {\n return hasProperty(element.props, 'children');\n}\n\n/**\n * Filter a JSX child to remove `null`, `undefined`, plain booleans, and empty\n * strings.\n *\n * @param child - The JSX child to filter.\n * @returns `true` if the child is not `null`, `undefined`, a plain boolean, or\n * an empty string, `false` otherwise.\n */\nfunction filterJsxChild(child: JSXElement | string | boolean | null): boolean {\n return Boolean(child) && child !== true;\n}\n\n/**\n * Get the children of a JSX element as an array. If the element has only one\n * child, the child is returned as an array.\n *\n * @param element - A JSX element.\n * @returns The children of the element.\n */\nexport function getJsxChildren(element: JSXElement): (JSXElement | string)[] {\n if (hasChildren(element)) {\n if (Array.isArray(element.props.children)) {\n // @ts-expect-error - Each member of the union type has signatures, but\n // none of those signatures are compatible with each other.\n return element.props.children.filter(filterJsxChild).flat(Infinity);\n }\n\n if (element.props.children) {\n return [element.props.children];\n }\n }\n\n return [];\n}\n\n/**\n * Walk a JSX tree and call a callback on each node.\n *\n * @param node - The JSX node to walk.\n * @param callback - The callback to call on each node.\n * @param depth - The current depth in the JSX tree for a walk.\n * @returns The result of the callback, if any.\n */\nexport function walkJsx<Value>(\n node: JSXElement | JSXElement[],\n callback: (node: JSXElement, depth: number) => Value | undefined,\n depth = 0,\n): Value | undefined {\n if (Array.isArray(node)) {\n for (const child of node) {\n const childResult = walkJsx(child, callback, depth);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n\n return undefined;\n }\n\n const result = callback(node, depth);\n if (result !== undefined) {\n return result;\n }\n\n if (\n hasProperty(node, 'props') &&\n isPlainObject(node.props) &&\n hasProperty(node.props, 'children')\n ) {\n const children = getJsxChildren(node);\n for (const child of children) {\n if (isPlainObject(child)) {\n const childResult = walkJsx(child, callback, depth + 1);\n if (childResult !== undefined) {\n return childResult;\n }\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Serialise a JSX prop to a string.\n *\n * @param prop - The JSX prop.\n * @returns The serialised JSX prop.\n */\nfunction serialiseProp(prop: unknown): string {\n if (typeof prop === 'string') {\n return `\"${prop}\"`;\n }\n\n return `{${JSON.stringify(prop)}}`;\n}\n\n/**\n * Serialise JSX props to a string.\n *\n * @param props - The JSX props.\n * @returns The serialised JSX props.\n */\nfunction serialiseProps(props: Record<string, unknown>): string {\n return Object.entries(props)\n .filter(([key]) => key !== 'children')\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([key, value]) => ` ${key}=${serialiseProp(value)}`)\n .join('');\n}\n\n/**\n * Serialise a JSX node to a string.\n *\n * @param node - The JSX node.\n * @param indentation - The indentation level. Defaults to `0`. This should not\n * be set by the caller, as it is used for recursion.\n * @returns The serialised JSX node.\n */\nexport function serialiseJsx(node: SnapNode, indentation = 0): string {\n if (Array.isArray(node)) {\n return node.map((child) => serialiseJsx(child, indentation)).join('');\n }\n\n const indent = ' '.repeat(indentation);\n if (typeof node === 'string') {\n return `${indent}${node}\\n`;\n }\n\n if (!node) {\n return '';\n }\n\n const { type, props } = node as GenericSnapElement;\n const trailingNewline = indentation > 0 ? '\\n' : '';\n\n if (hasProperty(props, 'children')) {\n const children = serialiseJsx(props.children as SnapNode, indentation + 1);\n return `${indent}<${type}${serialiseProps(\n props,\n )}>\\n${children}${indent}</${type}>${trailingNewline}`;\n }\n\n return `${indent}<${type}${serialiseProps(props)} />${trailingNewline}`;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-utils",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.7.0",
|
|
4
4
|
"description": "A collection of utilities for MetaMask Snaps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"MetaMask",
|
|
@@ -85,8 +85,8 @@
|
|
|
85
85
|
"@metamask/permission-controller": "^12.1.1",
|
|
86
86
|
"@metamask/rpc-errors": "^7.0.3",
|
|
87
87
|
"@metamask/slip44": "^4.3.0",
|
|
88
|
-
"@metamask/snaps-registry": "^
|
|
89
|
-
"@metamask/snaps-sdk": "^10.
|
|
88
|
+
"@metamask/snaps-registry": "^4.0.0",
|
|
89
|
+
"@metamask/snaps-sdk": "^10.3.0",
|
|
90
90
|
"@metamask/superstruct": "^3.2.1",
|
|
91
91
|
"@metamask/utils": "^11.8.1",
|
|
92
92
|
"@noble/hashes": "^1.7.1",
|