@metamask/snaps-rpc-methods 11.6.0 → 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 +10 -1
- package/dist/permitted/createInterface.d.cts +2 -2
- package/dist/permitted/createInterface.d.mts +2 -2
- package/dist/permitted/updateInterface.d.cts +2 -2
- package/dist/permitted/updateInterface.d.mts +2 -2
- package/dist/restricted/dialog.d.cts +4 -4
- package/dist/restricted/dialog.d.mts +4 -4
- package/dist/restricted/getBip32Entropy.cjs +5 -1
- package/dist/restricted/getBip32Entropy.cjs.map +1 -1
- package/dist/restricted/getBip32Entropy.d.cts +12 -1
- package/dist/restricted/getBip32Entropy.d.cts.map +1 -1
- package/dist/restricted/getBip32Entropy.d.mts +12 -1
- package/dist/restricted/getBip32Entropy.d.mts.map +1 -1
- package/dist/restricted/getBip32Entropy.mjs +5 -1
- package/dist/restricted/getBip32Entropy.mjs.map +1 -1
- package/dist/restricted/getBip32PublicKey.cjs +5 -1
- package/dist/restricted/getBip32PublicKey.cjs.map +1 -1
- package/dist/restricted/getBip32PublicKey.d.cts +12 -1
- package/dist/restricted/getBip32PublicKey.d.cts.map +1 -1
- package/dist/restricted/getBip32PublicKey.d.mts +12 -1
- package/dist/restricted/getBip32PublicKey.d.mts.map +1 -1
- package/dist/restricted/getBip32PublicKey.mjs +5 -1
- package/dist/restricted/getBip32PublicKey.mjs.map +1 -1
- package/dist/restricted/getBip44Entropy.cjs +5 -6
- package/dist/restricted/getBip44Entropy.cjs.map +1 -1
- package/dist/restricted/getBip44Entropy.d.cts +12 -1
- package/dist/restricted/getBip44Entropy.d.cts.map +1 -1
- package/dist/restricted/getBip44Entropy.d.mts +12 -1
- package/dist/restricted/getBip44Entropy.d.mts.map +1 -1
- package/dist/restricted/getBip44Entropy.mjs +5 -6
- package/dist/restricted/getBip44Entropy.mjs.map +1 -1
- package/dist/restricted/getEntropy.cjs +5 -1
- package/dist/restricted/getEntropy.cjs.map +1 -1
- package/dist/restricted/getEntropy.d.cts +12 -1
- package/dist/restricted/getEntropy.d.cts.map +1 -1
- package/dist/restricted/getEntropy.d.mts +12 -1
- package/dist/restricted/getEntropy.d.mts.map +1 -1
- package/dist/restricted/getEntropy.mjs +5 -1
- package/dist/restricted/getEntropy.mjs.map +1 -1
- package/dist/restricted/manageState.cjs +4 -1
- package/dist/restricted/manageState.cjs.map +1 -1
- package/dist/restricted/manageState.d.cts +5 -1
- package/dist/restricted/manageState.d.cts.map +1 -1
- package/dist/restricted/manageState.d.mts +5 -1
- package/dist/restricted/manageState.d.mts.map +1 -1
- package/dist/restricted/manageState.mjs +4 -1
- package/dist/restricted/manageState.mjs.map +1 -1
- package/dist/restricted/notify.cjs +49 -5
- package/dist/restricted/notify.cjs.map +1 -1
- package/dist/restricted/notify.d.cts +311 -13
- package/dist/restricted/notify.d.cts.map +1 -1
- package/dist/restricted/notify.d.mts +311 -13
- package/dist/restricted/notify.d.mts.map +1 -1
- package/dist/restricted/notify.mjs +52 -8
- package/dist/restricted/notify.mjs.map +1 -1
- package/dist/utils.cjs +8 -4
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +12 -3
- package/dist/utils.d.cts.map +1 -1
- package/dist/utils.d.mts +12 -3
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.mjs +8 -4
- package/dist/utils.mjs.map +1 -1
- package/package.json +5 -5
|
@@ -1,21 +1,314 @@
|
|
|
1
1
|
import type { PermissionSpecificationBuilder, RestrictedMethodOptions, ValidPermissionSpecification } from "@metamask/permission-controller";
|
|
2
2
|
import { PermissionType } from "@metamask/permission-controller";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
3
|
+
import type { NotifyParams, NotifyResult, InterfaceContext, ComponentOrElement } from "@metamask/snaps-sdk";
|
|
4
|
+
import { ContentType } from "@metamask/snaps-sdk";
|
|
5
5
|
import { type Snap } from "@metamask/snaps-utils";
|
|
6
|
+
import type { InferMatching } from "@metamask/snaps-utils";
|
|
6
7
|
import type { NonEmptyArray } from "@metamask/utils";
|
|
7
8
|
import { type MethodHooksObject } from "../utils.mjs";
|
|
8
9
|
declare const methodName = "snap_notify";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* Enum type to determine notification type.
|
|
12
|
-
*/
|
|
13
|
-
type: EnumToUnion<NotificationType>;
|
|
14
|
-
/**
|
|
15
|
-
* A message to show on the notification.
|
|
16
|
-
*/
|
|
10
|
+
declare const NotificationParametersStruct: import("@metamask/superstruct").Struct<{
|
|
11
|
+
type: "native";
|
|
17
12
|
message: string;
|
|
18
|
-
}
|
|
13
|
+
} | {
|
|
14
|
+
type: "inApp";
|
|
15
|
+
message: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: "inApp";
|
|
18
|
+
message: string;
|
|
19
|
+
content: import("@metamask/snaps-sdk").Panel | 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").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FieldProps, "Field"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FileInputProps, "FileInput"> | 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<import("@metamask/snaps-sdk/jsx").SelectorProps, "Selector"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoldProps, "Bold"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ItalicProps, "Italic"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AvatarProps, "Avatar"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AddressProps, "Address"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoxProps, "Box"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CardProps, "Card"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ContainerProps, "Container"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CopyableProps, "Copyable"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Divider"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").IconProps, "Icon"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").LinkProps, "Link"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").RowProps, "Row"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").SectionProps, "Section"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Spinner"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | {
|
|
20
|
+
type: import("@metamask/snaps-sdk").NodeType.Copyable;
|
|
21
|
+
value: string;
|
|
22
|
+
sensitive?: boolean | undefined;
|
|
23
|
+
} | {
|
|
24
|
+
type: import("@metamask/snaps-sdk").NodeType.Divider;
|
|
25
|
+
} | {
|
|
26
|
+
type: import("@metamask/snaps-sdk").NodeType.Heading; /**
|
|
27
|
+
* @param snapId - The ID of the Snap that created the notification.
|
|
28
|
+
* @param args - The notification arguments.
|
|
29
|
+
*/
|
|
30
|
+
value: string;
|
|
31
|
+
} | {
|
|
32
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
33
|
+
value: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: import("@metamask/snaps-sdk").NodeType.Spinner;
|
|
36
|
+
} | {
|
|
37
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
38
|
+
value: string;
|
|
39
|
+
markdown?: boolean | undefined;
|
|
40
|
+
} | {
|
|
41
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
42
|
+
value: `0x${string}`;
|
|
43
|
+
} | {
|
|
44
|
+
type: import("@metamask/snaps-sdk").NodeType.Row;
|
|
45
|
+
value: {
|
|
46
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
47
|
+
value: string;
|
|
48
|
+
} | {
|
|
49
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
50
|
+
value: string;
|
|
51
|
+
markdown?: boolean | undefined;
|
|
52
|
+
} | {
|
|
53
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
54
|
+
value: `0x${string}`;
|
|
55
|
+
};
|
|
56
|
+
label: string;
|
|
57
|
+
variant?: "default" | "warning" | "critical" | undefined;
|
|
58
|
+
} | {
|
|
59
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
60
|
+
name: string;
|
|
61
|
+
error?: string | undefined;
|
|
62
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
63
|
+
value?: string | undefined;
|
|
64
|
+
label?: string | undefined;
|
|
65
|
+
placeholder?: string | undefined;
|
|
66
|
+
} | {
|
|
67
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
68
|
+
value: string;
|
|
69
|
+
variant?: "primary" | "secondary" | undefined;
|
|
70
|
+
name?: string | undefined;
|
|
71
|
+
buttonType?: "button" | "submit" | undefined;
|
|
72
|
+
} | {
|
|
73
|
+
type: import("@metamask/snaps-sdk").NodeType.Form;
|
|
74
|
+
name: string;
|
|
75
|
+
children: ({
|
|
76
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
77
|
+
name: string;
|
|
78
|
+
error?: string | undefined;
|
|
79
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
80
|
+
value?: string | undefined;
|
|
81
|
+
label?: string | undefined;
|
|
82
|
+
placeholder?: string | undefined;
|
|
83
|
+
} | {
|
|
84
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
85
|
+
value: string;
|
|
86
|
+
variant?: "primary" | "secondary" | undefined;
|
|
87
|
+
name?: string | undefined;
|
|
88
|
+
buttonType?: "button" | "submit" | undefined;
|
|
89
|
+
})[];
|
|
90
|
+
} | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
91
|
+
src: string;
|
|
92
|
+
alt?: string | undefined;
|
|
93
|
+
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
94
|
+
name: string;
|
|
95
|
+
value?: string | undefined;
|
|
96
|
+
children: import("@metamask/snaps-sdk/jsx").SnapsChildren<import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
97
|
+
value: string;
|
|
98
|
+
children: string;
|
|
99
|
+
}, "Radio">>;
|
|
100
|
+
}, "RadioGroup"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
101
|
+
children: import("@metamask/snaps-sdk/jsx").StringElement;
|
|
102
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
103
|
+
}, "Heading">;
|
|
104
|
+
title: string;
|
|
105
|
+
footerLink?: {
|
|
106
|
+
text: string;
|
|
107
|
+
href: string;
|
|
108
|
+
} | undefined;
|
|
109
|
+
}, [head: import("@metamask/superstruct").Struct<{
|
|
110
|
+
type: "inApp";
|
|
111
|
+
message: string;
|
|
112
|
+
}, {
|
|
113
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
114
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
115
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
116
|
+
type: "inApp";
|
|
117
|
+
message: string;
|
|
118
|
+
content: import("@metamask/snaps-sdk").Panel | 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").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FieldProps, "Field"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FileInputProps, "FileInput"> | 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<import("@metamask/snaps-sdk/jsx").SelectorProps, "Selector"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoldProps, "Bold"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ItalicProps, "Italic"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AvatarProps, "Avatar"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AddressProps, "Address"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoxProps, "Box"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CardProps, "Card"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ContainerProps, "Container"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CopyableProps, "Copyable"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Divider"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").IconProps, "Icon"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").LinkProps, "Link"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").RowProps, "Row"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").SectionProps, "Section"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Spinner"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | {
|
|
119
|
+
type: import("@metamask/snaps-sdk").NodeType.Copyable;
|
|
120
|
+
value: string;
|
|
121
|
+
sensitive?: boolean | undefined;
|
|
122
|
+
} | {
|
|
123
|
+
type: import("@metamask/snaps-sdk").NodeType.Divider;
|
|
124
|
+
} | {
|
|
125
|
+
type: import("@metamask/snaps-sdk").NodeType.Heading; /**
|
|
126
|
+
* @param snapId - The ID of the Snap that created the notification.
|
|
127
|
+
* @param args - The notification arguments.
|
|
128
|
+
*/
|
|
129
|
+
value: string;
|
|
130
|
+
} | {
|
|
131
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
132
|
+
value: string;
|
|
133
|
+
} | {
|
|
134
|
+
type: import("@metamask/snaps-sdk").NodeType.Spinner;
|
|
135
|
+
} | {
|
|
136
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
137
|
+
value: string;
|
|
138
|
+
markdown?: boolean | undefined;
|
|
139
|
+
} | {
|
|
140
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
141
|
+
value: `0x${string}`;
|
|
142
|
+
} | {
|
|
143
|
+
type: import("@metamask/snaps-sdk").NodeType.Row;
|
|
144
|
+
value: {
|
|
145
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
146
|
+
value: string;
|
|
147
|
+
} | {
|
|
148
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
149
|
+
value: string;
|
|
150
|
+
markdown?: boolean | undefined;
|
|
151
|
+
} | {
|
|
152
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
153
|
+
value: `0x${string}`;
|
|
154
|
+
};
|
|
155
|
+
label: string;
|
|
156
|
+
variant?: "default" | "warning" | "critical" | undefined;
|
|
157
|
+
} | {
|
|
158
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
159
|
+
name: string;
|
|
160
|
+
error?: string | undefined;
|
|
161
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
162
|
+
value?: string | undefined;
|
|
163
|
+
label?: string | undefined;
|
|
164
|
+
placeholder?: string | undefined;
|
|
165
|
+
} | {
|
|
166
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
167
|
+
value: string;
|
|
168
|
+
variant?: "primary" | "secondary" | undefined;
|
|
169
|
+
name?: string | undefined;
|
|
170
|
+
buttonType?: "button" | "submit" | undefined;
|
|
171
|
+
} | {
|
|
172
|
+
type: import("@metamask/snaps-sdk").NodeType.Form;
|
|
173
|
+
name: string;
|
|
174
|
+
children: ({
|
|
175
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
176
|
+
name: string;
|
|
177
|
+
error?: string | undefined;
|
|
178
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
179
|
+
value?: string | undefined;
|
|
180
|
+
label?: string | undefined;
|
|
181
|
+
placeholder?: string | undefined;
|
|
182
|
+
} | {
|
|
183
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
184
|
+
value: string;
|
|
185
|
+
variant?: "primary" | "secondary" | undefined;
|
|
186
|
+
name?: string | undefined;
|
|
187
|
+
buttonType?: "button" | "submit" | undefined;
|
|
188
|
+
})[];
|
|
189
|
+
} | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
190
|
+
src: string;
|
|
191
|
+
alt?: string | undefined;
|
|
192
|
+
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
193
|
+
name: string;
|
|
194
|
+
value?: string | undefined;
|
|
195
|
+
children: import("@metamask/snaps-sdk/jsx").SnapsChildren<import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
196
|
+
value: string;
|
|
197
|
+
children: string;
|
|
198
|
+
}, "Radio">>;
|
|
199
|
+
}, "RadioGroup"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
200
|
+
children: import("@metamask/snaps-sdk/jsx").StringElement;
|
|
201
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
202
|
+
}, "Heading">;
|
|
203
|
+
title: string;
|
|
204
|
+
footerLink?: {
|
|
205
|
+
text: string;
|
|
206
|
+
href: string;
|
|
207
|
+
} | undefined;
|
|
208
|
+
}, {
|
|
209
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
210
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
211
|
+
content: import("@metamask/superstruct").Struct<import("@metamask/snaps-sdk").Panel | 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").FormProps, "Form"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FieldProps, "Field"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").FileInputProps, "FileInput"> | 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<import("@metamask/snaps-sdk/jsx").SelectorProps, "Selector"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoldProps, "Bold"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ItalicProps, "Italic"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AvatarProps, "Avatar"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").AddressProps, "Address"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").BoxProps, "Box"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CardProps, "Card"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").ContainerProps, "Container"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").CopyableProps, "Copyable"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Divider"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").IconProps, "Icon"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").LinkProps, "Link"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").RowProps, "Row"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").SectionProps, "Section"> | import("@metamask/snaps-sdk/jsx").SnapElement<Record<string, never>, "Spinner"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | {
|
|
212
|
+
type: import("@metamask/snaps-sdk").NodeType.Copyable;
|
|
213
|
+
value: string;
|
|
214
|
+
sensitive?: boolean | undefined;
|
|
215
|
+
} | {
|
|
216
|
+
type: import("@metamask/snaps-sdk").NodeType.Divider;
|
|
217
|
+
} | {
|
|
218
|
+
type: import("@metamask/snaps-sdk").NodeType.Heading; /**
|
|
219
|
+
* @param snapId - The ID of the Snap that created the notification.
|
|
220
|
+
* @param args - The notification arguments.
|
|
221
|
+
*/
|
|
222
|
+
value: string;
|
|
223
|
+
} | {
|
|
224
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
225
|
+
value: string;
|
|
226
|
+
} | {
|
|
227
|
+
type: import("@metamask/snaps-sdk").NodeType.Spinner;
|
|
228
|
+
} | {
|
|
229
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
230
|
+
value: string;
|
|
231
|
+
markdown?: boolean | undefined;
|
|
232
|
+
} | {
|
|
233
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
234
|
+
value: `0x${string}`;
|
|
235
|
+
} | {
|
|
236
|
+
type: import("@metamask/snaps-sdk").NodeType.Row;
|
|
237
|
+
value: {
|
|
238
|
+
type: import("@metamask/snaps-sdk").NodeType.Image;
|
|
239
|
+
value: string;
|
|
240
|
+
} | {
|
|
241
|
+
type: import("@metamask/snaps-sdk").NodeType.Text;
|
|
242
|
+
value: string;
|
|
243
|
+
markdown?: boolean | undefined;
|
|
244
|
+
} | {
|
|
245
|
+
type: import("@metamask/snaps-sdk").NodeType.Address;
|
|
246
|
+
value: `0x${string}`;
|
|
247
|
+
};
|
|
248
|
+
label: string;
|
|
249
|
+
variant?: "default" | "warning" | "critical" | undefined;
|
|
250
|
+
} | {
|
|
251
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
252
|
+
name: string;
|
|
253
|
+
error?: string | undefined;
|
|
254
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
255
|
+
value?: string | undefined;
|
|
256
|
+
label?: string | undefined;
|
|
257
|
+
placeholder?: string | undefined;
|
|
258
|
+
} | {
|
|
259
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
260
|
+
value: string;
|
|
261
|
+
variant?: "primary" | "secondary" | undefined;
|
|
262
|
+
name?: string | undefined;
|
|
263
|
+
buttonType?: "button" | "submit" | undefined;
|
|
264
|
+
} | {
|
|
265
|
+
type: import("@metamask/snaps-sdk").NodeType.Form;
|
|
266
|
+
name: string;
|
|
267
|
+
children: ({
|
|
268
|
+
type: import("@metamask/snaps-sdk").NodeType.Input;
|
|
269
|
+
name: string;
|
|
270
|
+
error?: string | undefined;
|
|
271
|
+
inputType?: "number" | "text" | "password" | undefined;
|
|
272
|
+
value?: string | undefined;
|
|
273
|
+
label?: string | undefined;
|
|
274
|
+
placeholder?: string | undefined;
|
|
275
|
+
} | {
|
|
276
|
+
type: import("@metamask/snaps-sdk").NodeType.Button;
|
|
277
|
+
value: string;
|
|
278
|
+
variant?: "primary" | "secondary" | undefined;
|
|
279
|
+
name?: string | undefined;
|
|
280
|
+
buttonType?: "button" | "submit" | undefined;
|
|
281
|
+
})[];
|
|
282
|
+
} | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
283
|
+
src: string;
|
|
284
|
+
alt?: string | undefined;
|
|
285
|
+
}, "Image"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
286
|
+
name: string;
|
|
287
|
+
value?: string | undefined;
|
|
288
|
+
children: import("@metamask/snaps-sdk/jsx").SnapsChildren<import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
289
|
+
value: string;
|
|
290
|
+
children: string;
|
|
291
|
+
}, "Radio">>;
|
|
292
|
+
}, "RadioGroup"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
293
|
+
children: import("@metamask/snaps-sdk/jsx").StringElement;
|
|
294
|
+
size?: "sm" | "md" | "lg" | undefined;
|
|
295
|
+
}, "Heading">, null>;
|
|
296
|
+
title: import("@metamask/superstruct").Struct<string, null>;
|
|
297
|
+
footerLink: import("@metamask/superstruct").Struct<{
|
|
298
|
+
text: string;
|
|
299
|
+
href: string;
|
|
300
|
+
} | undefined, {
|
|
301
|
+
href: import("@metamask/superstruct").Struct<string, null>;
|
|
302
|
+
text: import("@metamask/superstruct").Struct<string, null>;
|
|
303
|
+
}>;
|
|
304
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
305
|
+
type: "native";
|
|
306
|
+
message: string;
|
|
307
|
+
}, {
|
|
308
|
+
type: import("@metamask/superstruct").Struct<"native", null>;
|
|
309
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
310
|
+
}>]>;
|
|
311
|
+
export type NotificationArgs = InferMatching<typeof NotificationParametersStruct, NotifyParams>;
|
|
19
312
|
export type NotifyMethodHooks = {
|
|
20
313
|
/**
|
|
21
314
|
* @param snapId - The ID of the Snap that created the notification.
|
|
@@ -29,6 +322,7 @@ export type NotifyMethodHooks = {
|
|
|
29
322
|
showInAppNotification: (snapId: string, args: NotificationArgs) => Promise<null>;
|
|
30
323
|
isOnPhishingList: (url: string) => boolean;
|
|
31
324
|
maybeUpdatePhishingList: () => Promise<void>;
|
|
325
|
+
createInterface: (origin: string, content: ComponentOrElement, context?: InterfaceContext, contentType?: ContentType) => Promise<string>;
|
|
32
326
|
getSnap: (snapId: string) => Snap | undefined;
|
|
33
327
|
};
|
|
34
328
|
type SpecificationBuilderOptions = {
|
|
@@ -69,18 +363,22 @@ export declare const notifyBuilder: Readonly<{
|
|
|
69
363
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
70
364
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
71
365
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
366
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
72
367
|
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
73
368
|
* @returns The method implementation which returns `null` on success.
|
|
74
369
|
* @throws If the params are invalid.
|
|
75
370
|
*/
|
|
76
|
-
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, getSnap, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
371
|
+
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
77
372
|
/**
|
|
78
373
|
* Validates the notify method `params` and returns them cast to the correct
|
|
79
374
|
* type. Throws if validation fails.
|
|
80
375
|
*
|
|
81
376
|
* @param params - The unvalidated params object from the method request.
|
|
377
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
378
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
82
379
|
* @returns The validated method parameter object.
|
|
380
|
+
* @throws If the params are invalid.
|
|
83
381
|
*/
|
|
84
|
-
export declare function getValidatedParams(params: unknown): NotifyParams;
|
|
382
|
+
export declare function getValidatedParams(params: unknown, isOnPhishingList: NotifyMethodHooks['isOnPhishingList'], getSnap: NotifyMethodHooks['getSnap']): NotifyParams;
|
|
85
383
|
export {};
|
|
86
384
|
//# sourceMappingURL=notify.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.mts","sourceRoot":"","sources":["../../src/restricted/notify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,uBAAuB,EACvB,4BAA4B,EAC7B,wCAAwC;AACzC,OAAO,EAAE,cAAc,EAAe,wCAAwC;AAE9E,OAAO,
|
|
1
|
+
{"version":3,"file":"notify.d.mts","sourceRoot":"","sources":["../../src/restricted/notify.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
import { PermissionType, SubjectType } from "@metamask/permission-controller";
|
|
2
2
|
import { rpcErrors } from "@metamask/rpc-errors";
|
|
3
|
-
import { NotificationType } from "@metamask/snaps-sdk";
|
|
4
|
-
import { validateTextLinks } from "@metamask/snaps-utils";
|
|
5
|
-
import {
|
|
3
|
+
import { enumValue, NotificationType, union, ContentType, getErrorMessage, ComponentOrElementStruct } from "@metamask/snaps-sdk";
|
|
4
|
+
import { createUnion, validateLink, validateTextLinks } from "@metamask/snaps-utils";
|
|
5
|
+
import { object, string, optional } from "@metamask/superstruct";
|
|
6
|
+
import { hasProperty, isObject } from "@metamask/utils";
|
|
6
7
|
const methodName = 'snap_notify';
|
|
8
|
+
const NativeNotificationStruct = object({
|
|
9
|
+
type: enumValue(NotificationType.Native),
|
|
10
|
+
message: string(),
|
|
11
|
+
});
|
|
12
|
+
const InAppNotificationStruct = object({
|
|
13
|
+
type: enumValue(NotificationType.InApp),
|
|
14
|
+
message: string(),
|
|
15
|
+
});
|
|
16
|
+
const InAppNotificationWithDetailsStruct = object({
|
|
17
|
+
type: enumValue(NotificationType.InApp),
|
|
18
|
+
message: string(),
|
|
19
|
+
content: ComponentOrElementStruct,
|
|
20
|
+
title: string(),
|
|
21
|
+
footerLink: optional(object({
|
|
22
|
+
href: string(),
|
|
23
|
+
text: string(),
|
|
24
|
+
})),
|
|
25
|
+
});
|
|
26
|
+
const NotificationParametersStruct = union([
|
|
27
|
+
InAppNotificationStruct,
|
|
28
|
+
InAppNotificationWithDetailsStruct,
|
|
29
|
+
NativeNotificationStruct,
|
|
30
|
+
]);
|
|
7
31
|
/**
|
|
8
32
|
* The specification builder for the `snap_notify` permission.
|
|
9
33
|
* `snap_notify` allows snaps to send multiple types of notifications to its users.
|
|
@@ -27,6 +51,7 @@ const methodHooks = {
|
|
|
27
51
|
showInAppNotification: true,
|
|
28
52
|
isOnPhishingList: true,
|
|
29
53
|
maybeUpdatePhishingList: true,
|
|
54
|
+
createInterface: true,
|
|
30
55
|
getSnap: true,
|
|
31
56
|
};
|
|
32
57
|
export const notifyBuilder = Object.freeze({
|
|
@@ -42,16 +67,20 @@ export const notifyBuilder = Object.freeze({
|
|
|
42
67
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
43
68
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
44
69
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
70
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
45
71
|
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
46
72
|
* @returns The method implementation which returns `null` on success.
|
|
47
73
|
* @throws If the params are invalid.
|
|
48
74
|
*/
|
|
49
|
-
export function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, getSnap, }) {
|
|
75
|
+
export function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }) {
|
|
50
76
|
return async function implementation(args) {
|
|
51
77
|
const { params, context: { origin }, } = args;
|
|
52
|
-
const validatedParams = getValidatedParams(params);
|
|
53
78
|
await maybeUpdatePhishingList();
|
|
54
|
-
|
|
79
|
+
const validatedParams = getValidatedParams(params, isOnPhishingList, getSnap);
|
|
80
|
+
if (hasProperty(validatedParams, 'content')) {
|
|
81
|
+
const id = await createInterface(origin, validatedParams.content, undefined, ContentType.Notification);
|
|
82
|
+
validatedParams.content = id;
|
|
83
|
+
}
|
|
55
84
|
switch (validatedParams.type) {
|
|
56
85
|
case NotificationType.Native:
|
|
57
86
|
return await showNativeNotification(origin, validatedParams);
|
|
@@ -69,9 +98,12 @@ export function getImplementation({ showNativeNotification, showInAppNotificatio
|
|
|
69
98
|
* type. Throws if validation fails.
|
|
70
99
|
*
|
|
71
100
|
* @param params - The unvalidated params object from the method request.
|
|
101
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
102
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
72
103
|
* @returns The validated method parameter object.
|
|
104
|
+
* @throws If the params are invalid.
|
|
73
105
|
*/
|
|
74
|
-
export function getValidatedParams(params) {
|
|
106
|
+
export function getValidatedParams(params, isOnPhishingList, getSnap) {
|
|
75
107
|
if (!isObject(params)) {
|
|
76
108
|
throw rpcErrors.invalidParams({
|
|
77
109
|
message: 'Expected params to be a single object.',
|
|
@@ -99,6 +131,18 @@ export function getValidatedParams(params) {
|
|
|
99
131
|
message: 'Must specify a non-empty string "message" less than 500 characters long.',
|
|
100
132
|
});
|
|
101
133
|
}
|
|
102
|
-
|
|
134
|
+
try {
|
|
135
|
+
const validatedParams = createUnion(params, NotificationParametersStruct, 'type');
|
|
136
|
+
validateTextLinks(validatedParams.message, isOnPhishingList, getSnap);
|
|
137
|
+
if (hasProperty(validatedParams, 'footerLink')) {
|
|
138
|
+
validateLink(validatedParams.footerLink.href, isOnPhishingList, getSnap);
|
|
139
|
+
}
|
|
140
|
+
return validatedParams;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
throw rpcErrors.invalidParams({
|
|
144
|
+
message: `Invalid params: ${getErrorMessage(error)}`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
103
147
|
}
|
|
104
148
|
//# sourceMappingURL=notify.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.mjs","sourceRoot":"","sources":["../../src/restricted/notify.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PermissionSpecificationBuilder,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { NotificationType } from '@metamask/snaps-sdk';\nimport type {\n NotifyParams,\n NotifyResult,\n EnumToUnion,\n} from '@metamask/snaps-sdk';\nimport { type Snap, validateTextLinks } from '@metamask/snaps-utils';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { isObject } from '@metamask/utils';\n\nimport { type MethodHooksObject } from '../utils';\n\nconst methodName = 'snap_notify';\n\nexport type NotificationArgs = {\n /**\n * Enum type to determine notification type.\n */\n type: EnumToUnion<NotificationType>;\n\n /**\n * A message to show on the notification.\n */\n message: string;\n};\n\nexport type NotifyMethodHooks = {\n /**\n * @param snapId - The ID of the Snap that created the notification.\n * @param args - The notification arguments.\n */\n showNativeNotification: (\n snapId: string,\n args: NotificationArgs,\n ) => Promise<null>;\n\n /**\n * @param snapId - The ID of the Snap that created the notification.\n * @param args - The notification arguments.\n */\n showInAppNotification: (\n snapId: string,\n args: NotificationArgs,\n ) => Promise<null>;\n\n isOnPhishingList: (url: string) => boolean;\n\n maybeUpdatePhishingList: () => Promise<void>;\n\n getSnap: (snapId: string) => Snap | undefined;\n};\n\ntype SpecificationBuilderOptions = {\n allowedCaveats?: Readonly<NonEmptyArray<string>> | null;\n methodHooks: NotifyMethodHooks;\n};\n\ntype Specification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof methodName;\n methodImplementation: ReturnType<typeof getImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * The specification builder for the `snap_notify` permission.\n * `snap_notify` allows snaps to send multiple types of notifications to its users.\n *\n * @param options - The specification builder options.\n * @param options.allowedCaveats - The optional allowed caveats for the permission.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_notify` permission.\n */\nexport const specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n SpecificationBuilderOptions,\n Specification\n> = ({ allowedCaveats = null, methodHooks }: SpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName: methodName,\n allowedCaveats,\n methodImplementation: getImplementation(methodHooks),\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<NotifyMethodHooks> = {\n showNativeNotification: true,\n showInAppNotification: true,\n isOnPhishingList: true,\n maybeUpdatePhishingList: true,\n getSnap: true,\n};\n\nexport const notifyBuilder = Object.freeze({\n targetName: methodName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_notify`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.showNativeNotification - A function that shows a native browser notification.\n * @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.\n * @param hooks.isOnPhishingList - A function that checks for links against the phishing list.\n * @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.\n * @param hooks.getSnap - A function that checks if a snap is installed.\n * @returns The method implementation which returns `null` on success.\n * @throws If the params are invalid.\n */\nexport function getImplementation({\n showNativeNotification,\n showInAppNotification,\n isOnPhishingList,\n maybeUpdatePhishingList,\n getSnap,\n}: NotifyMethodHooks) {\n return async function implementation(\n args: RestrictedMethodOptions<NotifyParams>,\n ): Promise<NotifyResult> {\n const {\n params,\n context: { origin },\n } = args;\n\n const validatedParams = getValidatedParams(params);\n\n await maybeUpdatePhishingList();\n\n validateTextLinks(validatedParams.message, isOnPhishingList, getSnap);\n\n switch (validatedParams.type) {\n case NotificationType.Native:\n return await showNativeNotification(origin, validatedParams);\n case NotificationType.InApp:\n return await showInAppNotification(origin, validatedParams);\n default:\n throw rpcErrors.invalidParams({\n message: 'Must specify a valid notification \"type\".',\n });\n }\n };\n}\n\n/**\n * Validates the notify method `params` and returns them cast to the correct\n * type. Throws if validation fails.\n *\n * @param params - The unvalidated params object from the method request.\n * @returns The validated method parameter object.\n */\nexport function getValidatedParams(params: unknown): NotifyParams {\n if (!isObject(params)) {\n throw rpcErrors.invalidParams({\n message: 'Expected params to be a single object.',\n });\n }\n\n const { type, message } = params;\n\n if (\n !type ||\n typeof type !== 'string' ||\n !Object.values(NotificationType).includes(type as NotificationType)\n ) {\n throw rpcErrors.invalidParams({\n message: 'Must specify a valid notification \"type\".',\n });\n }\n\n const isNotString = !message || typeof message !== 'string';\n // Set to the max message length on a Mac notification for now.\n if (\n type === NotificationType.Native &&\n (isNotString || message.length >= 50)\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Must specify a non-empty string \"message\" less than 50 characters long.',\n });\n }\n\n if (\n type === NotificationType.InApp &&\n (isNotString || message.length >= 500)\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Must specify a non-empty string \"message\" less than 500 characters long.',\n });\n }\n\n return params as NotificationArgs;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"notify.mjs","sourceRoot":"","sources":["../../src/restricted/notify.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n PermissionSpecificationBuilder,\n RestrictedMethodOptions,\n ValidPermissionSpecification,\n} from '@metamask/permission-controller';\nimport { PermissionType, SubjectType } from '@metamask/permission-controller';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport type {\n NotifyParams,\n NotifyResult,\n InterfaceContext,\n ComponentOrElement,\n} from '@metamask/snaps-sdk';\nimport {\n enumValue,\n NotificationType,\n union,\n ContentType,\n getErrorMessage,\n ComponentOrElementStruct,\n} from '@metamask/snaps-sdk';\nimport {\n createUnion,\n validateLink,\n validateTextLinks,\n type Snap,\n} from '@metamask/snaps-utils';\nimport type { InferMatching } from '@metamask/snaps-utils';\nimport { object, string, optional } from '@metamask/superstruct';\nimport type { NonEmptyArray } from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport { type MethodHooksObject } from '../utils';\n\nconst methodName = 'snap_notify';\n\nconst NativeNotificationStruct = object({\n type: enumValue(NotificationType.Native),\n message: string(),\n});\n\nconst InAppNotificationStruct = object({\n type: enumValue(NotificationType.InApp),\n message: string(),\n});\n\nconst InAppNotificationWithDetailsStruct = object({\n type: enumValue(NotificationType.InApp),\n message: string(),\n content: ComponentOrElementStruct,\n title: string(),\n footerLink: optional(\n object({\n href: string(),\n text: string(),\n }),\n ),\n});\n\nconst NotificationParametersStruct = union([\n InAppNotificationStruct,\n InAppNotificationWithDetailsStruct,\n NativeNotificationStruct,\n]);\n\nexport type NotificationArgs = InferMatching<\n typeof NotificationParametersStruct,\n NotifyParams\n>;\n\nexport type NotifyMethodHooks = {\n /**\n * @param snapId - The ID of the Snap that created the notification.\n * @param args - The notification arguments.\n */\n showNativeNotification: (\n snapId: string,\n args: NotificationArgs,\n ) => Promise<null>;\n\n /**\n * @param snapId - The ID of the Snap that created the notification.\n * @param args - The notification arguments.\n */\n showInAppNotification: (\n snapId: string,\n args: NotificationArgs,\n ) => Promise<null>;\n\n isOnPhishingList: (url: string) => boolean;\n\n maybeUpdatePhishingList: () => Promise<void>;\n\n createInterface: (\n origin: string,\n content: ComponentOrElement,\n context?: InterfaceContext,\n contentType?: ContentType,\n ) => Promise<string>;\n getSnap: (snapId: string) => Snap | undefined;\n};\n\ntype SpecificationBuilderOptions = {\n allowedCaveats?: Readonly<NonEmptyArray<string>> | null;\n methodHooks: NotifyMethodHooks;\n};\n\ntype Specification = ValidPermissionSpecification<{\n permissionType: PermissionType.RestrictedMethod;\n targetName: typeof methodName;\n methodImplementation: ReturnType<typeof getImplementation>;\n allowedCaveats: Readonly<NonEmptyArray<string>> | null;\n}>;\n\n/**\n * The specification builder for the `snap_notify` permission.\n * `snap_notify` allows snaps to send multiple types of notifications to its users.\n *\n * @param options - The specification builder options.\n * @param options.allowedCaveats - The optional allowed caveats for the permission.\n * @param options.methodHooks - The RPC method hooks needed by the method implementation.\n * @returns The specification for the `snap_notify` permission.\n */\nexport const specificationBuilder: PermissionSpecificationBuilder<\n PermissionType.RestrictedMethod,\n SpecificationBuilderOptions,\n Specification\n> = ({ allowedCaveats = null, methodHooks }: SpecificationBuilderOptions) => {\n return {\n permissionType: PermissionType.RestrictedMethod,\n targetName: methodName,\n allowedCaveats,\n methodImplementation: getImplementation(methodHooks),\n subjectTypes: [SubjectType.Snap],\n };\n};\n\nconst methodHooks: MethodHooksObject<NotifyMethodHooks> = {\n showNativeNotification: true,\n showInAppNotification: true,\n isOnPhishingList: true,\n maybeUpdatePhishingList: true,\n createInterface: true,\n getSnap: true,\n};\n\nexport const notifyBuilder = Object.freeze({\n targetName: methodName,\n specificationBuilder,\n methodHooks,\n} as const);\n\n/**\n * Builds the method implementation for `snap_notify`.\n *\n * @param hooks - The RPC method hooks.\n * @param hooks.showNativeNotification - A function that shows a native browser notification.\n * @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.\n * @param hooks.isOnPhishingList - A function that checks for links against the phishing list.\n * @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.\n * @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.\n * @param hooks.getSnap - A function that checks if a snap is installed.\n * @returns The method implementation which returns `null` on success.\n * @throws If the params are invalid.\n */\nexport function getImplementation({\n showNativeNotification,\n showInAppNotification,\n isOnPhishingList,\n maybeUpdatePhishingList,\n createInterface,\n getSnap,\n}: NotifyMethodHooks) {\n return async function implementation(\n args: RestrictedMethodOptions<NotifyParams>,\n ): Promise<NotifyResult> {\n const {\n params,\n context: { origin },\n } = args;\n\n await maybeUpdatePhishingList();\n\n const validatedParams = getValidatedParams(\n params,\n isOnPhishingList,\n getSnap,\n );\n\n if (hasProperty(validatedParams, 'content')) {\n const id = await createInterface(\n origin,\n validatedParams.content as ComponentOrElement,\n undefined,\n ContentType.Notification,\n );\n validatedParams.content = id;\n }\n\n switch (validatedParams.type) {\n case NotificationType.Native:\n return await showNativeNotification(origin, validatedParams);\n case NotificationType.InApp:\n return await showInAppNotification(origin, validatedParams);\n default:\n throw rpcErrors.invalidParams({\n message: 'Must specify a valid notification \"type\".',\n });\n }\n };\n}\n\n/**\n * Validates the notify method `params` and returns them cast to the correct\n * type. Throws if validation fails.\n *\n * @param params - The unvalidated params object from the method request.\n * @param isOnPhishingList - The function that checks for links against the phishing list.\n * @param getSnap - A function that checks if a snap is installed.\n * @returns The validated method parameter object.\n * @throws If the params are invalid.\n */\nexport function getValidatedParams(\n params: unknown,\n isOnPhishingList: NotifyMethodHooks['isOnPhishingList'],\n getSnap: NotifyMethodHooks['getSnap'],\n): NotifyParams {\n if (!isObject(params)) {\n throw rpcErrors.invalidParams({\n message: 'Expected params to be a single object.',\n });\n }\n\n const { type, message } = params;\n\n if (\n !type ||\n typeof type !== 'string' ||\n !Object.values(NotificationType).includes(type as NotificationType)\n ) {\n throw rpcErrors.invalidParams({\n message: 'Must specify a valid notification \"type\".',\n });\n }\n\n const isNotString = !message || typeof message !== 'string';\n // Set to the max message length on a Mac notification for now.\n if (\n type === NotificationType.Native &&\n (isNotString || message.length >= 50)\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Must specify a non-empty string \"message\" less than 50 characters long.',\n });\n }\n\n if (\n type === NotificationType.InApp &&\n (isNotString || message.length >= 500)\n ) {\n throw rpcErrors.invalidParams({\n message:\n 'Must specify a non-empty string \"message\" less than 500 characters long.',\n });\n }\n\n try {\n const validatedParams = createUnion(\n params,\n NotificationParametersStruct,\n 'type',\n );\n\n validateTextLinks(validatedParams.message, isOnPhishingList, getSnap);\n\n if (hasProperty(validatedParams, 'footerLink')) {\n validateLink(validatedParams.footerLink.href, isOnPhishingList, getSnap);\n }\n\n return validatedParams;\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${getErrorMessage(error)}`,\n });\n }\n}\n"]}
|
package/dist/utils.cjs
CHANGED
|
@@ -62,9 +62,11 @@ function getDerivationPathArray(hash) {
|
|
|
62
62
|
* derivation.
|
|
63
63
|
* @param options.magic - A hardened BIP-32 index, which is used to derive the
|
|
64
64
|
* root key from the mnemonic phrase.
|
|
65
|
+
* @param options.cryptographicFunctions - The cryptographic functions to use
|
|
66
|
+
* for the derivation.
|
|
65
67
|
* @returns The derived entropy.
|
|
66
68
|
*/
|
|
67
|
-
async function deriveEntropy({ input, salt = '', mnemonicPhrase, magic, }) {
|
|
69
|
+
async function deriveEntropy({ input, salt = '', mnemonicPhrase, magic, cryptographicFunctions, }) {
|
|
68
70
|
const inputBytes = (0, utils_1.stringToBytes)(input);
|
|
69
71
|
const saltBytes = (0, utils_1.stringToBytes)(salt);
|
|
70
72
|
// Get the derivation path from the snap ID.
|
|
@@ -78,7 +80,7 @@ async function deriveEntropy({ input, salt = '', mnemonicPhrase, magic, }) {
|
|
|
78
80
|
...computedDerivationPath,
|
|
79
81
|
],
|
|
80
82
|
curve: 'secp256k1',
|
|
81
|
-
});
|
|
83
|
+
}, cryptographicFunctions);
|
|
82
84
|
// This should never happen, but this keeps TypeScript happy.
|
|
83
85
|
(0, utils_1.assert)(privateKey, 'Failed to derive the entropy.');
|
|
84
86
|
return (0, utils_1.add0x)(privateKey);
|
|
@@ -124,9 +126,11 @@ exports.getPathPrefix = getPathPrefix;
|
|
|
124
126
|
* derivation.
|
|
125
127
|
* @param options.path - The derivation path to use as array, starting with an
|
|
126
128
|
* "m" as the first item.
|
|
129
|
+
* @param options.cryptographicFunctions - The cryptographic functions to use
|
|
130
|
+
* for the node.
|
|
127
131
|
* @returns The `key-tree` SLIP-10 node.
|
|
128
132
|
*/
|
|
129
|
-
async function getNode({ curve, secretRecoveryPhrase, path, }) {
|
|
133
|
+
async function getNode({ curve, secretRecoveryPhrase, path, cryptographicFunctions, }) {
|
|
130
134
|
const prefix = getPathPrefix(curve);
|
|
131
135
|
return await key_tree_1.SLIP10Node.fromDerivationPath({
|
|
132
136
|
curve,
|
|
@@ -134,7 +138,7 @@ async function getNode({ curve, secretRecoveryPhrase, path, }) {
|
|
|
134
138
|
secretRecoveryPhrase,
|
|
135
139
|
...path.slice(1).map((index) => `${prefix}:${index}`),
|
|
136
140
|
],
|
|
137
|
-
});
|
|
141
|
+
}, cryptographicFunctions);
|
|
138
142
|
}
|
|
139
143
|
exports.getNode = getNode;
|
|
140
144
|
//# sourceMappingURL=utils.cjs.map
|
package/dist/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AAOA,iDAAgD;AAGhD,2CAOyB;AACzB,6CAA6D;AAE7D,MAAM,cAAc,GAAG,UAAU,CAAC;AAWlC;;;;;;;;;;;GAWG;AACH,SAAgB,WAAW,CAIzB,KAAY,EACZ,SAAqC;IAErC,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAClC,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE;YACxB,MAAM,QAAQ,GAAG,SAAqB,CAAC;YACvC,UAAU,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;YACvC,OAAO,UAAU,CAAC;QACpB,CAAC,EACD,EAAE,CACsB,CAAC;IAC7B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAlBD,kCAkBC;AAED;;;;;;GAMG;AACH,SAAS,sBAAsB,CAAC,IAAgB;IAC9C,MAAM,KAAK,GAAwB,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,IAAA,sBAAc,EAAC,IAAI,CAAC,CAAC;IAElC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAEzC,2EAA2E;QAC3E,0EAA0E;QAC1E,mCAAmC;QACnC,sCAAsC;QACtC,MAAM,SAAS,GAAG,CAAC,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAClD,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,cAAc,GAAY,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AA8BD;;;;;;;;;;;;;;;;GAgBG;AACI,KAAK,UAAU,aAAa,CAAC,EAClC,KAAK,EACL,IAAI,GAAG,EAAE,EACT,cAAc,EACd,KAAK,EACL,sBAAsB,GACD;IACrB,MAAM,UAAU,GAAG,IAAA,qBAAa,EAAC,KAAK,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAA,qBAAa,EAAC,IAAI,CAAC,CAAC;IAEtC,4CAA4C;IAC5C,MAAM,IAAI,GAAG,IAAA,iBAAS,EAAC,IAAA,mBAAW,EAAC,CAAC,UAAU,EAAE,IAAA,iBAAS,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,sBAAsB,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE5D,uCAAuC;IACvC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,qBAAU,CAAC,kBAAkB,CACxD;QACE,cAAc,EAAE;YACd,cAAc;YACd,SAAS,KAAK,EAAE;YAChB,GAAG,sBAAsB;SAC1B;QACD,KAAK,EAAE,WAAW;KACnB,EACD,sBAAsB,CACvB,CAAC;IAEF,6DAA6D;IAC7D,IAAA,cAAM,EAAC,UAAU,EAAE,+BAA+B,CAAC,CAAC;IAEpD,OAAO,IAAA,aAAK,EAAC,UAAU,CAAC,CAAC;AAC3B,CAAC;AA/BD,sCA+BC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAgB,aAAa,CAC3B,KAAqB;IAErB,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,WAAW;YACd,OAAO,OAAO,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,QAAQ,CAAC;QAClB,KAAK,cAAc;YACjB,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,IAAA,wBAAgB,EAAC,KAAK,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAbD,sCAaC;AASD;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,OAAO,CAAC,EAC5B,KAAK,EACL,oBAAoB,EACpB,IAAI,EACJ,sBAAsB,GACV;IACZ,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAEpC,OAAO,MAAM,qBAAU,CAAC,kBAAkB,CACxC;QACE,KAAK;QACL,cAAc,EAAE;YACd,oBAAoB;YACpB,GAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,CAEhC;SACtB;KACF,EACD,sBAAsB,CACvB,CAAC;AACJ,CAAC;AApBD,0BAoBC","sourcesContent":["import type {\n HardenedBIP32Node,\n BIP32Node,\n SLIP10PathNode,\n SupportedCurve,\n CryptographicFunctions,\n} from '@metamask/key-tree';\nimport { SLIP10Node } from '@metamask/key-tree';\nimport type { MagicValue } from '@metamask/snaps-utils';\nimport type { Hex } from '@metamask/utils';\nimport {\n assertExhaustive,\n add0x,\n assert,\n concatBytes,\n createDataView,\n stringToBytes,\n} from '@metamask/utils';\nimport { keccak_256 as keccak256 } from '@noble/hashes/sha3';\n\nconst HARDENED_VALUE = 0x80000000;\n\n/**\n * Maps an interface with method hooks to an object, using the keys of the\n * interface, and `true` as value. This ensures that the `methodHooks` object\n * has the same values as the interface.\n */\nexport type MethodHooksObject<HooksType extends Record<string, unknown>> = {\n [Key in keyof HooksType]: true;\n};\n\n/**\n * Returns the subset of the specified `hooks` that are included in the\n * `hookNames` object. This is a Principle of Least Authority (POLA) measure\n * to ensure that each RPC method implementation only has access to the\n * API \"hooks\" it needs to do its job.\n *\n * @param hooks - The hooks to select from.\n * @param hookNames - The names of the hooks to select.\n * @returns The selected hooks.\n * @template Hooks - The hooks to select from.\n * @template HookName - The names of the hooks to select.\n */\nexport function selectHooks<\n Hooks extends Record<string, unknown>,\n HookName extends keyof Hooks,\n>(\n hooks: Hooks,\n hookNames?: Record<HookName, boolean>,\n): Pick<Hooks, HookName> | undefined {\n if (hookNames) {\n return Object.keys(hookNames).reduce<Partial<Pick<Hooks, HookName>>>(\n (hookSubset, _hookName) => {\n const hookName = _hookName as HookName;\n hookSubset[hookName] = hooks[hookName];\n return hookSubset;\n },\n {},\n ) as Pick<Hooks, HookName>;\n }\n return undefined;\n}\n\n/**\n * Get a BIP-32 derivation path array from a hash, which is compatible with\n * `@metamask/key-tree`. The hash is assumed to be 32 bytes long.\n *\n * @param hash - The hash to derive indices from.\n * @returns The derived indices as a {@link HardenedBIP32Node} array.\n */\nfunction getDerivationPathArray(hash: Uint8Array): HardenedBIP32Node[] {\n const array: HardenedBIP32Node[] = [];\n const view = createDataView(hash);\n\n for (let index = 0; index < 8; index++) {\n const uint32 = view.getUint32(index * 4);\n\n // This is essentially `index | 0x80000000`. Because JavaScript numbers are\n // signed, we use the bitwise unsigned right shift operator to ensure that\n // the result is a positive number.\n // eslint-disable-next-line no-bitwise\n const pathIndex = (uint32 | HARDENED_VALUE) >>> 0;\n array.push(`bip32:${pathIndex - HARDENED_VALUE}'` as const);\n }\n\n return array;\n}\n\ntype DeriveEntropyOptions = {\n /**\n * The input value to derive entropy from.\n */\n input: string;\n\n /**\n * An optional salt to use when deriving entropy.\n */\n salt?: string;\n\n /**\n * The mnemonic phrase to use for entropy derivation.\n */\n mnemonicPhrase: Uint8Array;\n\n /**\n * A hardened BIP-32 index, which is used to derive the root key from the\n * mnemonic phrase.\n */\n magic: MagicValue;\n\n /**\n * The cryptographic functions to use for the derivation.\n */\n cryptographicFunctions: CryptographicFunctions | undefined;\n};\n\n/**\n * Derive entropy from the given mnemonic phrase and salt.\n *\n * This is based on the reference implementation of\n * [SIP-6](https://metamask.github.io/SIPs/SIPS/sip-6).\n *\n * @param options - The options for entropy derivation.\n * @param options.input - The input value to derive entropy from.\n * @param options.salt - An optional salt to use when deriving entropy.\n * @param options.mnemonicPhrase - The mnemonic phrase to use for entropy\n * derivation.\n * @param options.magic - A hardened BIP-32 index, which is used to derive the\n * root key from the mnemonic phrase.\n * @param options.cryptographicFunctions - The cryptographic functions to use\n * for the derivation.\n * @returns The derived entropy.\n */\nexport async function deriveEntropy({\n input,\n salt = '',\n mnemonicPhrase,\n magic,\n cryptographicFunctions,\n}: DeriveEntropyOptions): Promise<Hex> {\n const inputBytes = stringToBytes(input);\n const saltBytes = stringToBytes(salt);\n\n // Get the derivation path from the snap ID.\n const hash = keccak256(concatBytes([inputBytes, keccak256(saltBytes)]));\n const computedDerivationPath = getDerivationPathArray(hash);\n\n // Derive the private key using BIP-32.\n const { privateKey } = await SLIP10Node.fromDerivationPath(\n {\n derivationPath: [\n mnemonicPhrase,\n `bip32:${magic}`,\n ...computedDerivationPath,\n ],\n curve: 'secp256k1',\n },\n cryptographicFunctions,\n );\n\n // This should never happen, but this keeps TypeScript happy.\n assert(privateKey, 'Failed to derive the entropy.');\n\n return add0x(privateKey);\n}\n\n/**\n * Get the path prefix to use for key derivation in `key-tree`. This assumes the\n * following:\n *\n * - The Secp256k1 curve always uses the BIP-32 specification.\n * - The Ed25519 curve always uses the SLIP-10 specification.\n * - The BIP-32-Ed25519 curve always uses the CIP-3 specification.\n *\n * While this does not matter in most situations (no known case at the time of\n * writing), `key-tree` requires a specific specification to be used.\n *\n * @param curve - The curve to get the path prefix for. The curve is NOT\n * validated by this function.\n * @returns The path prefix, i.e., `bip32` or `slip10`.\n */\nexport function getPathPrefix(\n curve: SupportedCurve,\n): 'bip32' | 'slip10' | 'cip3' {\n switch (curve) {\n case 'secp256k1':\n return 'bip32';\n case 'ed25519':\n return 'slip10';\n case 'ed25519Bip32':\n return 'cip3';\n default:\n return assertExhaustive(curve);\n }\n}\n\ntype GetNodeArgs = {\n curve: SupportedCurve;\n secretRecoveryPhrase: Uint8Array;\n path: string[];\n cryptographicFunctions: CryptographicFunctions | undefined;\n};\n\n/**\n * Get a `key-tree`-compatible node.\n *\n * Note: This function assumes that all the parameters have been validated\n * beforehand.\n *\n * @param options - The derivation options.\n * @param options.curve - The curve to use for derivation.\n * @param options.secretRecoveryPhrase - The secret recovery phrase to use for\n * derivation.\n * @param options.path - The derivation path to use as array, starting with an\n * \"m\" as the first item.\n * @param options.cryptographicFunctions - The cryptographic functions to use\n * for the node.\n * @returns The `key-tree` SLIP-10 node.\n */\nexport async function getNode({\n curve,\n secretRecoveryPhrase,\n path,\n cryptographicFunctions,\n}: GetNodeArgs) {\n const prefix = getPathPrefix(curve);\n\n return await SLIP10Node.fromDerivationPath(\n {\n curve,\n derivationPath: [\n secretRecoveryPhrase,\n ...(path.slice(1).map((index) => `${prefix}:${index}`) as\n | BIP32Node[]\n | SLIP10PathNode[]),\n ],\n },\n cryptographicFunctions,\n );\n}\n"]}
|