Skip to content

feat: add gator permissions controller#6033

Merged
V00D00-child merged 32 commits into
mainfrom
feat/add-gator-permissions-controller
Aug 20, 2025
Merged

feat: add gator permissions controller#6033
V00D00-child merged 32 commits into
mainfrom
feat/add-gator-permissions-controller

Conversation

@V00D00-child

@V00D00-child V00D00-child commented Jun 25, 2025

Copy link
Copy Markdown
Member

Explanation

@metamask/gator-permissions-controller

Current State and Why Change is Needed

MetaMask clients currently lack a dedicated system for managing gator permissions that are stored to profile sync via the @metamask/gator-permissions-snap.

Solution and How It Works

This change introduces a new @metamask/gator-permissions-controller package that provides a comprehensive solution for managing gator permissions in MetaMask clients with gator-snap integration.

Changes That Might Not Be Obvious

  • Serialization Strategy: The controller state uses JSON serialization for storing permission data fetched from @metamask/gator-permissions-snap, which allows for efficient storage and retrieval while maintaining data integrity. The deserialize permission data is represented as a list of gator permissions filtered by permission type and chainId.
  • Default Permission Structure: The controller initializes with an empty structure for all three permission types, ensuring consistent state even when no permissions are configured

Package Dependencies and Integration

The new package depends on @metamask/snaps-controllers as a peer dependency, ensuring it can leverage sending RPC requests to an installed Metamask Snap. This integration allows the GatorPermissionsController to forward requests to @metamask/gator-permissions-snap to fetch users' Gator permissions that have been stored in the MetaMask Profile Sync service.

The @metamask/gator-permissions-snap will take on the responsibility of authenticating with MetaMask Profile Sync service using anSRP identifier via integration with @metamask/message-signing-snap.

No Dependency Upgrades Required

This is a new package that introduces new functionality without requiring changes to existing dependencies. The package uses the current stable versions of @metamask/base-controller, @metamask/utils ,@metamask/snaps-sdk, and @metamask/snaps-utils following the established patterns in the MetaMask codebase.

References

Related to(MM snap-7715-permissions): Persisting Granted Permissions with MM Profile Sync
Requires(MM snap-7715-permissions):Add new permissionsProvider_getGrantedPermissions RPC
Required by(MM Extension): MetaMask/metamask-extension#33996

Gator Permissions Data Flow

graph TD
    %% dApp flow for storing permissions
    A[dApp<br/>client side RPC] -->|RPC| GPS[gator-permissions-snap]
    C -->|WRITE| D[(permissions stored<br/>across all sites)]
    
    %% User flow for reading permissions
    E[user<br/>permissions page] -->|UI| F[MM client]
    F -->|submitRequestToBackground| G[GatorPermissionsController]
    G --> MSYS[messagingSystem]
    MSYS -->|handleRequest| SC[SnapController]
    SC -->|RPC| GPS
    C -->|READ| D

    %% SRP Auth
    GPS -->|OAuth 2.0 Auth| MS[message-signing-snap]
    MS -->|SRP identifier & signature| C[profile sync service]
    
    %% Styling
    classDef dappStyle fill:#e1f5fe,stroke:#01579b,stroke-width:2px
    classDef userStyle fill:#f3e5f5,stroke:#4a148c,stroke-width:2px
    classDef serviceStyle fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px
    classDef dataStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef authStyle fill:#ffebee,stroke:#c62828,stroke-width:2px
    classDef systemStyle fill:#fce4ec,stroke:#ad1457,stroke-width:2px
    
    class A dappStyle
    class E,F userStyle
    class GPS,C serviceStyle
    class D dataStyle
    class MS authStyle
    class G,MSYS,SC systemStyle
Loading

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed, highlighting breaking changes as necessary
  • I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes

@jeffsmale90 jeffsmale90 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a high level glance through and this looks good 👍

Just one question regarding the long-term scope of this controller.

@V00D00-child V00D00-child changed the title Add GatorPermissionsController package feat: add gator permissions controller Jun 26, 2025
@V00D00-child V00D00-child added the team-delegation MetaMask Delegation Team label Jun 26, 2025
@V00D00-child V00D00-child force-pushed the feat/add-gator-permissions-controller branch from cbf1238 to 22ab42d Compare June 30, 2025 15:56
@V00D00-child V00D00-child marked this pull request as ready for review June 30, 2025 16:23
@V00D00-child V00D00-child requested review from a team as code owners June 30, 2025 16:23
@V00D00-child V00D00-child requested a review from jeffsmale90 June 30, 2025 16:24
cursor[bot]

This comment was marked as outdated.

mathieuartu
mathieuartu previously approved these changes Jul 4, 2025

@mathieuartu mathieuartu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Owned files LGTM! Nice usage of our controllers, I'm very happy to see this.

cursor[bot]

This comment was marked as outdated.

@V00D00-child V00D00-child moved this from Needs more work from the author to Needs dev review in PR review queue Aug 12, 2025
>[]
).push(sanitizedStoredGatorPermission);
break;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Type Safety Violation in Permission Categorization

The #categorizePermissionsDataByTypeAndChainId method contains a type safety violation. It pushes StoredGatorPermissionSanitized (which is generic over a union of PermissionTypes) into GatorPermissionsMap arrays that are typed for specific permission types. Type assertions mask this mismatch, allowing incorrect specific types (including unhandled types in the default case) to be stored, potentially leading to runtime type errors or data corruption.

Fix in Cursor Fix in Web

jeffsmale90
jeffsmale90 previously approved these changes Aug 13, 2025

@jeffsmale90 jeffsmale90 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - a couple nits, mostly about naming and data safety, that maybe we should address, but I'm happy to defer those to separate tickets to keep this moving.

* @param args.snapId - The ID of the Snap of the gator permissions provider snap.
* @returns A promise that resolves with the gator permissions.
*/
async #handleSnapRequestToGatorPermissionsProvider({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this could be better named to describe the action that it's performing rather than how it's performing that action.

ie. fetchStoredPermissions or fetchStoredPermissionsFromSnap

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with the corresponding error message.

* @param storedGatorPermission - The stored gator permission to sanitize.
* @returns The sanitized stored gator permission.
*/
#sanitizeStoredGatorPermission(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I don't think sanitize is the best term here, as it implies that the data has had any potentially malicious or dangerous content stripped out. Both for the function name and the return type.

Because we are fetching data from an external service (profile sync) and displaying it, maybe we do want to actually sanitize it though (and type check it, to ensure that invalid data is unable to crash the wallet), to ensure that nothing malicious has been injected.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I wanted to add some type checks here after removing the fields we do not want exposed to MetaMask client, but I wanted to defer that to a subsequent PR.

@V00D00-child V00D00-child enabled auto-merge (squash) August 13, 2025 14:53
@V00D00-child V00D00-child moved this from Needs dev review to Has approvals, needs CODEOWNER in PR review queue Aug 13, 2025
V00D00-child added a commit to MetaMask/metamask-extension that referenced this pull request Aug 14, 2025
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/34373?quickstart=1)

Submit transactions to revoke gator permissions. Support single and
batch revokes.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Adds a button for the user to revoke a gator
permission.

## **Related issues**

requires: #33996
requires: MetaMask/core#6033
requires: MetaMask/snap-7715-permissions#108
relates to: MetaMask/snap-7715-permissions#84

## **Manual testing steps**

1. Generate a MM Flask build - `yarn dist --build-type flask
--apply-lavamoat false`
2. Install the latest development version of
`@metamask/permissions-kernel-snap` and
`@metamask/gator-permissions-snap`.
3. Make a permission 7715 request to store a permission in profile sync.
4. Go to the "All Permissions page".
5. Click revoke to trigger a transaction to revoke a permission.
6. Sign the transaction.

- Evidence of revoke permission transaction on testnet:
https://sepolia.etherscan.io/tx/0x157ae09d68e0b922876f131648657fd780194625ff2d3825021a8293f6f16dd5

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed some inconsistencies with how we write controllers. I have left some comments but need to hop into a meeting, I will continue this a bit later.

In general I would advise taking a look at the guidelines we have around writing controllers and make sure you are following them. This will help us keep a consistent codebase and make it easier to maintain this code going forward: https://github.com/MetaMask/core/blob/e4feac813b058a5b280df1755284950f777a6571/docs/controller-guidelines.md. EDIT: There is also a sample-controllers package that provides some guidance as well. https://github.com/MetaMask/core/blob/e4feac813b058a5b280df1755284950f777a6571/packages/sample-controllers/

Comment thread packages/gator-permissions-controller/src/GatorPermissionContoller.test.ts Outdated
Comment thread packages/gator-permissions-controller/src/GatorPermissionContoller.test.ts Outdated
Comment thread packages/gator-permissions-controller/src/GatorPermissionsController.ts Outdated
@github-project-automation github-project-automation Bot moved this from Has approvals, needs CODEOWNER to Needs more work from the author in PR review queue Aug 14, 2025

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished review! Overall this looks good, mostly minor inconsistencies. It would be good if we could confirm whether snaps-controllers can be removed as a peer dependency though as that would make this package easier to release in the future (fewer things to keep track of).

Comment thread packages/gator-permissions-controller/src/GatorPermissionsController.ts Outdated
Comment thread packages/gator-permissions-controller/src/GatorPermissionsController.ts Outdated
Comment thread packages/gator-permissions-controller/src/GatorPermissionsController.ts Outdated
Comment thread packages/gator-permissions-controller/src/GatorPermissionsController.ts Outdated
Comment thread packages/gator-permissions-controller/src/index.ts Outdated
Comment thread packages/gator-permissions-controller/src/index.ts Outdated
Comment thread packages/gator-permissions-controller/package.json Outdated

@mcmire mcmire left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small thing but it is non-blocking, up to you.

public async fetchAndUpdateGatorPermissions(): Promise<GatorPermissionsMap> {
try {
this.#setIsFetchingGatorPermissions(true);
this.#assertGatorPermissionsEnabled();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be called first so that if permissions aren't enabled, no state updates occur?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is fine since it is an attempt to update the and will fail if permissions aren't enabled. The entire statement is wrapped in a try, catch, and finally block, with this.#setIsFetchingGatorPermissions(false) in the finally block. Keeping this.#setIsFetchingGatorPermissions(true) try block ensures we open and close the circuit even if that results in the happy path or error path.

@jeffsmale90 jeffsmale90 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One comment regarding explicit configuration, but looks good!

defaultGatorPermissionsMap,
),
isFetchingGatorPermissions: false,
gatorPermissionsProviderSnapId: defaultGatorPermissionsProviderSnapId,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I’d avoid specifying a default snapId and require callers to pass the config explicitly when constructing the controller. Forcing the parent to specify the snapId keeps environment-specific code paths aligned, is more resilient, and makes switching between environments simpler.

Specifically, if the consumer isn't built in such a way that it passes a snapId, there’s no way to target a locally running snap.

In metamask-extension#35193 we introduce the PERMISSIONS_KERNEL_SNAP_ID env var to choose the snap that wallet_requestExecutionPermissions forwards to, which makes local development trivial because you can point directly at a local snap.

I get that this isn’t the extension repo, but if we require explicit configuration here, it'll bring those devex improvements in the extension repo.

@github-project-automation github-project-automation Bot moved this from Needs more work from the author to Review finalised - Ready to be merged in PR review queue Aug 20, 2025
@V00D00-child V00D00-child merged commit 420b2e3 into main Aug 20, 2025
238 of 241 checks passed
@V00D00-child V00D00-child deleted the feat/add-gator-permissions-controller branch August 20, 2025 16:19
@github-project-automation github-project-automation Bot moved this from Review finalised - Ready to be merged to Merged, Closed or Archived in PR review queue Aug 20, 2025
github-merge-queue Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Sep 3, 2025
## **Description**

Add a new build feature flag `GATOR_PERMISSIONS_ENABLED` that defaults
to false. It is intended to serve as a feature flag for the development
of the gator-permission page.

- When `GATOR_PERMISSIONS_ENABLED=true`, the `/permissions` path will
route to the `GatorPermissionsPage` component.
- When `GATOR_PERMISSIONS_ENABLED=false` or empty, the `/permissions`
path will continue to route to the `PermissionsPage` component.

## **Changelog**

CHANGELOG entry: This PR is not End-User-Facing, and it is intended to
serve as a feature flag for the development of the gator-permission
page.

## **Related issues**

relates to: MetaMask/core#6033
required by: #35219
relates to: MetaMask/snap-7715-permissions#84

## **Manual testing steps**

1. Set `GATOR_PERMISSIONS_ENABLED=true` in `.metamaskrc`
2.  Build Flask: `yarn dist --build-type flask --apply-lavamoat false `
3. Navigate to the `All Permissions page`
4. A Blank page will show as a placeholder to the Gator permission
management UI(ie, permission revocation flow).

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
github-merge-queue Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Sep 11, 2025
## **Description**

This PR adds
[@metamask/gator-permissions-controller](https://github.com/MetaMask/core/tree/main/packages/gator-permissions-controller)
package into extension:

- `@metamask/gator-permissions-controller`: a controller to handle
managing gator permissions in MetaMask clients with
[@metamask/gator-permissions-snap](https://github.com/MetaMask/snap-7715-permissions/tree/main/packages/gator-permissions-snap)
integration.

It also creates background actions to allow the UI to submit requests to
the background to invoke actions exposed on
`@metamask/gator-permissions-controller`:
- `fetchAndUpdateGatorPermissions`

### **Note - local snap for development**

The `GatorPermissionsControllerInit` is configured to use a local
running instance of the gator-snap for non-production environments to
support development in future PRs.

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/35627?quickstart=1)

## **Related issues**

Requires: MetaMask/core#6467
Relates to(MM Core): MetaMask/core#6033
Relates to: #35307
Required by: #35219
## **Manual testing steps**

There is no need for testing, since we are integrating dependencies to
support future PRs.

### **Before**

### **After**

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---------

Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com>
Co-authored-by: jeffsmale90 <6363749+jeffsmale90@users.noreply.github.com>
github-merge-queue Bot pushed a commit to MetaMask/metamask-extension that referenced this pull request Sep 29, 2025
## **Description**

This PR lays the foundation for the gator permissions revocation
feature. Introduces the following:
- The usage of the `GatorPemissionsController` to fetch gator
permissions that have been granted to sites.
- A dedicated selector that filters `GatorPemissionsController` state to
provide necessary data allowing components to render gator permissions
revocation features.
- Introduces the `GATOR_PERMISSIONS_REVOCATION_ENABLED` feature flag
that is set to `false`. This flag is used to continue building the gator
permissions view without impacting end-users.
- All UI changes are behind the `GATOR_PERMISSIONS_REVOCATION_ENABLED`
feature flag.
- Dynamic routing based on `GATOR_PERMISSIONS_REVOCATION_ENABLED`
feature flag.
    - 'All permissions' click on the global menu.
    - 'Back button' click on the site connection page.
- Targeting flask build - Once the feature is complete, it will target a
MM Flash realease
- Placeholder for gator `TokenTransferPage` to be implemented fully
#36207

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/35219?quickstart=1)

## **Related issues**

requires: MetaMask/core#6033
requires: #35627
requires: MetaMask/snap-7715-permissions#108
requires: #35307
relates to: MetaMask/snap-7715-permissions#84
required by: #36207

## **Manual testing steps**

### Setting up required MM snaps(Installing snaps):
Local version of kernel-snap, gator-snap, and the message-signing-snap
from [snap-7715-permissions mono
repo](https://github.com/MetaMask/snap-7715-permissions) is required to
be running locally to fully test e2e manually. Follow the steps in the
README.md to get those snaps up and running. The development site at
`http://localhost:8000/` will be used to install the snaps and grant
some gator permissions.

- repo: [snap-7715-permissions mono
repo](https://github.com/MetaMask/snap-7715-permissions)
- branch: `dev`
- commit hash: `520fffde76c98701e9bac9eb080695e673b7736e`

### Testing e2e flow
1. Ensure `snap-7715-permissions mono` development server is up and
running
2. In MM extension `.metamaskrc` file, ensure the following env values
are set:
```bash
GATOR_PERMISSIONS_ENABLED=true
GATOR_PERMISSIONS_REVOCATION_ENABLED=true
PERMISSIONS_KERNEL_SNAP_ID='local:http://localhost:8081'
GATOR_PERMISSIONS_PROVIDER_SNAP_ID='local:http://localhost:8082'
```
4. Run `yarn start:flask`
5. Once MM extension is installed, navigate to the snaps development
site at `http://localhost:8000/`
   - Install kernel-snap
   - Install gator-snap
6. Go to "All Permissions Page" in MM extension

## **Screenshots/Recordings**

### **Installing snaps**


https://github.com/user-attachments/assets/b21a7827-d4d2-4b72-bfa9-ea7ff9a08bd4

### **Before**


https://github.com/user-attachments/assets/f3b4d4fe-8cad-4c48-a314-a65a8fd2dc14

### **After**


https://github.com/user-attachments/assets/490e03d4-54db-48e5-b4b2-f9b16d1d257a

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds gated Gator Permissions revocation flow: new
routes/pages/components, selectors and hook, global menu/nav updates,
env flag, locales, and comprehensive tests.
> 
> - **Feature flag & config**
> - Add `GATOR_PERMISSIONS_REVOCATION_ENABLED` env (builds.yml) and
`isGatorPermissionsRevocationFeatureEnabled()` with tests.
> - **Routing & navigation**
> - Add routes: `GATOR_PERMISSIONS`, `TOKEN_TRANSFER_ROUTE`; register in
router and analytics map.
> - Update Global Menu “Connected sites” link to route to
`GATOR_PERMISSIONS` when flag is on.
> - Permissions page back button and title vary based on flag; header
visibility utils updated for new routes.
> - **UI**
> - New pages: `GatorPermissionsPage`, `TokenTransferPage` (scaffolded),
and `PermissionListItem` component.
> - Gator Permissions page lists Sites and Token transfer categories
(loading/empty states included).
> - **Data layer**
> - New selectors in `ui/selectors/gator-permissions` to
deserialize/aggregate permissions.
>   - New hook `useGatorPermissions` to fetch/update permissions state.
> - **Tests**
> - Unit tests for env flag, selectors, hook; snapshots for new
pages/components.
> - E2E: permissions navigation and back behavior; global menu link
target.
> - **Locales**
>   - Add strings for `sites` and `tokenTransfer` in `en` and `en_GB`.
> - **Fixtures**
> - Extend mock state with gator permissions fields and serialized map.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ddf1657. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Tadej Vengust <tadej.vengust@consensys.net>
NidhiKJha pushed a commit to MetaMask/metamask-extension that referenced this pull request Oct 9, 2025
## **Description**

This PR lays the foundation for the gator permissions revocation
feature. Introduces the following:
- The usage of the `GatorPemissionsController` to fetch gator
permissions that have been granted to sites.
- A dedicated selector that filters `GatorPemissionsController` state to
provide necessary data allowing components to render gator permissions
revocation features.
- Introduces the `GATOR_PERMISSIONS_REVOCATION_ENABLED` feature flag
that is set to `false`. This flag is used to continue building the gator
permissions view without impacting end-users.
- All UI changes are behind the `GATOR_PERMISSIONS_REVOCATION_ENABLED`
feature flag.
- Dynamic routing based on `GATOR_PERMISSIONS_REVOCATION_ENABLED`
feature flag.
    - 'All permissions' click on the global menu.
    - 'Back button' click on the site connection page.
- Targeting flask build - Once the feature is complete, it will target a
MM Flash realease
- Placeholder for gator `TokenTransferPage` to be implemented fully
#36207

[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/35219?quickstart=1)

## **Related issues**

requires: MetaMask/core#6033
requires: #35627
requires: MetaMask/snap-7715-permissions#108
requires: #35307
relates to: MetaMask/snap-7715-permissions#84
required by: #36207

## **Manual testing steps**

### Setting up required MM snaps(Installing snaps):
Local version of kernel-snap, gator-snap, and the message-signing-snap
from [snap-7715-permissions mono
repo](https://github.com/MetaMask/snap-7715-permissions) is required to
be running locally to fully test e2e manually. Follow the steps in the
README.md to get those snaps up and running. The development site at
`http://localhost:8000/` will be used to install the snaps and grant
some gator permissions.

- repo: [snap-7715-permissions mono
repo](https://github.com/MetaMask/snap-7715-permissions)
- branch: `dev`
- commit hash: `520fffde76c98701e9bac9eb080695e673b7736e`

### Testing e2e flow
1. Ensure `snap-7715-permissions mono` development server is up and
running
2. In MM extension `.metamaskrc` file, ensure the following env values
are set:
```bash
GATOR_PERMISSIONS_ENABLED=true
GATOR_PERMISSIONS_REVOCATION_ENABLED=true
PERMISSIONS_KERNEL_SNAP_ID='local:http://localhost:8081'
GATOR_PERMISSIONS_PROVIDER_SNAP_ID='local:http://localhost:8082'
```
4. Run `yarn start:flask`
5. Once MM extension is installed, navigate to the snaps development
site at `http://localhost:8000/`
   - Install kernel-snap
   - Install gator-snap
6. Go to "All Permissions Page" in MM extension

## **Screenshots/Recordings**

### **Installing snaps**


https://github.com/user-attachments/assets/b21a7827-d4d2-4b72-bfa9-ea7ff9a08bd4

### **Before**


https://github.com/user-attachments/assets/f3b4d4fe-8cad-4c48-a314-a65a8fd2dc14

### **After**


https://github.com/user-attachments/assets/490e03d4-54db-48e5-b4b2-f9b16d1d257a

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds gated Gator Permissions revocation flow: new
routes/pages/components, selectors and hook, global menu/nav updates,
env flag, locales, and comprehensive tests.
> 
> - **Feature flag & config**
> - Add `GATOR_PERMISSIONS_REVOCATION_ENABLED` env (builds.yml) and
`isGatorPermissionsRevocationFeatureEnabled()` with tests.
> - **Routing & navigation**
> - Add routes: `GATOR_PERMISSIONS`, `TOKEN_TRANSFER_ROUTE`; register in
router and analytics map.
> - Update Global Menu “Connected sites” link to route to
`GATOR_PERMISSIONS` when flag is on.
> - Permissions page back button and title vary based on flag; header
visibility utils updated for new routes.
> - **UI**
> - New pages: `GatorPermissionsPage`, `TokenTransferPage` (scaffolded),
and `PermissionListItem` component.
> - Gator Permissions page lists Sites and Token transfer categories
(loading/empty states included).
> - **Data layer**
> - New selectors in `ui/selectors/gator-permissions` to
deserialize/aggregate permissions.
>   - New hook `useGatorPermissions` to fetch/update permissions state.
> - **Tests**
> - Unit tests for env flag, selectors, hook; snapshots for new
pages/components.
> - E2E: permissions navigation and back behavior; global menu link
target.
> - **Locales**
>   - Add strings for `sites` and `tokenTransfer` in `en` and `en_GB`.
> - **Fixtures**
> - Extend mock state with gator permissions fields and serialized map.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
ddf1657. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Tadej Vengust <tadej.vengust@consensys.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

team-delegation MetaMask Delegation Team

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

5 participants