@metamask/snaps-rpc-methods 11.1.1 → 11.2.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 +88 -1
- package/dist/restricted/notify.cjs +61 -5
- package/dist/restricted/notify.cjs.map +1 -1
- package/dist/restricted/notify.d.cts +96 -15
- package/dist/restricted/notify.d.cts.map +1 -1
- package/dist/restricted/notify.d.mts +96 -15
- package/dist/restricted/notify.d.mts.map +1 -1
- package/dist/restricted/notify.mjs +64 -8
- package/dist/restricted/notify.mjs.map +1 -1
- package/package.json +30 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# Changelog
|
|
2
|
+
|
|
2
3
|
All notable changes to this project will be documented in this file.
|
|
3
4
|
|
|
4
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
@@ -6,16 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
7
|
|
|
7
8
|
## [Unreleased]
|
|
8
9
|
|
|
10
|
+
## [11.2.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add support for `metamask:` schemed URLs ([#2719](https://github.com/MetaMask/snaps/pull/2719))
|
|
15
|
+
- Add support for JSX in `snap_notify` notifications ([#2706](https://github.com/MetaMask/snaps/pull/2706))
|
|
16
|
+
|
|
9
17
|
## [11.1.1]
|
|
18
|
+
|
|
10
19
|
### Fixed
|
|
20
|
+
|
|
11
21
|
- Fix invalid types in type declaration in some cases ([#2714](https://github.com/MetaMask/snaps/pull/2714))
|
|
12
22
|
|
|
13
23
|
## [11.1.0]
|
|
24
|
+
|
|
14
25
|
### Changed
|
|
26
|
+
|
|
15
27
|
- Improve error messaging ([#2696](https://github.com/MetaMask/snaps/pull/2696))
|
|
16
28
|
- Increase character limit for in-app notification messages ([#2684](https://github.com/MetaMask/snaps/pull/2684))
|
|
17
29
|
|
|
18
30
|
### Fixed
|
|
31
|
+
|
|
19
32
|
- Fix ESM version of the package ([#2682](https://github.com/MetaMask/snaps/pull/2682))
|
|
20
33
|
- This fixes the ESM version of the package to be fully compliant with the ESM
|
|
21
34
|
standard.
|
|
@@ -23,85 +36,118 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
23
36
|
- Bump other MetaMask dependencies ([#2703](https://github.com/MetaMask/snaps/pull/2703))
|
|
24
37
|
|
|
25
38
|
## [11.0.0]
|
|
39
|
+
|
|
26
40
|
### Added
|
|
41
|
+
|
|
27
42
|
- **BREAKING:** Add `snap_getPreferences` ([#2607](https://github.com/MetaMask/snaps/pull/2607))
|
|
28
43
|
- This is breaking because a `getPreferences` method hook is now required.
|
|
29
44
|
|
|
30
45
|
## [10.0.1]
|
|
46
|
+
|
|
31
47
|
### Changed
|
|
48
|
+
|
|
32
49
|
- Bump `@metamask/json-rpc-engine` from `^9.0.0` to `^9.0.2` ([#2593](https://github.com/metamask/snaps/pull/2593))
|
|
33
50
|
- Bump `@metamask/permission-controller` from `^10.0.1` to `^11.0.0` ([#2593](https://github.com/metamask/snaps/pull/2593))
|
|
34
51
|
- Bump `@metamask/snaps-utils` from `^7.8.0` to `^7.8.1` ([#2595](https://github.com/MetaMask/snaps/pull/2595))
|
|
35
52
|
|
|
36
53
|
## [10.0.0]
|
|
54
|
+
|
|
37
55
|
### Added
|
|
56
|
+
|
|
38
57
|
- **BREAKING:** `snap_dialog` now takes the `requestUserApproval` hook ([#2509](https://github.com/metamask/snaps/pull/2509))
|
|
39
58
|
- It should bind to the `addAndShowRequest` method of the `ApprovalController`.
|
|
40
59
|
- Add type `DialogApprovalTypes` and object `DIALOG_APPROVAL_TYPES`.
|
|
41
60
|
|
|
42
61
|
### Changed
|
|
62
|
+
|
|
43
63
|
- Bump `@metamask/key-tree` from `^9.1.1` to `^9.1.2` ([#2445](https://github.com/MetaMask/snaps/pull/2445))
|
|
44
64
|
- Bump `@metamask/permission-controller` from `^10.0.0` to `^10.0.1` ([#2445](https://github.com/MetaMask/snaps/pull/2445))
|
|
45
65
|
- Bump `@metamask/rpc-errors` from `^6.2.1` to `^6.3.1` ([#2445](https://github.com/MetaMask/snaps/pull/2445))
|
|
46
66
|
- Bump `@metamask/utils` from `^8.3.0` to `^9.1.0` ([#2445](https://github.com/MetaMask/snaps/pull/2445))
|
|
47
67
|
|
|
48
68
|
### Fixed
|
|
69
|
+
|
|
49
70
|
- Replace `superstruct` with ESM-compatible `@metamask/superstruct` `^3.1.0` ([#2445](https://github.com/MetaMask/snaps/pull/2445))
|
|
50
71
|
- This fixes the issue of this package being unusable by any TypeScript project that uses `Node16` or `NodeNext` as its `moduleResolution` option.
|
|
51
72
|
|
|
52
73
|
## [9.1.4]
|
|
74
|
+
|
|
53
75
|
### Changed
|
|
76
|
+
|
|
54
77
|
- Bump MetaMask dependencies ([#2516](https://github.com/MetaMask/snaps/pull/2516))
|
|
55
78
|
|
|
56
79
|
## [9.1.3]
|
|
80
|
+
|
|
57
81
|
### Changed
|
|
82
|
+
|
|
58
83
|
- Bump MetaMask dependencies ([#2460](https://github.com/MetaMask/snaps/pull/2460))
|
|
59
84
|
|
|
60
85
|
## [9.1.2]
|
|
86
|
+
|
|
61
87
|
### Fixed
|
|
88
|
+
|
|
62
89
|
- Fix invalid `@metamask/snaps-sdk` imports ([#2452](https://github.com/MetaMask/snaps/pull/2452))
|
|
63
90
|
|
|
64
91
|
## [9.1.1]
|
|
92
|
+
|
|
65
93
|
### Changed
|
|
94
|
+
|
|
66
95
|
- Bump `@metamask/key-tree` from `9.1.0` to `9.1.1` ([#2431](https://github.com/MetaMask/snaps/pull/2431))
|
|
67
96
|
|
|
68
97
|
## [9.1.0]
|
|
98
|
+
|
|
69
99
|
### Added
|
|
100
|
+
|
|
70
101
|
- Add `context` field to `snap_createInterface` ([#2413](https://github.com/MetaMask/snaps/pull/2413))
|
|
71
102
|
|
|
72
103
|
## [9.0.0]
|
|
104
|
+
|
|
73
105
|
### Added
|
|
106
|
+
|
|
74
107
|
- Add support for BIP-32-Ed25519 / CIP-3 key derivation ([#2408](https://github.com/MetaMask/snaps/pull/2408))
|
|
75
108
|
- The `ed25519Bip32` curve is now supported for `snap_getBip32Entropy` and `snap_getBip32PublicKey`
|
|
76
109
|
|
|
77
110
|
### Changed
|
|
111
|
+
|
|
78
112
|
- **BREAKING:** Use hooks in `wallet_invokeSnap` instead of remapping the request to `wallet_snap` ([#2406](https://github.com/MetaMask/snaps/pull/2406))
|
|
79
113
|
|
|
80
114
|
## [8.1.0]
|
|
115
|
+
|
|
81
116
|
### Added
|
|
117
|
+
|
|
82
118
|
- Add JSX support for custom UI ([#2258](https://github.com/MetaMask/snaps/pull/2258))
|
|
83
119
|
|
|
84
120
|
## [8.0.0]
|
|
121
|
+
|
|
85
122
|
### Changed
|
|
123
|
+
|
|
86
124
|
- **BREAKING:** Refactor to support changes to encryption ([#2316](https://github.com/MetaMask/snaps/pull/2316))
|
|
87
125
|
- No longer expects `encrypt` or `decrypt`, instead expects `updateSnapState` and `getSnapState` to be asynchronous
|
|
88
126
|
|
|
89
127
|
## [7.0.2]
|
|
128
|
+
|
|
90
129
|
### Changed
|
|
130
|
+
|
|
91
131
|
- Bump MetaMask dependencies ([#2270](https://github.com/MetaMask/snaps/pull/2270))
|
|
92
132
|
- Bump @metamask/json-rpc-engine from 7.3.2 to 7.3.3 ([#2247](https://github.com/MetaMask/snaps/pull/2247))
|
|
93
133
|
|
|
94
134
|
## [7.0.1]
|
|
135
|
+
|
|
95
136
|
### Fixed
|
|
137
|
+
|
|
96
138
|
- Fix minor build configuration problems ([#2220](https://github.com/MetaMask/snaps/pull/2220))
|
|
97
139
|
|
|
98
140
|
## [7.0.0]
|
|
141
|
+
|
|
99
142
|
### Changed
|
|
143
|
+
|
|
100
144
|
- **BREAKING:** Update ESM build to be fully compliant with the ESM standard ([#2210](https://github.com/MetaMask/snaps/pull/2210))
|
|
101
145
|
- Bump `@metamask/rpc-errors` to `^6.2.1` ([#2209](https://github.com/MetaMask/snaps/pull/2209))
|
|
102
146
|
|
|
103
147
|
## [6.0.0]
|
|
148
|
+
|
|
104
149
|
### Added
|
|
150
|
+
|
|
105
151
|
- **BREAKING:** Add support for dynamic user interfaces ([#1465](https://github.com/MetaMask/snaps/pull/1465), [#2144](https://github.com/MetaMask/snaps/pull/2144), [#2143](https://github.com/MetaMask/snaps/pull/2143))
|
|
106
152
|
- This adds the `snap_createInterface`, `snap_updateInterface`, and `snap_getInterfaceState` methods.
|
|
107
153
|
- This is breaking because it changes the expected type of the `showDialog` RPC method hook.
|
|
@@ -110,102 +156,143 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
110
156
|
- Add endowment permission specifications to this package ([#2155](https://github.com/MetaMask/snaps/pull/2155))
|
|
111
157
|
|
|
112
158
|
### Changed
|
|
159
|
+
|
|
113
160
|
- Bump MetaMask dependencies ([#2129](https://github.com/MetaMask/snaps/pull/2129), [#2142](https://github.com/MetaMask/snaps/pull/2142))
|
|
114
161
|
|
|
115
162
|
## [5.0.0]
|
|
163
|
+
|
|
116
164
|
### Added
|
|
165
|
+
|
|
117
166
|
- Add `snap_getClientStatus` ([#2051](https://github.com/MetaMask/snaps/pull/2051))
|
|
118
167
|
|
|
119
168
|
### Changed
|
|
169
|
+
|
|
120
170
|
- **BREAKING:** Use origin bound hooks for `invokeKeyring` ([#2090](https://github.com/MetaMask/snaps/pull/2090))
|
|
121
171
|
- Bump several MetaMask dependencies ([#2069](https://github.com/MetaMask/snaps/pull/2069), [#2100](https://github.com/MetaMask/snaps/pull/2100))
|
|
122
172
|
|
|
123
173
|
## [4.1.0]
|
|
174
|
+
|
|
124
175
|
### Added
|
|
176
|
+
|
|
125
177
|
- Add `wallet_getAllSnaps` method to get all installed Snaps ([#2047](https://github.com/MetaMask/snaps/pull/2047))
|
|
126
178
|
|
|
127
179
|
### Changed
|
|
180
|
+
|
|
128
181
|
- Bump several MetaMask dependencies ([#2064](https://github.com/MetaMask/snaps/pull/2064), [#2065](https://github.com/MetaMask/snaps/pull/2065))
|
|
129
182
|
|
|
130
183
|
## [4.0.3]
|
|
184
|
+
|
|
131
185
|
### Changed
|
|
186
|
+
|
|
132
187
|
- Use prototype `startsWith` for RPC method middleware ([#2035](https://github.com/MetaMask/snaps/pull/2035))
|
|
133
188
|
|
|
134
189
|
## [4.0.2]
|
|
190
|
+
|
|
135
191
|
### Changed
|
|
192
|
+
|
|
136
193
|
- Bump several MetaMask dependencies ([#1989](https://github.com/MetaMask/snaps/pull/1989))
|
|
137
194
|
|
|
138
195
|
## [4.0.1]
|
|
196
|
+
|
|
139
197
|
### Changed
|
|
198
|
+
|
|
140
199
|
- Bump several MetaMask dependencies ([#1964](https://github.com/MetaMask/snaps/pull/1964), [#1968](https://github.com/MetaMask/snaps/pull/1968))
|
|
141
200
|
|
|
142
201
|
## [4.0.0]
|
|
202
|
+
|
|
143
203
|
### Changed
|
|
204
|
+
|
|
144
205
|
- Use `@metamask/snaps-sdk` package ([#1930](https://github.com/MetaMask/snaps/pull/1930),
|
|
145
206
|
[#1950](https://github.com/MetaMask/snaps/pull/1950), [#1954](https://github.com/MetaMask/snaps/pull/1954))
|
|
146
207
|
- This package replaces the `@metamask/snaps-types` and
|
|
147
208
|
- `@metamask/snaps-ui` packages.
|
|
148
209
|
|
|
149
210
|
### Removed
|
|
211
|
+
|
|
150
212
|
- **BREAKING**: Remove `DialogType`, `ManageStateOperation`, and `NotificationType` enums ([#1930](https://github.com/MetaMask/snaps/pull/1930))
|
|
151
213
|
- These are now defined in the `@metamask/snaps-sdk` package.
|
|
152
214
|
|
|
153
215
|
## [3.3.0]
|
|
216
|
+
|
|
154
217
|
### Added
|
|
218
|
+
|
|
155
219
|
- Add support for unencrypted storage using `snap_manageState` ([#1902](https://github.com/MetaMask/snaps/pull/1902))
|
|
156
220
|
|
|
157
221
|
## [3.2.1]
|
|
222
|
+
|
|
158
223
|
### Fixed
|
|
224
|
+
|
|
159
225
|
- Fix `assertLinksAreSafe` import ([#1908](https://github.com/MetaMask/snaps/pull/1908))
|
|
160
226
|
|
|
161
227
|
## [3.2.0]
|
|
228
|
+
|
|
162
229
|
### Added
|
|
230
|
+
|
|
163
231
|
- Add support for links in custom UI and notifications ([#1814](https://github.com/MetaMask/snaps/pull/1814))
|
|
164
232
|
|
|
165
233
|
## [3.1.0]
|
|
234
|
+
|
|
166
235
|
### Changed
|
|
236
|
+
|
|
167
237
|
- Rename package to `@metamask/snaps-rpc-methods` ([#1864](https://github.com/MetaMask/snaps/pull/1864))
|
|
168
238
|
- Update multiple MetaMask dependencies ([#1841](https://github.com/MetaMask/snaps/pull/1841))
|
|
169
239
|
|
|
170
240
|
## [3.0.0]
|
|
241
|
+
|
|
171
242
|
### Added
|
|
243
|
+
|
|
172
244
|
- Add keyring export and endowment ([#1787](https://github.com/MetaMask/snaps/pull/1787))
|
|
173
245
|
|
|
174
246
|
### Changed
|
|
247
|
+
|
|
175
248
|
- **BREAKING:** Bump minimum Node.js version to `^18.16.0` ([#1741](https://github.com/MetaMask/snaps/pull/1741))
|
|
176
249
|
|
|
177
250
|
## [2.0.0]
|
|
251
|
+
|
|
178
252
|
### Changed
|
|
253
|
+
|
|
179
254
|
- Initial stable release from main branch ([#1757](https://github.com/MetaMask/snaps/pull/1757))
|
|
180
255
|
|
|
181
256
|
## [0.38.3-flask.1]
|
|
257
|
+
|
|
182
258
|
### Changed
|
|
259
|
+
|
|
183
260
|
- Bump `metamask/utils` and `metamask/snaps-registry` ([#1738](https://github.com/MetaMask/snaps/pull/1738))
|
|
184
261
|
|
|
185
262
|
## [0.38.2-flask.1]
|
|
263
|
+
|
|
186
264
|
### Changed
|
|
265
|
+
|
|
187
266
|
- Remove business-logic callbacks from `manageAccounts` ([#1725](https://github.com/MetaMask/snaps/pull/1725))
|
|
188
267
|
- Bump `@metamask/utils` and `@metamask/snaps-registry` ([#1694](https://github.com/MetaMask/snaps/pull/1694))
|
|
189
268
|
|
|
190
269
|
## [0.38.1-flask.1]
|
|
270
|
+
|
|
191
271
|
### Fixed
|
|
272
|
+
|
|
192
273
|
- Make `manageAccounts` arguments extend `RestrictedMethodParameters` ([#1687](https://github.com/MetaMask/snaps/pull/1687))
|
|
193
274
|
|
|
194
275
|
## [0.38.0-flask.1]
|
|
276
|
+
|
|
195
277
|
### Added
|
|
278
|
+
|
|
196
279
|
- Add `snap_getLocale` JSON-RPC method ([#1557](https://github.com/MetaMask/snaps/pull/1557))
|
|
197
280
|
- This will let snaps get the user locale from the client.
|
|
198
281
|
|
|
199
282
|
### Fixed
|
|
283
|
+
|
|
200
284
|
- Fix ed25519 public key derivation ([#1678](https://github.com/MetaMask/snaps/pull/1678))
|
|
201
285
|
|
|
202
286
|
## [0.37.2-flask.1]
|
|
287
|
+
|
|
203
288
|
### Changed
|
|
289
|
+
|
|
204
290
|
- Release package independently ([#1600](https://github.com/MetaMask/snaps/pull/1600))
|
|
205
291
|
- The version of the package no longer needs to match the version of all other
|
|
206
292
|
MetaMask Snaps packages.
|
|
207
293
|
|
|
208
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@11.
|
|
294
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@11.2.0...HEAD
|
|
295
|
+
[11.2.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@11.1.1...@metamask/snaps-rpc-methods@11.2.0
|
|
209
296
|
[11.1.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@11.1.0...@metamask/snaps-rpc-methods@11.1.1
|
|
210
297
|
[11.1.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@11.0.0...@metamask/snaps-rpc-methods@11.1.0
|
|
211
298
|
[11.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-rpc-methods@10.0.1...@metamask/snaps-rpc-methods@11.0.0
|
|
@@ -4,9 +4,41 @@ exports.getValidatedParams = exports.getImplementation = exports.notifyBuilder =
|
|
|
4
4
|
const permission_controller_1 = require("@metamask/permission-controller");
|
|
5
5
|
const rpc_errors_1 = require("@metamask/rpc-errors");
|
|
6
6
|
const snaps_sdk_1 = require("@metamask/snaps-sdk");
|
|
7
|
+
const jsx_1 = require("@metamask/snaps-sdk/jsx");
|
|
7
8
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
9
|
+
const superstruct_1 = require("@metamask/superstruct");
|
|
8
10
|
const utils_1 = require("@metamask/utils");
|
|
9
11
|
const methodName = 'snap_notify';
|
|
12
|
+
const NativeNotificationStruct = (0, superstruct_1.object)({
|
|
13
|
+
type: (0, snaps_sdk_1.enumValue)(snaps_sdk_1.NotificationType.Native),
|
|
14
|
+
message: (0, superstruct_1.string)(),
|
|
15
|
+
});
|
|
16
|
+
const InAppNotificationStruct = (0, superstruct_1.object)({
|
|
17
|
+
type: (0, snaps_sdk_1.enumValue)(snaps_sdk_1.NotificationType.InApp),
|
|
18
|
+
message: (0, superstruct_1.string)(),
|
|
19
|
+
});
|
|
20
|
+
const InAppNotificationWithDetailsStruct = (0, superstruct_1.object)({
|
|
21
|
+
type: (0, snaps_sdk_1.enumValue)(snaps_sdk_1.NotificationType.InApp),
|
|
22
|
+
message: (0, superstruct_1.string)(),
|
|
23
|
+
content: jsx_1.NotificationComponentsStruct,
|
|
24
|
+
title: (0, superstruct_1.string)(),
|
|
25
|
+
});
|
|
26
|
+
const InAppNotificationWithDetailsAndFooterStruct = (0, superstruct_1.object)({
|
|
27
|
+
type: (0, snaps_sdk_1.enumValue)(snaps_sdk_1.NotificationType.InApp),
|
|
28
|
+
message: (0, superstruct_1.string)(),
|
|
29
|
+
content: jsx_1.NotificationComponentsStruct,
|
|
30
|
+
title: (0, superstruct_1.string)(),
|
|
31
|
+
footerLink: (0, superstruct_1.object)({
|
|
32
|
+
href: (0, superstruct_1.string)(),
|
|
33
|
+
text: (0, superstruct_1.string)(),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
const NotificationParametersStruct = (0, snaps_sdk_1.union)([
|
|
37
|
+
InAppNotificationStruct,
|
|
38
|
+
InAppNotificationWithDetailsStruct,
|
|
39
|
+
InAppNotificationWithDetailsAndFooterStruct,
|
|
40
|
+
NativeNotificationStruct,
|
|
41
|
+
]);
|
|
10
42
|
/**
|
|
11
43
|
* The specification builder for the `snap_notify` permission.
|
|
12
44
|
* `snap_notify` allows snaps to send multiple types of notifications to its users.
|
|
@@ -31,6 +63,8 @@ const methodHooks = {
|
|
|
31
63
|
showInAppNotification: true,
|
|
32
64
|
isOnPhishingList: true,
|
|
33
65
|
maybeUpdatePhishingList: true,
|
|
66
|
+
createInterface: true,
|
|
67
|
+
getSnap: true,
|
|
34
68
|
};
|
|
35
69
|
exports.notifyBuilder = Object.freeze({
|
|
36
70
|
targetName: methodName,
|
|
@@ -45,15 +79,21 @@ exports.notifyBuilder = Object.freeze({
|
|
|
45
79
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
46
80
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
47
81
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
82
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
83
|
+
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
48
84
|
* @returns The method implementation which returns `null` on success.
|
|
49
85
|
* @throws If the params are invalid.
|
|
50
86
|
*/
|
|
51
|
-
function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, }) {
|
|
87
|
+
function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }) {
|
|
52
88
|
return async function implementation(args) {
|
|
53
89
|
const { params, context: { origin }, } = args;
|
|
54
|
-
const validatedParams = getValidatedParams(params);
|
|
55
90
|
await maybeUpdatePhishingList();
|
|
56
|
-
(
|
|
91
|
+
const validatedParams = getValidatedParams(params, isOnPhishingList, getSnap);
|
|
92
|
+
let id;
|
|
93
|
+
if ((0, utils_1.hasProperty)(validatedParams, 'content')) {
|
|
94
|
+
id = await createInterface(origin, validatedParams.content);
|
|
95
|
+
validatedParams.content = id;
|
|
96
|
+
}
|
|
57
97
|
switch (validatedParams.type) {
|
|
58
98
|
case snaps_sdk_1.NotificationType.Native:
|
|
59
99
|
return await showNativeNotification(origin, validatedParams);
|
|
@@ -72,9 +112,12 @@ exports.getImplementation = getImplementation;
|
|
|
72
112
|
* type. Throws if validation fails.
|
|
73
113
|
*
|
|
74
114
|
* @param params - The unvalidated params object from the method request.
|
|
115
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
116
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
75
117
|
* @returns The validated method parameter object.
|
|
118
|
+
* @throws If the params are invalid.
|
|
76
119
|
*/
|
|
77
|
-
function getValidatedParams(params) {
|
|
120
|
+
function getValidatedParams(params, isOnPhishingList, getSnap) {
|
|
78
121
|
if (!(0, utils_1.isObject)(params)) {
|
|
79
122
|
throw rpc_errors_1.rpcErrors.invalidParams({
|
|
80
123
|
message: 'Expected params to be a single object.',
|
|
@@ -102,7 +145,20 @@ function getValidatedParams(params) {
|
|
|
102
145
|
message: 'Must specify a non-empty string "message" less than 500 characters long.',
|
|
103
146
|
});
|
|
104
147
|
}
|
|
105
|
-
|
|
148
|
+
try {
|
|
149
|
+
const validatedParams = (0, snaps_utils_1.createUnion)(params, NotificationParametersStruct, 'type');
|
|
150
|
+
(0, snaps_utils_1.validateTextLinks)(validatedParams.message, isOnPhishingList, getSnap);
|
|
151
|
+
if ((0, utils_1.hasProperty)(validatedParams, 'footerLink')) {
|
|
152
|
+
(0, snaps_utils_1.validateTextLinks)(validatedParams.footerLink.text, isOnPhishingList, getSnap);
|
|
153
|
+
(0, snaps_utils_1.validateLink)(validatedParams.footerLink.href, isOnPhishingList, getSnap);
|
|
154
|
+
}
|
|
155
|
+
return validatedParams;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
throw rpc_errors_1.rpcErrors.invalidParams({
|
|
159
|
+
message: `Invalid params: ${error.message}`,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
106
162
|
}
|
|
107
163
|
exports.getValidatedParams = getValidatedParams;
|
|
108
164
|
//# sourceMappingURL=notify.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.cjs","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 { 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\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};\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 * @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}: 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);\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.cjs","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 { enumValue, NotificationType, union } from '@metamask/snaps-sdk';\nimport type {\n NotifyParams,\n NotifyResult,\n NotificationComponent,\n} from '@metamask/snaps-sdk';\nimport { NotificationComponentsStruct } from '@metamask/snaps-sdk/jsx';\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 } 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: NotificationComponentsStruct,\n title: string(),\n});\n\nconst InAppNotificationWithDetailsAndFooterStruct = object({\n type: enumValue(NotificationType.InApp),\n message: string(),\n content: NotificationComponentsStruct,\n title: string(),\n footerLink: object({\n href: string(),\n text: string(),\n }),\n});\n\nconst NotificationParametersStruct = union([\n InAppNotificationStruct,\n InAppNotificationWithDetailsStruct,\n InAppNotificationWithDetailsAndFooterStruct,\n NativeNotificationStruct,\n]);\n\nexport type NotificationParameters = 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: NotificationParameters,\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: NotificationParameters,\n ) => Promise<null>;\n\n isOnPhishingList: (url: string) => boolean;\n\n maybeUpdatePhishingList: () => Promise<void>;\n\n createInterface: (\n origin: string,\n content: NotificationComponent,\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 let id;\n if (hasProperty(validatedParams, 'content')) {\n id = await createInterface(\n origin,\n validatedParams.content as NotificationComponent,\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 validateTextLinks(\n validatedParams.footerLink.text,\n isOnPhishingList,\n getSnap,\n );\n validateLink(validatedParams.footerLink.href, isOnPhishingList, getSnap);\n }\n\n return validatedParams;\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}`,\n });\n }\n}\n"]}
|
|
@@ -1,33 +1,109 @@
|
|
|
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, NotificationComponent } from "@metamask/snaps-sdk";
|
|
4
|
+
import { type Snap } from "@metamask/snaps-utils";
|
|
5
|
+
import type { InferMatching } from "@metamask/snaps-utils";
|
|
5
6
|
import type { NonEmptyArray } from "@metamask/utils";
|
|
6
7
|
import { type MethodHooksObject } from "../utils.cjs";
|
|
7
8
|
declare const methodName = "snap_notify";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Enum type to determine notification type.
|
|
11
|
-
*/
|
|
12
|
-
type: EnumToUnion<NotificationType>;
|
|
13
|
-
/**
|
|
14
|
-
* A message to show on the notification.
|
|
15
|
-
*/
|
|
9
|
+
declare const NotificationParametersStruct: import("@metamask/superstruct").Struct<{
|
|
10
|
+
type: "native";
|
|
16
11
|
message: string;
|
|
17
|
-
}
|
|
12
|
+
} | {
|
|
13
|
+
type: "inApp";
|
|
14
|
+
message: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "inApp";
|
|
17
|
+
message: string;
|
|
18
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
19
|
+
src: string;
|
|
20
|
+
alt?: string | undefined;
|
|
21
|
+
}, "Image">;
|
|
22
|
+
title: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: "inApp";
|
|
25
|
+
message: string;
|
|
26
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
27
|
+
src: string;
|
|
28
|
+
alt?: string | undefined;
|
|
29
|
+
}, "Image">;
|
|
30
|
+
title: string;
|
|
31
|
+
footerLink: {
|
|
32
|
+
text: string;
|
|
33
|
+
href: string;
|
|
34
|
+
};
|
|
35
|
+
}, [head: import("@metamask/superstruct").Struct<{
|
|
36
|
+
type: "inApp";
|
|
37
|
+
message: string;
|
|
38
|
+
}, {
|
|
39
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
40
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
41
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
42
|
+
type: "inApp";
|
|
43
|
+
message: string;
|
|
44
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
45
|
+
src: string;
|
|
46
|
+
alt?: string | undefined;
|
|
47
|
+
}, "Image">;
|
|
48
|
+
title: string;
|
|
49
|
+
}, {
|
|
50
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
51
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
52
|
+
content: import("@metamask/superstruct").Struct<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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
53
|
+
src: string;
|
|
54
|
+
alt?: string | undefined;
|
|
55
|
+
}, "Image">, null>;
|
|
56
|
+
title: import("@metamask/superstruct").Struct<string, null>;
|
|
57
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
58
|
+
type: "inApp";
|
|
59
|
+
message: string;
|
|
60
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
61
|
+
src: string;
|
|
62
|
+
alt?: string | undefined;
|
|
63
|
+
}, "Image">;
|
|
64
|
+
title: string;
|
|
65
|
+
footerLink: {
|
|
66
|
+
text: string;
|
|
67
|
+
href: string;
|
|
68
|
+
};
|
|
69
|
+
}, {
|
|
70
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
71
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
72
|
+
content: import("@metamask/superstruct").Struct<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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
73
|
+
src: string;
|
|
74
|
+
alt?: string | undefined;
|
|
75
|
+
}, "Image">, null>;
|
|
76
|
+
title: import("@metamask/superstruct").Struct<string, null>;
|
|
77
|
+
footerLink: import("@metamask/superstruct").Struct<{
|
|
78
|
+
text: string;
|
|
79
|
+
href: string;
|
|
80
|
+
}, {
|
|
81
|
+
href: import("@metamask/superstruct").Struct<string, null>;
|
|
82
|
+
text: import("@metamask/superstruct").Struct<string, null>;
|
|
83
|
+
}>;
|
|
84
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
85
|
+
type: "native";
|
|
86
|
+
message: string;
|
|
87
|
+
}, {
|
|
88
|
+
type: import("@metamask/superstruct").Struct<"native", null>;
|
|
89
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
90
|
+
}>]>;
|
|
91
|
+
export type NotificationParameters = InferMatching<typeof NotificationParametersStruct, NotifyParams>;
|
|
18
92
|
export type NotifyMethodHooks = {
|
|
19
93
|
/**
|
|
20
94
|
* @param snapId - The ID of the Snap that created the notification.
|
|
21
95
|
* @param args - The notification arguments.
|
|
22
96
|
*/
|
|
23
|
-
showNativeNotification: (snapId: string, args:
|
|
97
|
+
showNativeNotification: (snapId: string, args: NotificationParameters) => Promise<null>;
|
|
24
98
|
/**
|
|
25
99
|
* @param snapId - The ID of the Snap that created the notification.
|
|
26
100
|
* @param args - The notification arguments.
|
|
27
101
|
*/
|
|
28
|
-
showInAppNotification: (snapId: string, args:
|
|
102
|
+
showInAppNotification: (snapId: string, args: NotificationParameters) => Promise<null>;
|
|
29
103
|
isOnPhishingList: (url: string) => boolean;
|
|
30
104
|
maybeUpdatePhishingList: () => Promise<void>;
|
|
105
|
+
createInterface: (origin: string, content: NotificationComponent) => Promise<string>;
|
|
106
|
+
getSnap: (snapId: string) => Snap | undefined;
|
|
31
107
|
};
|
|
32
108
|
type SpecificationBuilderOptions = {
|
|
33
109
|
allowedCaveats?: Readonly<NonEmptyArray<string>> | null;
|
|
@@ -67,17 +143,22 @@ export declare const notifyBuilder: Readonly<{
|
|
|
67
143
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
68
144
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
69
145
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
146
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
147
|
+
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
70
148
|
* @returns The method implementation which returns `null` on success.
|
|
71
149
|
* @throws If the params are invalid.
|
|
72
150
|
*/
|
|
73
|
-
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
151
|
+
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
74
152
|
/**
|
|
75
153
|
* Validates the notify method `params` and returns them cast to the correct
|
|
76
154
|
* type. Throws if validation fails.
|
|
77
155
|
*
|
|
78
156
|
* @param params - The unvalidated params object from the method request.
|
|
157
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
158
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
79
159
|
* @returns The validated method parameter object.
|
|
160
|
+
* @throws If the params are invalid.
|
|
80
161
|
*/
|
|
81
|
-
export declare function getValidatedParams(params: unknown): NotifyParams;
|
|
162
|
+
export declare function getValidatedParams(params: unknown, isOnPhishingList: NotifyMethodHooks['isOnPhishingList'], getSnap: NotifyMethodHooks['getSnap']): NotifyParams;
|
|
82
163
|
export {};
|
|
83
164
|
//# sourceMappingURL=notify.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notify.d.cts","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;
|
|
1
|
+
{"version":3,"file":"notify.d.cts","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;AAG9E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,EAIL,KAAK,IAAI,EACV,8BAA8B;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA8B;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,EAAE,KAAK,iBAAiB,EAAE,qBAAiB;AAElD,QAAA,MAAM,UAAU,gBAAgB,CAAC;AA8BjC,QAAA,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKhC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,aAAa,CAChD,OAAO,4BAA4B,EACnC,YAAY,CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,sBAAsB,EAAE,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,sBAAsB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,qBAAqB,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,sBAAsB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAE3C,uBAAuB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,eAAe,EAAE,CACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,KAAK,aAAa,GAAG,4BAA4B,CAAC;IAChD,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC;IAChD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,oBAAoB,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC3D,cAAc,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;CACxD,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,8BAA8B,CAC/D,cAAc,CAAC,gBAAgB,EAC/B,2BAA2B,EAC3B,aAAa,CASd,CAAC;AAWF,eAAO,MAAM,aAAa;;;wBAtCR,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,wBAAwB,CAAC;wBAC1C,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;;;EAuC7C,CAAC;AAEZ;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,OAAO,GACR,EAAE,iBAAiB,UAEV,wBAAwB,YAAY,CAAC,KAC1C,QAAQ,YAAY,CAAC,CAkCzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,EACf,gBAAgB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,EACvD,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,GACpC,YAAY,CAiEd"}
|
|
@@ -1,33 +1,109 @@
|
|
|
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, NotificationComponent } from "@metamask/snaps-sdk";
|
|
4
|
+
import { type Snap } from "@metamask/snaps-utils";
|
|
5
|
+
import type { InferMatching } from "@metamask/snaps-utils";
|
|
5
6
|
import type { NonEmptyArray } from "@metamask/utils";
|
|
6
7
|
import { type MethodHooksObject } from "../utils.mjs";
|
|
7
8
|
declare const methodName = "snap_notify";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
* Enum type to determine notification type.
|
|
11
|
-
*/
|
|
12
|
-
type: EnumToUnion<NotificationType>;
|
|
13
|
-
/**
|
|
14
|
-
* A message to show on the notification.
|
|
15
|
-
*/
|
|
9
|
+
declare const NotificationParametersStruct: import("@metamask/superstruct").Struct<{
|
|
10
|
+
type: "native";
|
|
16
11
|
message: string;
|
|
17
|
-
}
|
|
12
|
+
} | {
|
|
13
|
+
type: "inApp";
|
|
14
|
+
message: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: "inApp";
|
|
17
|
+
message: string;
|
|
18
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
19
|
+
src: string;
|
|
20
|
+
alt?: string | undefined;
|
|
21
|
+
}, "Image">;
|
|
22
|
+
title: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: "inApp";
|
|
25
|
+
message: string;
|
|
26
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
27
|
+
src: string;
|
|
28
|
+
alt?: string | undefined;
|
|
29
|
+
}, "Image">;
|
|
30
|
+
title: string;
|
|
31
|
+
footerLink: {
|
|
32
|
+
text: string;
|
|
33
|
+
href: string;
|
|
34
|
+
};
|
|
35
|
+
}, [head: import("@metamask/superstruct").Struct<{
|
|
36
|
+
type: "inApp";
|
|
37
|
+
message: string;
|
|
38
|
+
}, {
|
|
39
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
40
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
41
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
42
|
+
type: "inApp";
|
|
43
|
+
message: string;
|
|
44
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
45
|
+
src: string;
|
|
46
|
+
alt?: string | undefined;
|
|
47
|
+
}, "Image">;
|
|
48
|
+
title: string;
|
|
49
|
+
}, {
|
|
50
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
51
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
52
|
+
content: import("@metamask/superstruct").Struct<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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
53
|
+
src: string;
|
|
54
|
+
alt?: string | undefined;
|
|
55
|
+
}, "Image">, null>;
|
|
56
|
+
title: import("@metamask/superstruct").Struct<string, null>;
|
|
57
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
58
|
+
type: "inApp";
|
|
59
|
+
message: string;
|
|
60
|
+
content: 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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
61
|
+
src: string;
|
|
62
|
+
alt?: string | undefined;
|
|
63
|
+
}, "Image">;
|
|
64
|
+
title: string;
|
|
65
|
+
footerLink: {
|
|
66
|
+
text: string;
|
|
67
|
+
href: string;
|
|
68
|
+
};
|
|
69
|
+
}, {
|
|
70
|
+
type: import("@metamask/superstruct").Struct<"inApp", null>;
|
|
71
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
72
|
+
content: import("@metamask/superstruct").Struct<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").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").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").TextProps, "Text"> | import("@metamask/snaps-sdk/jsx").SnapElement<import("@metamask/snaps-sdk/jsx").TooltipProps, "Tooltip"> | import("@metamask/snaps-sdk/jsx").SnapElement<{
|
|
73
|
+
src: string;
|
|
74
|
+
alt?: string | undefined;
|
|
75
|
+
}, "Image">, null>;
|
|
76
|
+
title: import("@metamask/superstruct").Struct<string, null>;
|
|
77
|
+
footerLink: import("@metamask/superstruct").Struct<{
|
|
78
|
+
text: string;
|
|
79
|
+
href: string;
|
|
80
|
+
}, {
|
|
81
|
+
href: import("@metamask/superstruct").Struct<string, null>;
|
|
82
|
+
text: import("@metamask/superstruct").Struct<string, null>;
|
|
83
|
+
}>;
|
|
84
|
+
}>, import("@metamask/superstruct").Struct<{
|
|
85
|
+
type: "native";
|
|
86
|
+
message: string;
|
|
87
|
+
}, {
|
|
88
|
+
type: import("@metamask/superstruct").Struct<"native", null>;
|
|
89
|
+
message: import("@metamask/superstruct").Struct<string, null>;
|
|
90
|
+
}>]>;
|
|
91
|
+
export type NotificationParameters = InferMatching<typeof NotificationParametersStruct, NotifyParams>;
|
|
18
92
|
export type NotifyMethodHooks = {
|
|
19
93
|
/**
|
|
20
94
|
* @param snapId - The ID of the Snap that created the notification.
|
|
21
95
|
* @param args - The notification arguments.
|
|
22
96
|
*/
|
|
23
|
-
showNativeNotification: (snapId: string, args:
|
|
97
|
+
showNativeNotification: (snapId: string, args: NotificationParameters) => Promise<null>;
|
|
24
98
|
/**
|
|
25
99
|
* @param snapId - The ID of the Snap that created the notification.
|
|
26
100
|
* @param args - The notification arguments.
|
|
27
101
|
*/
|
|
28
|
-
showInAppNotification: (snapId: string, args:
|
|
102
|
+
showInAppNotification: (snapId: string, args: NotificationParameters) => Promise<null>;
|
|
29
103
|
isOnPhishingList: (url: string) => boolean;
|
|
30
104
|
maybeUpdatePhishingList: () => Promise<void>;
|
|
105
|
+
createInterface: (origin: string, content: NotificationComponent) => Promise<string>;
|
|
106
|
+
getSnap: (snapId: string) => Snap | undefined;
|
|
31
107
|
};
|
|
32
108
|
type SpecificationBuilderOptions = {
|
|
33
109
|
allowedCaveats?: Readonly<NonEmptyArray<string>> | null;
|
|
@@ -67,17 +143,22 @@ export declare const notifyBuilder: Readonly<{
|
|
|
67
143
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
68
144
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
69
145
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
146
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
147
|
+
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
70
148
|
* @returns The method implementation which returns `null` on success.
|
|
71
149
|
* @throws If the params are invalid.
|
|
72
150
|
*/
|
|
73
|
-
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
151
|
+
export declare function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }: NotifyMethodHooks): (args: RestrictedMethodOptions<NotifyParams>) => Promise<NotifyResult>;
|
|
74
152
|
/**
|
|
75
153
|
* Validates the notify method `params` and returns them cast to the correct
|
|
76
154
|
* type. Throws if validation fails.
|
|
77
155
|
*
|
|
78
156
|
* @param params - The unvalidated params object from the method request.
|
|
157
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
158
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
79
159
|
* @returns The validated method parameter object.
|
|
160
|
+
* @throws If the params are invalid.
|
|
80
161
|
*/
|
|
81
|
-
export declare function getValidatedParams(params: unknown): NotifyParams;
|
|
162
|
+
export declare function getValidatedParams(params: unknown, isOnPhishingList: NotifyMethodHooks['isOnPhishingList'], getSnap: NotifyMethodHooks['getSnap']): NotifyParams;
|
|
82
163
|
export {};
|
|
83
164
|
//# 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;
|
|
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;AAG9E,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACtB,4BAA4B;AAE7B,OAAO,EAIL,KAAK,IAAI,EACV,8BAA8B;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,8BAA8B;AAE3D,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB;AAGrD,OAAO,EAAE,KAAK,iBAAiB,EAAE,qBAAiB;AAElD,QAAA,MAAM,UAAU,gBAAgB,CAAC;AA8BjC,QAAA,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAKhC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,aAAa,CAChD,OAAO,4BAA4B,EACnC,YAAY,CACb,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;OAGG;IACH,sBAAsB,EAAE,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,sBAAsB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB;;;OAGG;IACH,qBAAqB,EAAE,CACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,sBAAsB,KACzB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAE3C,uBAAuB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,eAAe,EAAE,CACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,KAC3B,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,SAAS,CAAC;CAC/C,CAAC;AAEF,KAAK,2BAA2B,GAAG;IACjC,cAAc,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;IACxD,WAAW,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAEF,KAAK,aAAa,GAAG,4BAA4B,CAAC;IAChD,cAAc,EAAE,cAAc,CAAC,gBAAgB,CAAC;IAChD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,oBAAoB,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC3D,cAAc,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;CACxD,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,EAAE,8BAA8B,CAC/D,cAAc,CAAC,gBAAgB,EAC/B,2BAA2B,EAC3B,aAAa,CASd,CAAC;AAWF,eAAO,MAAM,aAAa;;;wBAtCR,eAAe,gBAAgB;oBACnC,iBAAiB;8BACP,WAAW,wBAAwB,CAAC;wBAC1C,SAAS,cAAc,MAAM,CAAC,CAAC,GAAG,IAAI;;;EAuC7C,CAAC;AAEZ;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,OAAO,GACR,EAAE,iBAAiB,UAEV,wBAAwB,YAAY,CAAC,KAC1C,QAAQ,YAAY,CAAC,CAkCzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,OAAO,EACf,gBAAgB,EAAE,iBAAiB,CAAC,kBAAkB,CAAC,EACvD,OAAO,EAAE,iBAAiB,CAAC,SAAS,CAAC,GACpC,YAAY,CAiEd"}
|
|
@@ -1,9 +1,41 @@
|
|
|
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 {
|
|
5
|
-
import {
|
|
3
|
+
import { enumValue, NotificationType, union } from "@metamask/snaps-sdk";
|
|
4
|
+
import { NotificationComponentsStruct } from "@metamask/snaps-sdk/jsx";
|
|
5
|
+
import { createUnion, validateLink, validateTextLinks } from "@metamask/snaps-utils";
|
|
6
|
+
import { object, string } from "@metamask/superstruct";
|
|
7
|
+
import { hasProperty, isObject } from "@metamask/utils";
|
|
6
8
|
const methodName = 'snap_notify';
|
|
9
|
+
const NativeNotificationStruct = object({
|
|
10
|
+
type: enumValue(NotificationType.Native),
|
|
11
|
+
message: string(),
|
|
12
|
+
});
|
|
13
|
+
const InAppNotificationStruct = object({
|
|
14
|
+
type: enumValue(NotificationType.InApp),
|
|
15
|
+
message: string(),
|
|
16
|
+
});
|
|
17
|
+
const InAppNotificationWithDetailsStruct = object({
|
|
18
|
+
type: enumValue(NotificationType.InApp),
|
|
19
|
+
message: string(),
|
|
20
|
+
content: NotificationComponentsStruct,
|
|
21
|
+
title: string(),
|
|
22
|
+
});
|
|
23
|
+
const InAppNotificationWithDetailsAndFooterStruct = object({
|
|
24
|
+
type: enumValue(NotificationType.InApp),
|
|
25
|
+
message: string(),
|
|
26
|
+
content: NotificationComponentsStruct,
|
|
27
|
+
title: string(),
|
|
28
|
+
footerLink: object({
|
|
29
|
+
href: string(),
|
|
30
|
+
text: string(),
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
const NotificationParametersStruct = union([
|
|
34
|
+
InAppNotificationStruct,
|
|
35
|
+
InAppNotificationWithDetailsStruct,
|
|
36
|
+
InAppNotificationWithDetailsAndFooterStruct,
|
|
37
|
+
NativeNotificationStruct,
|
|
38
|
+
]);
|
|
7
39
|
/**
|
|
8
40
|
* The specification builder for the `snap_notify` permission.
|
|
9
41
|
* `snap_notify` allows snaps to send multiple types of notifications to its users.
|
|
@@ -27,6 +59,8 @@ const methodHooks = {
|
|
|
27
59
|
showInAppNotification: true,
|
|
28
60
|
isOnPhishingList: true,
|
|
29
61
|
maybeUpdatePhishingList: true,
|
|
62
|
+
createInterface: true,
|
|
63
|
+
getSnap: true,
|
|
30
64
|
};
|
|
31
65
|
export const notifyBuilder = Object.freeze({
|
|
32
66
|
targetName: methodName,
|
|
@@ -41,15 +75,21 @@ export const notifyBuilder = Object.freeze({
|
|
|
41
75
|
* @param hooks.showInAppNotification - A function that shows a notification in the MetaMask UI.
|
|
42
76
|
* @param hooks.isOnPhishingList - A function that checks for links against the phishing list.
|
|
43
77
|
* @param hooks.maybeUpdatePhishingList - A function that updates the phishing list if needed.
|
|
78
|
+
* @param hooks.createInterface - A function that creates the interface in SnapInterfaceController.
|
|
79
|
+
* @param hooks.getSnap - A function that checks if a snap is installed.
|
|
44
80
|
* @returns The method implementation which returns `null` on success.
|
|
45
81
|
* @throws If the params are invalid.
|
|
46
82
|
*/
|
|
47
|
-
export function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, }) {
|
|
83
|
+
export function getImplementation({ showNativeNotification, showInAppNotification, isOnPhishingList, maybeUpdatePhishingList, createInterface, getSnap, }) {
|
|
48
84
|
return async function implementation(args) {
|
|
49
85
|
const { params, context: { origin }, } = args;
|
|
50
|
-
const validatedParams = getValidatedParams(params);
|
|
51
86
|
await maybeUpdatePhishingList();
|
|
52
|
-
|
|
87
|
+
const validatedParams = getValidatedParams(params, isOnPhishingList, getSnap);
|
|
88
|
+
let id;
|
|
89
|
+
if (hasProperty(validatedParams, 'content')) {
|
|
90
|
+
id = await createInterface(origin, validatedParams.content);
|
|
91
|
+
validatedParams.content = id;
|
|
92
|
+
}
|
|
53
93
|
switch (validatedParams.type) {
|
|
54
94
|
case NotificationType.Native:
|
|
55
95
|
return await showNativeNotification(origin, validatedParams);
|
|
@@ -67,9 +107,12 @@ export function getImplementation({ showNativeNotification, showInAppNotificatio
|
|
|
67
107
|
* type. Throws if validation fails.
|
|
68
108
|
*
|
|
69
109
|
* @param params - The unvalidated params object from the method request.
|
|
110
|
+
* @param isOnPhishingList - The function that checks for links against the phishing list.
|
|
111
|
+
* @param getSnap - A function that checks if a snap is installed.
|
|
70
112
|
* @returns The validated method parameter object.
|
|
113
|
+
* @throws If the params are invalid.
|
|
71
114
|
*/
|
|
72
|
-
export function getValidatedParams(params) {
|
|
115
|
+
export function getValidatedParams(params, isOnPhishingList, getSnap) {
|
|
73
116
|
if (!isObject(params)) {
|
|
74
117
|
throw rpcErrors.invalidParams({
|
|
75
118
|
message: 'Expected params to be a single object.',
|
|
@@ -97,6 +140,19 @@ export function getValidatedParams(params) {
|
|
|
97
140
|
message: 'Must specify a non-empty string "message" less than 500 characters long.',
|
|
98
141
|
});
|
|
99
142
|
}
|
|
100
|
-
|
|
143
|
+
try {
|
|
144
|
+
const validatedParams = createUnion(params, NotificationParametersStruct, 'type');
|
|
145
|
+
validateTextLinks(validatedParams.message, isOnPhishingList, getSnap);
|
|
146
|
+
if (hasProperty(validatedParams, 'footerLink')) {
|
|
147
|
+
validateTextLinks(validatedParams.footerLink.text, isOnPhishingList, getSnap);
|
|
148
|
+
validateLink(validatedParams.footerLink.href, isOnPhishingList, getSnap);
|
|
149
|
+
}
|
|
150
|
+
return validatedParams;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
throw rpcErrors.invalidParams({
|
|
154
|
+
message: `Invalid params: ${error.message}`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
101
157
|
}
|
|
102
158
|
//# 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 { 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\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};\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 * @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}: 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);\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 { enumValue, NotificationType, union } from '@metamask/snaps-sdk';\nimport type {\n NotifyParams,\n NotifyResult,\n NotificationComponent,\n} from '@metamask/snaps-sdk';\nimport { NotificationComponentsStruct } from '@metamask/snaps-sdk/jsx';\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 } 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: NotificationComponentsStruct,\n title: string(),\n});\n\nconst InAppNotificationWithDetailsAndFooterStruct = object({\n type: enumValue(NotificationType.InApp),\n message: string(),\n content: NotificationComponentsStruct,\n title: string(),\n footerLink: object({\n href: string(),\n text: string(),\n }),\n});\n\nconst NotificationParametersStruct = union([\n InAppNotificationStruct,\n InAppNotificationWithDetailsStruct,\n InAppNotificationWithDetailsAndFooterStruct,\n NativeNotificationStruct,\n]);\n\nexport type NotificationParameters = 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: NotificationParameters,\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: NotificationParameters,\n ) => Promise<null>;\n\n isOnPhishingList: (url: string) => boolean;\n\n maybeUpdatePhishingList: () => Promise<void>;\n\n createInterface: (\n origin: string,\n content: NotificationComponent,\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 let id;\n if (hasProperty(validatedParams, 'content')) {\n id = await createInterface(\n origin,\n validatedParams.content as NotificationComponent,\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 validateTextLinks(\n validatedParams.footerLink.text,\n isOnPhishingList,\n getSnap,\n );\n validateLink(validatedParams.footerLink.href, isOnPhishingList, getSnap);\n }\n\n return validatedParams;\n } catch (error) {\n throw rpcErrors.invalidParams({\n message: `Invalid params: ${error.message}`,\n });\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-rpc-methods",
|
|
3
|
-
"version": "11.
|
|
4
|
-
"description": "MetaMask Snaps JSON-RPC method implementations
|
|
3
|
+
"version": "11.2.0",
|
|
4
|
+
"description": "MetaMask Snaps JSON-RPC method implementations",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"MetaMask",
|
|
7
|
+
"Snaps",
|
|
8
|
+
"Ethereum"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/MetaMask/snaps/tree/main/packages/snaps-rpc-methods#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/MetaMask/snaps/issues"
|
|
13
|
+
},
|
|
5
14
|
"repository": {
|
|
6
15
|
"type": "git",
|
|
7
16
|
"url": "https://github.com/MetaMask/snaps.git"
|
|
8
17
|
},
|
|
18
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
9
19
|
"sideEffects": false,
|
|
10
20
|
"exports": {
|
|
11
21
|
".": {
|
|
@@ -27,25 +37,29 @@
|
|
|
27
37
|
"dist"
|
|
28
38
|
],
|
|
29
39
|
"scripts": {
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
40
|
+
"build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
|
|
41
|
+
"changelog:update": "../../scripts/update-changelog.sh @metamask/snaps-rpc-methods",
|
|
42
|
+
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/snaps-rpc-methods",
|
|
43
|
+
"lint": "yarn lint:eslint && yarn lint:misc --check && yarn changelog:validate && yarn lint:dependencies",
|
|
44
|
+
"lint:ci": "yarn lint",
|
|
45
|
+
"lint:dependencies": "depcheck",
|
|
33
46
|
"lint:eslint": "eslint . --cache --ext js,ts,jsx,tsx",
|
|
34
|
-
"lint:misc": "prettier --no-error-on-unmatched-pattern --loglevel warn \"**/*.json\" \"**/*.md\" \"**/*.html\" \"!CHANGELOG.md\" --ignore-path ../../.gitignore",
|
|
35
|
-
"lint": "yarn lint:eslint && yarn lint:misc --check && yarn lint:changelog && yarn lint:dependencies",
|
|
36
47
|
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
|
|
37
|
-
"lint:
|
|
38
|
-
"build": "ts-bridge --project tsconfig.build.json --verbose --no-references",
|
|
48
|
+
"lint:misc": "prettier --no-error-on-unmatched-pattern --loglevel warn \"**/*.json\" \"**/*.md\" \"**/*.html\" \"!CHANGELOG.md\" --ignore-path ../../.gitignore",
|
|
39
49
|
"publish:preview": "yarn npm publish --tag preview",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
50
|
+
"since-latest-release": "../../scripts/since-latest-release.sh",
|
|
51
|
+
"test": "jest --reporters=jest-silent-reporter",
|
|
52
|
+
"test:clean": "jest --clearCache",
|
|
53
|
+
"test:post": "jest-it-up",
|
|
54
|
+
"test:verbose": "jest --verbose",
|
|
55
|
+
"test:watch": "jest --watch"
|
|
42
56
|
},
|
|
43
57
|
"dependencies": {
|
|
44
58
|
"@metamask/key-tree": "^9.1.2",
|
|
45
59
|
"@metamask/permission-controller": "^11.0.0",
|
|
46
60
|
"@metamask/rpc-errors": "^6.3.1",
|
|
47
|
-
"@metamask/snaps-sdk": "^6.
|
|
48
|
-
"@metamask/snaps-utils": "^8.
|
|
61
|
+
"@metamask/snaps-sdk": "^6.6.0",
|
|
62
|
+
"@metamask/snaps-utils": "^8.2.0",
|
|
49
63
|
"@metamask/superstruct": "^3.1.0",
|
|
50
64
|
"@metamask/utils": "^9.2.1",
|
|
51
65
|
"@noble/hashes": "^1.3.1"
|
|
@@ -76,8 +90,9 @@
|
|
|
76
90
|
"eslint-plugin-promise": "^6.1.1",
|
|
77
91
|
"jest": "^29.0.2",
|
|
78
92
|
"jest-it-up": "^2.0.0",
|
|
79
|
-
"
|
|
80
|
-
"prettier
|
|
93
|
+
"jest-silent-reporter": "^0.6.0",
|
|
94
|
+
"prettier": "^2.8.8",
|
|
95
|
+
"prettier-plugin-packagejson": "^2.5.2",
|
|
81
96
|
"typescript": "~5.3.3"
|
|
82
97
|
},
|
|
83
98
|
"engines": {
|