@metamask-previews/gator-permissions-controller 1.1.2-preview-e8f4442d4 → 1.1.2-preview-27e39dd44

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +0 -6
  2. package/README.md +10 -15
  3. package/dist/GatorPermissionsController.cjs +176 -123
  4. package/dist/GatorPermissionsController.cjs.map +1 -1
  5. package/dist/GatorPermissionsController.d.cts +74 -56
  6. package/dist/GatorPermissionsController.d.cts.map +1 -1
  7. package/dist/GatorPermissionsController.d.mts +74 -56
  8. package/dist/GatorPermissionsController.d.mts.map +1 -1
  9. package/dist/GatorPermissionsController.mjs +176 -125
  10. package/dist/GatorPermissionsController.mjs.map +1 -1
  11. package/dist/errors.cjs +22 -1
  12. package/dist/errors.cjs.map +1 -1
  13. package/dist/errors.d.cts +11 -0
  14. package/dist/errors.d.cts.map +1 -1
  15. package/dist/errors.d.mts +11 -0
  16. package/dist/errors.d.mts.map +1 -1
  17. package/dist/errors.mjs +19 -0
  18. package/dist/errors.mjs.map +1 -1
  19. package/dist/index.cjs +4 -1
  20. package/dist/index.cjs.map +1 -1
  21. package/dist/index.d.cts +3 -2
  22. package/dist/index.d.cts.map +1 -1
  23. package/dist/index.d.mts +3 -2
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +1 -0
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/test/mocks.cjs +49 -28
  28. package/dist/test/mocks.cjs.map +1 -1
  29. package/dist/test/mocks.d.cts +16 -32
  30. package/dist/test/mocks.d.cts.map +1 -1
  31. package/dist/test/mocks.d.mts +16 -32
  32. package/dist/test/mocks.d.mts.map +1 -1
  33. package/dist/test/mocks.mjs +47 -27
  34. package/dist/test/mocks.mjs.map +1 -1
  35. package/dist/types.cjs +2 -0
  36. package/dist/types.cjs.map +1 -1
  37. package/dist/types.d.cts +74 -31
  38. package/dist/types.d.cts.map +1 -1
  39. package/dist/types.d.mts +74 -31
  40. package/dist/types.d.mts.map +1 -1
  41. package/dist/types.mjs +2 -0
  42. package/dist/types.mjs.map +1 -1
  43. package/dist/utils.cjs +30 -25
  44. package/dist/utils.cjs.map +1 -1
  45. package/dist/utils.d.cts +12 -18
  46. package/dist/utils.d.cts.map +1 -1
  47. package/dist/utils.d.mts +12 -18
  48. package/dist/utils.d.mts.map +1 -1
  49. package/dist/utils.mjs +28 -24
  50. package/dist/utils.mjs.map +1 -1
  51. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,12 +9,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Changed
11
11
 
12
- - **BREAKING:** Refactor `GatorPermissionsController`: simplified config, permission storage, and public API ([#7847](https://github.com/MetaMask/core/pull/7847))
13
- - Constructor now requires `config`, internal configuration is removed from controller state
14
- - New `initialize()` function performs a syncronisation process if required when the controller is first initialized
15
- - Replaces `gatorPermissionsMapSerialized` with `grantedPermissions` property in internal state, replaces related types, and utility functions
16
- - `fetchAndUpdateGatorPermissions()` no longer accepts parameters and resolves to `void`
17
- - `getPendingRevocations` / `pendingRevocations` getter replaced by `isPendingRevocation(permissionContext)`; list on `state.pendingRevocations`
18
12
  - Bump `@metamask/transaction-controller` from `^62.11.0` to `^62.17.0` ([#7775](https://github.com/MetaMask/core/pull/7775), [#7802](https://github.com/MetaMask/core/pull/7802), [#7832](https://github.com/MetaMask/core/pull/7832), [#7854](https://github.com/MetaMask/core/pull/7854), [#7872](https://github.com/MetaMask/core/pull/7872)), ([#7897](https://github.com/MetaMask/core/pull/7897))
19
13
 
20
14
  ## [1.1.2]
package/README.md CHANGED
@@ -17,21 +17,13 @@ or
17
17
  ```typescript
18
18
  import { GatorPermissionsController } from '@metamask/gator-permissions-controller';
19
19
 
20
- // Create the controller with required config
20
+ // Create the controller
21
21
  const gatorPermissionsController = new GatorPermissionsController({
22
22
  messenger: yourMessenger,
23
- config: {
24
- supportedPermissionTypes: [
25
- 'native-token-stream',
26
- 'native-token-periodic',
27
- 'erc20-token-stream',
28
- 'erc20-token-periodic',
29
- 'erc20-token-revocation',
30
- ],
31
- // Optional: override the default gator permissions provider Snap id
32
- // gatorPermissionsProviderSnapId: 'npm:@metamask/gator-permissions-snap',
33
- },
34
23
  });
24
+
25
+ // Enable the feature (requires authentication)
26
+ gatorPermissionsController.enableGatorPermissions();
35
27
  ```
36
28
 
37
29
  ### Fetch from Profile Sync
@@ -41,9 +33,12 @@ const gatorPermissionsController = new GatorPermissionsController({
41
33
  const permissions =
42
34
  await gatorPermissionsController.fetchAndUpdateGatorPermissions();
43
35
 
44
- // Fetch permissions and update internal state
45
- const permissions =
46
- await gatorPermissionsController.fetchAndUpdateGatorPermissions();
36
+ // Fetch permissions with optional filter params
37
+ const filteredPermissions =
38
+ await gatorPermissionsController.fetchAndUpdateGatorPermissions({
39
+ origin: 'https://example.com',
40
+ chainId: '0x1',
41
+ });
47
42
  ```
48
43
 
49
44
  ## Contributing
@@ -4,14 +4,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
5
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
6
  };
7
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
8
- if (kind === "m") throw new TypeError("Private method is not writable");
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
11
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
12
- };
13
- var _GatorPermissionsController_instances, _GatorPermissionsController_supportedPermissionTypes, _GatorPermissionsController_gatorPermissionsProviderSnapId, _GatorPermissionsController_maxSyncIntervalMs, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, _GatorPermissionsController_setIsFetchingGatorPermissions, _GatorPermissionsController_addPendingRevocationToState, _GatorPermissionsController_removePendingRevocationFromStateByTxId, _GatorPermissionsController_removePendingRevocationFromStateByPermissionContext, _GatorPermissionsController_registerMessageHandlers, _GatorPermissionsController_storedPermissionToPermissionInfo, _GatorPermissionsController_storedPermissionsToPermissionInfoWithMetadata;
7
+ var _GatorPermissionsController_instances, _GatorPermissionsController_setIsFetchingGatorPermissions, _GatorPermissionsController_setIsGatorPermissionsEnabled, _GatorPermissionsController_addPendingRevocationToState, _GatorPermissionsController_removePendingRevocationFromStateByTxId, _GatorPermissionsController_removePendingRevocationFromStateByPermissionContext, _GatorPermissionsController_registerMessageHandlers, _GatorPermissionsController_assertGatorPermissionsEnabled, _GatorPermissionsController_handleSnapRequestToGatorPermissionsProvider, _GatorPermissionsController_sanitizeStoredGatorPermission, _GatorPermissionsController_categorizePermissionsDataByTypeAndChainId;
14
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getDefaultGatorPermissionsControllerState = void 0;
15
10
  const base_controller_1 = require("@metamask/base-controller");
16
11
  const delegation_deployments_1 = require("@metamask/delegation-deployments");
17
12
  const snaps_utils_1 = require("@metamask/snaps-utils");
@@ -27,7 +22,16 @@ const utils_1 = require("./utils.cjs");
27
22
  const controllerName = 'GatorPermissionsController';
28
23
  // Default value for the gator permissions provider snap id
29
24
  const defaultGatorPermissionsProviderSnapId = 'npm:@metamask/gator-permissions-snap';
30
- const DEFAULT_MAX_SYNC_INTERVAL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days in milliseconds
25
+ const createEmptyGatorPermissionsMap = () => {
26
+ return {
27
+ 'erc20-token-revocation': {},
28
+ 'native-token-stream': {},
29
+ 'native-token-periodic': {},
30
+ 'erc20-token-stream': {},
31
+ 'erc20-token-periodic': {},
32
+ other: {},
33
+ };
34
+ };
31
35
  /**
32
36
  * Timeout duration for pending revocations (2 hours in milliseconds).
33
37
  * After this time, event listeners will be cleaned up to prevent memory leaks.
@@ -35,7 +39,13 @@ const DEFAULT_MAX_SYNC_INTERVAL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days in mil
35
39
  const PENDING_REVOCATION_TIMEOUT = 2 * 60 * 60 * 1000;
36
40
  const contractsByChainId = delegation_deployments_1.DELEGATOR_CONTRACTS[constants_1.DELEGATION_FRAMEWORK_VERSION];
37
41
  const gatorPermissionsControllerMetadata = {
38
- grantedPermissions: {
42
+ isGatorPermissionsEnabled: {
43
+ includeInStateLogs: true,
44
+ persist: true,
45
+ includeInDebugSnapshot: false,
46
+ usedInUi: false,
47
+ },
48
+ gatorPermissionsMapSerialized: {
39
49
  includeInStateLogs: true,
40
50
  persist: true,
41
51
  includeInDebugSnapshot: false,
@@ -45,149 +55,134 @@ const gatorPermissionsControllerMetadata = {
45
55
  includeInStateLogs: true,
46
56
  persist: false,
47
57
  includeInDebugSnapshot: false,
48
- usedInUi: true,
58
+ usedInUi: false,
49
59
  },
50
- pendingRevocations: {
60
+ gatorPermissionsProviderSnapId: {
51
61
  includeInStateLogs: true,
52
62
  persist: false,
53
63
  includeInDebugSnapshot: false,
54
- usedInUi: true,
64
+ usedInUi: false,
55
65
  },
56
- lastSyncedTimestamp: {
66
+ pendingRevocations: {
57
67
  includeInStateLogs: true,
58
- persist: true,
68
+ persist: false,
59
69
  includeInDebugSnapshot: false,
60
- usedInUi: false,
70
+ usedInUi: true,
61
71
  },
62
72
  };
63
73
  /**
64
- * Creates initial controller state, merging defaults with optional partial state.
65
- * Internal use only (e.g. constructor, tests).
74
+ * Constructs the default {@link GatorPermissionsController} state. This allows
75
+ * consumers to provide a partial state object when initializing the controller
76
+ * and also helps in constructing complete state objects for this controller in
77
+ * tests.
66
78
  *
67
- * @param state - Optional partial state to merge with defaults.
68
- * @returns Complete {@link GatorPermissionsController} state.
79
+ * @returns The default {@link GatorPermissionsController} state.
69
80
  */
70
- function createGatorPermissionsControllerState(state) {
81
+ function getDefaultGatorPermissionsControllerState() {
71
82
  return {
72
- grantedPermissions: [],
73
- pendingRevocations: [],
74
- lastSyncedTimestamp: -1,
75
- ...state,
76
- // isFetchingGatorPermissions is _always_ false when the controller is created
83
+ isGatorPermissionsEnabled: false,
84
+ gatorPermissionsMapSerialized: (0, utils_1.serializeGatorPermissionsMap)(createEmptyGatorPermissionsMap()),
77
85
  isFetchingGatorPermissions: false,
86
+ gatorPermissionsProviderSnapId: defaultGatorPermissionsProviderSnapId,
87
+ pendingRevocations: [],
78
88
  };
79
89
  }
90
+ exports.getDefaultGatorPermissionsControllerState = getDefaultGatorPermissionsControllerState;
80
91
  /**
81
- * Controller that manages gator permissions by reading from the gator permissions provider Snap.
92
+ * Controller that manages gator permissions by reading from profile sync
82
93
  */
83
94
  class GatorPermissionsController extends base_controller_1.BaseController {
84
- /**
85
- * The Snap ID of the gator permissions provider.
86
- *
87
- * @returns The Snap ID of the gator permissions provider.
88
- */
89
- get gatorPermissionsProviderSnapId() {
90
- return __classPrivateFieldGet(this, _GatorPermissionsController_gatorPermissionsProviderSnapId, "f");
91
- }
92
95
  /**
93
96
  * Creates a GatorPermissionsController instance.
94
97
  *
95
98
  * @param args - The arguments to this function.
96
- * @param args.messenger - Messenger used to communicate with other controllers.
97
- * @param args.config - Configuration (supported permission types and optional Snap id).
98
- * @param args.state - Optional partial state to merge with defaults.
99
+ * @param args.messenger - Messenger used to communicate with BaseV2 controller.
100
+ * @param args.state - Initial state to set on this controller.
99
101
  */
100
- constructor({ messenger, config, state, }) {
101
- const initialState = createGatorPermissionsControllerState(state);
102
+ constructor({ messenger, state, }) {
102
103
  super({
103
104
  name: controllerName,
104
105
  metadata: gatorPermissionsControllerMetadata,
105
106
  messenger,
106
- state: initialState,
107
+ state: {
108
+ ...getDefaultGatorPermissionsControllerState(),
109
+ ...state,
110
+ isFetchingGatorPermissions: false,
111
+ },
107
112
  });
108
113
  _GatorPermissionsController_instances.add(this);
109
- _GatorPermissionsController_supportedPermissionTypes.set(this, void 0);
110
- _GatorPermissionsController_gatorPermissionsProviderSnapId.set(this, void 0);
111
- _GatorPermissionsController_maxSyncIntervalMs.set(this, void 0);
112
- /**
113
- * When a sync is in progress, holds the promise for that sync so concurrent
114
- * callers receive the same promise. Cleared when the sync completes.
115
- */
116
- _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise.set(this, null);
117
- __classPrivateFieldSet(this, _GatorPermissionsController_supportedPermissionTypes, config.supportedPermissionTypes, "f");
118
- __classPrivateFieldSet(this, _GatorPermissionsController_gatorPermissionsProviderSnapId, config.gatorPermissionsProviderSnapId ??
119
- defaultGatorPermissionsProviderSnapId, "f");
120
- __classPrivateFieldSet(this, _GatorPermissionsController_maxSyncIntervalMs, config.maxSyncIntervalMs ?? DEFAULT_MAX_SYNC_INTERVAL_MS, "f");
121
114
  __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_registerMessageHandlers).call(this);
122
115
  }
123
116
  /**
124
- * Supported permission types this controller was configured with.
117
+ * Gets the gator permissions map from the state.
125
118
  *
126
- * @returns The supported permission types.
119
+ * @returns The gator permissions map.
127
120
  */
128
- get supportedPermissionTypes() {
129
- return __classPrivateFieldGet(this, _GatorPermissionsController_supportedPermissionTypes, "f");
121
+ get gatorPermissionsMap() {
122
+ return (0, utils_1.deserializeGatorPermissionsMap)(this.state.gatorPermissionsMapSerialized);
130
123
  }
131
124
  /**
132
- * Fetches granted permissions from the gator permissions provider Snap and updates state.
133
- * If a sync is already in progress, returns the same promise. After the sync completes,
134
- * the next call will perform a new sync.
125
+ * Gets the gator permissions provider snap id that is used to fetch gator permissions.
135
126
  *
136
- * @returns A promise that resolves when the sync completes. All data is available via the controller's state.
137
- * @throws {GatorPermissionsFetchError} If the gator permissions fetch fails.
127
+ * @returns The gator permissions provider snap id.
138
128
  */
139
- fetchAndUpdateGatorPermissions() {
140
- if (__classPrivateFieldGet(this, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, "f") !== null) {
141
- return __classPrivateFieldGet(this, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, "f");
142
- }
143
- const performFetchAndUpdate = async () => {
144
- try {
145
- __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_setIsFetchingGatorPermissions).call(this, true);
146
- // Only ever fetch non-revoked permissions. Revoked permissions may be
147
- // left in storage by the gator permissions snap, but we don't need to
148
- // fetch them.
149
- const params = { isRevoked: false };
150
- const permissionsData = await (0, utils_1.executeSnapRpc)({
151
- messenger: this.messenger,
152
- snapId: __classPrivateFieldGet(this, _GatorPermissionsController_gatorPermissionsProviderSnapId, "f"),
153
- method: types_1.GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,
154
- params,
155
- });
156
- const grantedPermissions = __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_storedPermissionsToPermissionInfoWithMetadata).call(this, permissionsData);
157
- this.update((state) => {
158
- state.grantedPermissions = grantedPermissions;
159
- state.lastSyncedTimestamp = Date.now();
160
- });
161
- }
162
- catch (error) {
163
- (0, logger_1.controllerLog)('Failed to fetch gator permissions', error);
164
- throw new errors_1.GatorPermissionsFetchError({
165
- message: 'Failed to fetch gator permissions',
166
- cause: error,
167
- });
168
- }
169
- finally {
170
- __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_setIsFetchingGatorPermissions).call(this, false);
171
- __classPrivateFieldSet(this, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, null, "f");
172
- }
173
- };
174
- __classPrivateFieldSet(this, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, performFetchAndUpdate(), "f");
175
- return __classPrivateFieldGet(this, _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise, "f");
129
+ get permissionsProviderSnapId() {
130
+ return this.state.gatorPermissionsProviderSnapId;
176
131
  }
177
132
  /**
178
- * Initializes the controller. Call once after construction to ensure the
179
- * controller is ready for use.
133
+ * Enables gator permissions for the user.
134
+ */
135
+ async enableGatorPermissions() {
136
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_setIsGatorPermissionsEnabled).call(this, true);
137
+ }
138
+ /**
139
+ * Clears the gator permissions map and disables the feature.
140
+ */
141
+ async disableGatorPermissions() {
142
+ this.update((state) => {
143
+ state.isGatorPermissionsEnabled = false;
144
+ state.gatorPermissionsMapSerialized = (0, utils_1.serializeGatorPermissionsMap)(createEmptyGatorPermissionsMap());
145
+ });
146
+ }
147
+ /**
148
+ * Gets the pending revocations list.
180
149
  *
181
- * @returns A promise that resolves when initialization is complete.
150
+ * @returns The pending revocations list.
182
151
  */
183
- async initialize() {
184
- const currentTime = Date.now();
185
- const millisecondsSinceLastSync = currentTime - this.state.lastSyncedTimestamp;
186
- // Sync only when we have no data or data is stale, to avoid excessive startup
187
- // queries while still avoiding showing stale data while a refresh runs.
188
- if (this.state.lastSyncedTimestamp === -1 ||
189
- millisecondsSinceLastSync > __classPrivateFieldGet(this, _GatorPermissionsController_maxSyncIntervalMs, "f")) {
190
- await this.fetchAndUpdateGatorPermissions();
152
+ get pendingRevocations() {
153
+ return this.state.pendingRevocations;
154
+ }
155
+ /**
156
+ * Fetches the gator permissions from profile sync and updates the state.
157
+ *
158
+ * @param params - Optional parameters to pass to the snap's getGrantedPermissions method.
159
+ * @returns A promise that resolves to the gator permissions map.
160
+ * @throws {GatorPermissionsFetchError} If the gator permissions fetch fails.
161
+ */
162
+ async fetchAndUpdateGatorPermissions(params) {
163
+ try {
164
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_setIsFetchingGatorPermissions).call(this, true);
165
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_assertGatorPermissionsEnabled).call(this);
166
+ const permissionsData = await __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_handleSnapRequestToGatorPermissionsProvider).call(this, {
167
+ snapId: this.state.gatorPermissionsProviderSnapId,
168
+ params,
169
+ });
170
+ const gatorPermissionsMap = __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_categorizePermissionsDataByTypeAndChainId).call(this, permissionsData);
171
+ this.update((state) => {
172
+ state.gatorPermissionsMapSerialized =
173
+ (0, utils_1.serializeGatorPermissionsMap)(gatorPermissionsMap);
174
+ });
175
+ return gatorPermissionsMap;
176
+ }
177
+ catch (error) {
178
+ (0, logger_1.controllerLog)('Failed to fetch gator permissions', error);
179
+ throw new errors_1.GatorPermissionsFetchError({
180
+ message: 'Failed to fetch gator permissions',
181
+ cause: error,
182
+ });
183
+ }
184
+ finally {
185
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_setIsFetchingGatorPermissions).call(this, false);
191
186
  }
192
187
  }
193
188
  /**
@@ -211,7 +206,7 @@ class GatorPermissionsController extends base_controller_1.BaseController {
211
206
  * or the enforcers/terms do not match a supported permission type.
212
207
  */
213
208
  decodePermissionFromPermissionContextForOrigin({ origin, chainId, delegation: { caveats, delegator, delegate, authority }, metadata: { justification, origin: specifiedOrigin }, }) {
214
- if (origin !== __classPrivateFieldGet(this, _GatorPermissionsController_gatorPermissionsProviderSnapId, "f")) {
209
+ if (origin !== this.permissionsProviderSnapId) {
215
210
  throw new errors_1.OriginNotAllowedError({ origin });
216
211
  }
217
212
  const contracts = contractsByChainId[chainId];
@@ -253,14 +248,16 @@ class GatorPermissionsController extends base_controller_1.BaseController {
253
248
  *
254
249
  * @param revocationParams - The revocation parameters containing the permission context.
255
250
  * @returns A promise that resolves when the revocation is submitted successfully.
251
+ * @throws {GatorPermissionsNotEnabledError} If the gator permissions are not enabled.
256
252
  * @throws {GatorPermissionsProviderError} If the snap request fails.
257
253
  */
258
254
  async submitRevocation(revocationParams) {
259
255
  (0, logger_1.controllerLog)('submitRevocation method called', {
260
256
  permissionContext: revocationParams.permissionContext,
261
257
  });
258
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_assertGatorPermissionsEnabled).call(this);
262
259
  const snapRequest = {
263
- snapId: __classPrivateFieldGet(this, _GatorPermissionsController_gatorPermissionsProviderSnapId, "f"),
260
+ snapId: this.state.gatorPermissionsProviderSnapId,
264
261
  origin: 'metamask',
265
262
  handler: snaps_utils_1.HandlerType.OnRpcRequest,
266
263
  request: {
@@ -272,7 +269,7 @@ class GatorPermissionsController extends base_controller_1.BaseController {
272
269
  try {
273
270
  const result = await this.messenger.call('SnapController:handleRequest', snapRequest);
274
271
  // Refresh list first (permission removed from list)
275
- await this.fetchAndUpdateGatorPermissions();
272
+ await this.fetchAndUpdateGatorPermissions({ isRevoked: false });
276
273
  (0, logger_1.controllerLog)('Successfully submitted revocation', {
277
274
  permissionContext: revocationParams.permissionContext,
278
275
  result,
@@ -328,6 +325,7 @@ class GatorPermissionsController extends base_controller_1.BaseController {
328
325
  txId,
329
326
  permissionContext,
330
327
  });
328
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_assertGatorPermissionsEnabled).call(this);
331
329
  // Track handlers and timeout for cleanup
332
330
  const handlers = {
333
331
  approved: undefined,
@@ -339,7 +337,7 @@ class GatorPermissionsController extends base_controller_1.BaseController {
339
337
  };
340
338
  // Helper to refresh permissions after transaction state change
341
339
  const refreshPermissions = (context) => {
342
- this.fetchAndUpdateGatorPermissions().catch((error) => {
340
+ this.fetchAndUpdateGatorPermissions({ isRevoked: false }).catch((error) => {
343
341
  (0, logger_1.controllerLog)(`Failed to refresh permissions after ${context}`, {
344
342
  txId,
345
343
  permissionContext,
@@ -490,9 +488,11 @@ class GatorPermissionsController extends base_controller_1.BaseController {
490
488
  *
491
489
  * @param params - The revocation parameters containing the permission context.
492
490
  * @returns A promise that resolves when the revocation is submitted successfully.
491
+ * @throws {GatorPermissionsNotEnabledError} If the gator permissions are not enabled.
493
492
  * @throws {GatorPermissionsProviderError} If the snap request fails.
494
493
  */
495
494
  async submitDirectRevocation(params) {
495
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_assertGatorPermissionsEnabled).call(this);
496
496
  // Use a placeholder txId that doesn't conflict with real transaction IDs
497
497
  const placeholderTxId = `no-tx-${params.permissionContext}`;
498
498
  // Add to pending revocations state first (disables UI button immediately)
@@ -507,15 +507,18 @@ class GatorPermissionsController extends base_controller_1.BaseController {
507
507
  * @returns `true` if the permission context is pending revocation, `false` otherwise.
508
508
  */
509
509
  isPendingRevocation(permissionContext) {
510
- const requestedPermissionContextLowercase = permissionContext.toLowerCase();
511
510
  return this.state.pendingRevocations.some((pendingRevocation) => pendingRevocation.permissionContext.toLowerCase() ===
512
- requestedPermissionContextLowercase);
511
+ permissionContext.toLowerCase());
513
512
  }
514
513
  }
515
- _GatorPermissionsController_supportedPermissionTypes = new WeakMap(), _GatorPermissionsController_gatorPermissionsProviderSnapId = new WeakMap(), _GatorPermissionsController_maxSyncIntervalMs = new WeakMap(), _GatorPermissionsController_fetchAndUpdateGatorPermissionsPromise = new WeakMap(), _GatorPermissionsController_instances = new WeakSet(), _GatorPermissionsController_setIsFetchingGatorPermissions = function _GatorPermissionsController_setIsFetchingGatorPermissions(isFetchingGatorPermissions) {
514
+ _GatorPermissionsController_instances = new WeakSet(), _GatorPermissionsController_setIsFetchingGatorPermissions = function _GatorPermissionsController_setIsFetchingGatorPermissions(isFetchingGatorPermissions) {
516
515
  this.update((state) => {
517
516
  state.isFetchingGatorPermissions = isFetchingGatorPermissions;
518
517
  });
518
+ }, _GatorPermissionsController_setIsGatorPermissionsEnabled = function _GatorPermissionsController_setIsGatorPermissionsEnabled(isGatorPermissionsEnabled) {
519
+ this.update((state) => {
520
+ state.isGatorPermissionsEnabled = isGatorPermissionsEnabled;
521
+ });
519
522
  }, _GatorPermissionsController_addPendingRevocationToState = function _GatorPermissionsController_addPendingRevocationToState(txId, permissionContext) {
520
523
  this.update((state) => {
521
524
  state.pendingRevocations = [
@@ -534,24 +537,74 @@ _GatorPermissionsController_supportedPermissionTypes = new WeakMap(), _GatorPerm
534
537
  });
535
538
  }, _GatorPermissionsController_registerMessageHandlers = function _GatorPermissionsController_registerMessageHandlers() {
536
539
  this.messenger.registerActionHandler(`${controllerName}:fetchAndUpdateGatorPermissions`, this.fetchAndUpdateGatorPermissions.bind(this));
540
+ this.messenger.registerActionHandler(`${controllerName}:enableGatorPermissions`, this.enableGatorPermissions.bind(this));
541
+ this.messenger.registerActionHandler(`${controllerName}:disableGatorPermissions`, this.disableGatorPermissions.bind(this));
537
542
  this.messenger.registerActionHandler(`${controllerName}:decodePermissionFromPermissionContextForOrigin`, this.decodePermissionFromPermissionContextForOrigin.bind(this));
538
543
  const submitRevocationAction = `${controllerName}:submitRevocation`;
539
544
  this.messenger.registerActionHandler(submitRevocationAction, this.submitRevocation.bind(this));
540
545
  this.messenger.registerActionHandler(`${controllerName}:addPendingRevocation`, this.addPendingRevocation.bind(this));
541
546
  this.messenger.registerActionHandler(`${controllerName}:submitDirectRevocation`, this.submitDirectRevocation.bind(this));
542
547
  this.messenger.registerActionHandler(`${controllerName}:isPendingRevocation`, this.isPendingRevocation.bind(this));
543
- }, _GatorPermissionsController_storedPermissionToPermissionInfo = function _GatorPermissionsController_storedPermissionToPermissionInfo(storedGatorPermission) {
544
- const { permissionResponse: fullPermissionResponse } = storedGatorPermission;
545
- const { dependencies: _dependencies, to: _to, ...permissionResponse } = fullPermissionResponse;
548
+ }, _GatorPermissionsController_assertGatorPermissionsEnabled = function _GatorPermissionsController_assertGatorPermissionsEnabled() {
549
+ if (!this.state.isGatorPermissionsEnabled) {
550
+ throw new errors_1.GatorPermissionsNotEnabledError();
551
+ }
552
+ }, _GatorPermissionsController_handleSnapRequestToGatorPermissionsProvider =
553
+ /**
554
+ * Forwards a Snap request to the SnapController.
555
+ *
556
+ * @param args - The request parameters.
557
+ * @param args.snapId - The ID of the Snap of the gator permissions provider snap.
558
+ * @param args.params - Optional parameters to pass to the snap method.
559
+ * @returns A promise that resolves with the gator permissions.
560
+ */
561
+ async function _GatorPermissionsController_handleSnapRequestToGatorPermissionsProvider({ snapId, params, }) {
562
+ try {
563
+ const response = (await this.messenger.call('SnapController:handleRequest', {
564
+ snapId,
565
+ origin: 'metamask',
566
+ handler: snaps_utils_1.HandlerType.OnRpcRequest,
567
+ request: {
568
+ jsonrpc: '2.0',
569
+ method: types_1.GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,
570
+ ...(params !== undefined && { params }),
571
+ },
572
+ }));
573
+ return response;
574
+ }
575
+ catch (error) {
576
+ (0, logger_1.controllerLog)('Failed to handle snap request to gator permissions provider', error);
577
+ throw new errors_1.GatorPermissionsProviderError({
578
+ method: types_1.GatorPermissionsSnapRpcMethod.PermissionProviderGetGrantedPermissions,
579
+ cause: error,
580
+ });
581
+ }
582
+ }, _GatorPermissionsController_sanitizeStoredGatorPermission = function _GatorPermissionsController_sanitizeStoredGatorPermission(storedGatorPermission) {
583
+ const { permissionResponse } = storedGatorPermission;
584
+ const { dependencies, to, ...rest } = permissionResponse;
546
585
  return {
547
586
  ...storedGatorPermission,
548
- permissionResponse,
587
+ permissionResponse: {
588
+ ...rest,
589
+ },
549
590
  };
550
- }, _GatorPermissionsController_storedPermissionsToPermissionInfoWithMetadata = function _GatorPermissionsController_storedPermissionsToPermissionInfoWithMetadata(storedGatorPermissions) {
591
+ }, _GatorPermissionsController_categorizePermissionsDataByTypeAndChainId = function _GatorPermissionsController_categorizePermissionsDataByTypeAndChainId(storedGatorPermissions) {
592
+ const gatorPermissionsMap = createEmptyGatorPermissionsMap();
551
593
  if (!storedGatorPermissions) {
552
- return [];
594
+ return gatorPermissionsMap;
595
+ }
596
+ for (const storedGatorPermission of storedGatorPermissions) {
597
+ const { permissionResponse: { permission: { type: permissionType }, chainId, }, } = storedGatorPermission;
598
+ const isPermissionTypeKnown = Object.prototype.hasOwnProperty.call(gatorPermissionsMap, permissionType);
599
+ const permissionTypeKey = isPermissionTypeKnown
600
+ ? permissionType
601
+ : 'other';
602
+ gatorPermissionsMap[permissionTypeKey][chainId] = [
603
+ ...(gatorPermissionsMap[permissionTypeKey][chainId] || []),
604
+ __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_sanitizeStoredGatorPermission).call(this, storedGatorPermission),
605
+ ];
553
606
  }
554
- return storedGatorPermissions.map((storedPermission) => __classPrivateFieldGet(this, _GatorPermissionsController_instances, "m", _GatorPermissionsController_storedPermissionToPermissionInfo).call(this, storedPermission));
607
+ return gatorPermissionsMap;
555
608
  };
556
609
  exports.default = GatorPermissionsController;
557
610
  //# sourceMappingURL=GatorPermissionsController.cjs.map