Skip to content

Feat: disable revoke button while tx pending#37554

Closed
V00D00-child wants to merge 30 commits intomainfrom
feat/disable-revoke-button-while-tx-pending
Closed

Feat: disable revoke button while tx pending#37554
V00D00-child wants to merge 30 commits intomainfrom
feat/disable-revoke-button-while-tx-pending

Conversation

@V00D00-child
Copy link
Member

@V00D00-child V00D00-child commented Nov 5, 2025

Description

This PR extends the gatar permission revocation UI to dynamically determine if the revoke CTA should be disabled when a transaction to revoke said permission is pending.

  • Extends the gator permission selector file to read pendingRevocations from GatorPermissionsController
  • Extends the ReviewGatorPermissionItem component props to include pendingRevocations values
  • Extends the ReviewGatorPermissionItem logic to render button text and determine button disabled status dynamically

Related issues

Relates to: #37209
Requires: MetaMask/core#7055

Screenshots/Recordings

Before

before-revoke-disabled.mov

After

after-1.mov

Pre-merge author checklist

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.

Note

Disables the Gator permission "Revoke" button when a matching revocation transaction is pending, wiring state via a new selector and updating UI text and tests.

  • Gator Permissions UI:
    • ReviewGatorPermissionItem: accepts pendingRevocations, computes isPendingRevocation from permissionResponse.context, switches label between gatorPermissionsRevocationPending/gatorPermissionsRevoke, disables the Button, and replaces the clickable div with a proper Button.
    • ReviewGatorPermissionsPage: selects pendingRevocations via getPendingRevocations and passes to each ReviewGatorPermissionItem.
  • State/Selectors:
    • Add getPendingRevocations selector to expose metamask.pendingRevocations.
  • i18n:
    • Add gatorPermissionsRevocationPending and gatorPermissionsRevoke to app/_locales/en/messages.json and app/_locales/en_GB/messages.json.
  • Tests:
    • Update review-gator-permission-item tests and snapshots to pass pendingRevocations and reflect button changes.
    • Add tests for getPendingRevocations selector.

Written by Cursor Bugbot for commit d3bc4c0. This will update automatically on new commits. Configure here.

hanzel98 and others added 26 commits November 5, 2025 21:55
- @metamask/gator-permissios-controller
- @metamask/signature-controller
- @metamask/permissions-kernel-controller
- @metamask/shielf-controller
<!--
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/37540?quickstart=1)

## **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:

## **Related issues**

Fixes:

## **Manual testing steps**

1. Go to this page...
2.
3.

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] 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).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] 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]
> Replace generic RPC with dedicated `checkDelegationDisabled` flow,
wiring backend API and refactoring hook/tests to skip tx when delegation
already disabled.
> 
> - **Gator Permissions (backend)**:
> - Add `checkDelegationDisabled` API on `MetamaskController` to query
`disabledDelegations(bytes32)` via `eth_call` and decode result.
> - Expose `checkDelegationDisabled` in controller API; remove generic
`callRpc` exposure.
> - **UI Hook**:
> - `useRevokeGatorPermissions` now calls `checkDelegationDisabled`
before submitting a revoke tx; if already disabled, calls
`submitRevocation` and skips tx.
> - Update imports and mocks from `isDelegationDisabled` →
`checkDelegationDisabled`; adjust tests accordingly.
> - **Controller Actions**:
> - Add `checkDelegationDisabled` action delegating to background;
remove manual ABI encode/decode and generic RPC usage.
> - Introduce `FetchAndUpdateGatorPermissionsParams` with optional
`isRevoked`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
0b78869. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…rPermissions

When revoking an already-disabled permission, the hook returns null and setTransactionId(null?.id) sets transactionId to undefined. The useEffect hook now checks that transactionId is defined before attempting navigation to avoid calling navigateToId(undefined).
@metamaskbot metamaskbot added the team-delegation MetaMask Delegation Team label Nov 5, 2025
@github-actions github-actions bot added the size-M label Nov 5, 2025
@V00D00-child V00D00-child added the no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed label Nov 5, 2025
@metamaskbot
Copy link
Collaborator

✨ Files requiring CODEOWNER review ✨

👨‍🔧 @MetaMask/core-extension-ux (4 files, +121 -49)
  • 📁 ui/
    • 📁 components/
      • 📁 multichain/
        • 📁 pages/
          • 📁 gator-permissions/
            • 📁 components/
              • 📁 __snapshots__/
                • 📄 review-gator-permission-item.test.tsx.snap +65 -40
                • 📄 review-gator-permission-item.test.tsx +9 -0
                • 📄 review-gator-permission-item.tsx +44 -9
            • 📁 review-permissions/
              • 📄 review-gator-permissions-page.tsx +3 -0

@metamaskbot metamaskbot added the INVALID-PR-TEMPLATE PR's body doesn't match template label Nov 5, 2025
@V00D00-child V00D00-child marked this pull request as ready for review November 5, 2025 17:21
@V00D00-child V00D00-child requested a review from a team as a code owner November 5, 2025 17:21
@metamaskbot
Copy link
Collaborator

Builds ready [ca31da8]
UI Startup Metrics (1253 ± 97 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1253109417149713021403
load107694313858511211206
domContentLoaded107093813778411161201
domInteractive231595162063
firstPaint61690137443510681185
backgroundConnect23522231411239247
firstReactRender26186772943
getState2176192639
initialActions71427821
loadScripts841715112181887970
setupStore1162641219
numNetworkReqs1367719670
BrowserifyPower User HomeuiStartup21001856267031225972670
load1098959151419213461514
domContentLoaded1090955150719013391507
domInteractive321683235483
firstPaint794175148041210211480
backgroundConnect24823326711257267
firstReactRender30265163151
getState18016620211189202
initialActions52112611
loadScripts853717126418610781264
setupStore1493061330
numNetworkReqs1207525374245253
WebpackStandard HomeuiStartup88472616791209021158
load6365671437105629869
domContentLoaded6285601421102623857
domInteractive17126191643
firstPaint21963885194209604
backgroundConnect271187143159
firstReactRender32197693742
getState1263041318
initialActions41375511
loadScripts6255581411100620846
setupStore1363151422
numNetworkReqs1367419869
WebpackPower User HomeuiStartup12901130168216814011682
load65256683394789833
domContentLoaded63555681386758813
domInteractive261381203681
firstPaint34783772246608772
backgroundConnect53102046160204
firstReactRender26252912729
getState14410316020158160
initialActions31133413
loadScripts63055480282747802
setupStore106307930
numNetworkReqs1116922453165224
FirefoxBrowserifyStandard HomeuiStartup14781278195012015361687
load1257110315648913181419
domContentLoaded1257110215638913181419
domInteractive1203634960122280
firstPaint------
backgroundConnect43251332147110
firstReactRender26214952641
getState74183714
initialActions51759416
loadScripts1229108515338312891355
setupStore13567101327
numNetworkReqs1266415756
BrowserifyPower User HomeuiStartup26022226338332626783383
load14331213194422514701944
domContentLoaded14331212194422514701944
domInteractive220101604176307604
firstPaint------
backgroundConnect1323432898215328
firstReactRender453376125176
getState1349620929146209
initialActions923891538
loadScripts13881183188122614461881
setupStore36796245896
numNetworkReqs1286830378169303
WebpackStandard HomeuiStartup15561384226415315811951
load13221161165310313601543
domContentLoaded13211161165210413591543
domInteractive962832135100148
firstPaint------
backgroundConnect45211302348109
firstReactRender302276103166
getState84527715
initialActions7121723325
loadScripts1292114015709513391500
setupStore187160241275
numNetworkReqs1367417765
WebpackPower User HomeuiStartup25962311310327428963103
load15841370186316317501863
domContentLoaded15841370186216317501862
domInteractive20074514153411514
firstPaint------
backgroundConnect792918851135188
firstReactRender41315685056
getState1328419028152190
initialActions812061420
loadScripts15531352183115917151831
setupStore3371263538126
numNetworkReqs1336329681240296
📊 Page Load Benchmark Results

Current Commit: ca31da8 | Date: 11/5/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.06s (±78ms) 🟡 | historical mean value: 1.02s ⬆️ (historical data)
  • domContentLoaded-> current mean value: 743ms (±75ms) 🟢 | historical mean value: 710ms ⬆️ (historical data)
  • firstContentfulPaint-> current mean value: 79ms (±14ms) 🟢 | historical mean value: 76ms ⬆️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.06s 78ms 1.02s 1.38s 1.29s 1.38s
domContentLoaded 743ms 75ms 702ms 1.07s 965ms 1.07s
firstPaint 79ms 14ms 60ms 196ms 88ms 196ms
firstContentfulPaint 79ms 14ms 60ms 196ms 88ms 196ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms

@metamaskbot
Copy link
Collaborator

Builds ready [d445cfc]
UI Startup Metrics (1172 ± 94 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup117299516199412191327
load99385412467810391133
domContentLoaded98685212367710341116
domInteractive201479121847
firstPaint61773124339710021121
backgroundConnect19617224411199222
firstReactRender23174952436
getState20777112237
initialActions71588728
loadScripts798659103176846928
setupStore1052521113
numNetworkReqs1367619674
BrowserifyPower User HomeuiStartup19501773258427621552584
load1009898136216411241362
domContentLoaded1002891135316211171353
domInteractive271687193187
firstPaint72215013803909401380
backgroundConnect23822026513249265
firstReactRender29255262852
getState18016021617193216
initialActions62205620
loadScripts77666411191598941119
setupStore15949101349
numNetworkReqs1147324866198248
WebpackStandard HomeuiStartup84570715131198451098
load6165571255104598862
domContentLoaded6095531238100593848
domInteractive161172101439
firstPaint204541248227187776
backgroundConnect251188152762
firstReactRender30185793550
getState1153031216
initialActions3114259
loadScripts606551122898591837
setupStore1253051327
numNetworkReqs1367919871
WebpackPower User HomeuiStartup12751119181621014671816
load653565955122778955
domContentLoaded636554912108740912
domInteractive231370183870
firstPaint28362915271561915
backgroundConnect56918567134185
firstReactRender26232712727
getState14210316721155167
initialActions21174217
loadScripts631552901105730901
setupStore2061794110179
numNetworkReqs1106623049167230
FirefoxBrowserifyStandard HomeuiStartup14851266189112515641717
load1258108214639213211439
domContentLoaded1258108214639213201438
domInteractive1163730548127233
firstPaint------
backgroundConnect4720416415190
firstReactRender26214842736
getState74193713
initialActions51759414
loadScripts1232106614268812951407
setupStore1273451326
numNetworkReqs1266215757
BrowserifyPower User HomeuiStartup25522144342940028983429
load14381148215628816722156
domContentLoaded14371148215528816722155
domInteractive218109635169304635
firstPaint------
backgroundConnect14530591144243591
firstReactRender433089145089
getState13910730344138303
initialActions9154141054
loadScripts13761130195224916451952
setupStore25683242883
numNetworkReqs1337030380199303
WebpackStandard HomeuiStartup16991514219815417192084
load14361267177810214811653
domContentLoaded14351266177810214811652
domInteractive1093438350121182
firstPaint------
backgroundConnect55281462759122
firstReactRender32257893444
getState11420021820
initialActions62729425
loadScripts1398124816929614531604
setupStore208241291574
numNetworkReqs1367117765
WebpackPower User HomeuiStartup26522360365238928713652
load15861374193616116771936
domContentLoaded15851374193616116771936
domInteractive19863560154334560
firstPaint------
backgroundConnect873322957125229
firstReactRender51311743850174
getState1277521733143217
initialActions511241012
loadScripts15501345188515216331885
setupStore3081293555129
numNetworkReqs1326430693247306
📊 Page Load Benchmark Results

Current Commit: d445cfc | Date: 11/5/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 971ms (±50ms) 🟢 | historical mean value: 1.02s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 676ms (±48ms) 🟢 | historical mean value: 710ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 74ms (±12ms) 🟢 | historical mean value: 76ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 971ms 50ms 943ms 1.25s 1.00s 1.25s
domContentLoaded 676ms 48ms 652ms 939ms 701ms 939ms
firstPaint 74ms 12ms 60ms 180ms 84ms 180ms
firstContentfulPaint 74ms 12ms 60ms 180ms 84ms 180ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms

@metamaskbot
Copy link
Collaborator

Builds ready [d3bc4c0]
UI Startup Metrics (1175 ± 89 ms)
PlatformBuildTypePageMetricMean (ms)Min (ms)Max (ms)Std Dev (ms)P 75 (ms)P 95 (ms)
ChromeBrowserifyStandard HomeuiStartup1175101614378912281328
load101087311927710601138
domContentLoaded100386811857610531121
domInteractive211480121846
firstPaint683122115538410251117
backgroundConnect1981812339202217
firstReactRender25175683041
getState2076092340
initialActions61366623
loadScripts81267398274857930
setupStore1062731215
numNetworkReqs1367620674
BrowserifyPower User HomeuiStartup20201795277132024002771
load1043910145319112951453
domContentLoaded1036904143318912891433
domInteractive321681205281
firstPaint54014512983639331298
backgroundConnect23422326011240260
firstReactRender30255983159
getState18116222517195225
initialActions71368636
loadScripts811676119218710711192
setupStore1693092830
numNetworkReqs1177225167168251
WebpackStandard HomeuiStartup8277001109788361069
load60355689567601788
domContentLoaded59655086463595774
domInteractive16124581538
firstPaint17758835162177593
backgroundConnect251169142664
firstReactRender291897103336
getState1163141216
initialActions3114249
loadScripts59354885461592763
setupStore1153051224
numNetworkReqs1367519871
WebpackPower User HomeuiStartup11931058157416513261574
load59152785096667850
domContentLoaded57251081385625813
domInteractive191246103346
firstPaint29063729236527729
backgroundConnect691122277183222
firstReactRender26232812728
getState1328816124147161
initialActions21164316
loadScripts56950780683617806
setupStore85214821
numNetworkReqs1116822549165225
FirefoxBrowserifyStandard HomeuiStartup14731307208412715241729
load1246111815348413011402
domContentLoaded1245111815348413011402
domInteractive1113633848116216
firstPaint------
backgroundConnect4226112165187
firstReactRender26225142729
getState84597719
initialActions41243413
loadScripts1220109514508112811383
setupStore147147161231
numNetworkReqs1267516760
BrowserifyPower User HomeuiStartup25862206416652328664166
load14291195192525217281925
domContentLoaded14291195192525217281925
domInteractive22687591180432591
firstPaint------
backgroundConnect12332544129191544
firstReactRender433260115760
getState1373820436164204
initialActions611441014
loadScripts13971148189525016791895
setupStore3562245136224
numNetworkReqs1337031377205313
WebpackStandard HomeuiStartup18321536321230718832462
load15731259279326816322229
domContentLoaded15721258279226816312228
domInteractive1203850964132254
firstPaint------
backgroundConnect53261612757130
firstReactRender3423137183380
getState84375815
initialActions51467426
loadScripts15391241276326615862191
setupStore197264301475
numNetworkReqs1367017764
WebpackPower User HomeuiStartup26732267370138529903701
load16061373192916017441929
domContentLoaded16061373192816017441928
domInteractive17675501122282501
firstPaint------
backgroundConnect983625372155253
firstReactRender40315695056
getState16011322340205223
initialActions816315963
loadScripts15611351185214616691852
setupStore27793253693
numNetworkReqs1216030179138301
📊 Page Load Benchmark Results

Current Commit: d3bc4c0 | Date: 11/5/2025

📄 Localhost MetaMask Test Dapp

Samples: 100

Summary

  • pageLoadTime-> current mean value: 1.02s (±37ms) 🟡 | historical mean value: 1.02s ⬇️ (historical data)
  • domContentLoaded-> current mean value: 710ms (±34ms) 🟢 | historical mean value: 713ms ⬇️ (historical data)
  • firstContentfulPaint-> current mean value: 74ms (±12ms) 🟢 | historical mean value: 76ms ⬇️ (historical data)

📈 Detailed Results

Metric Mean Std Dev Min Max P95 P99
pageLoadTime 1.02s 37ms 1000ms 1.29s 1.05s 1.29s
domContentLoaded 710ms 34ms 693ms 966ms 725ms 966ms
firstPaint 74ms 12ms 60ms 172ms 84ms 172ms
firstContentfulPaint 74ms 12ms 60ms 172ms 84ms 172ms
largestContentfulPaint 0ms 0ms 0ms 0ms 0ms 0ms

Base automatically changed from feat/add-revocation-flow to main November 5, 2025 20:02
@V00D00-child V00D00-child requested review from a team as code owners November 5, 2025 20:02
@V00D00-child
Copy link
Member Author

Replaced with #37559

@github-actions github-actions bot locked and limited conversation to collaborators Nov 5, 2025
@V00D00-child V00D00-child deleted the feat/disable-revoke-button-while-tx-pending branch November 5, 2025 20:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

INVALID-PR-TEMPLATE PR's body doesn't match template no-changelog no-changelog Indicates no external facing user changes, therefore no changelog documentation needed size-M team-delegation MetaMask Delegation Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants