From c4ef1679996db3426ca6eaa419d7a3663e4fb288 Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:27:37 -0500 Subject: [PATCH 1/8] Attach metadata when submitting a revocation to the permission provider snap --- .../src/GatorPermissionsController.test.ts | 68 +++++++++++++++++++ .../src/GatorPermissionsController.ts | 29 +++++++- .../gator-permissions-controller/src/types.ts | 13 ++++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts index a46ca7879c7..51f42ddb327 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts @@ -1235,6 +1235,74 @@ describe('GatorPermissionsController', () => { }); }); + it('should submit revocation metadata when transaction is confirmed', async () => { + const mockHandleRequestHandler = jest.fn().mockResolvedValue(undefined); + const rootMessenger = getRootMessenger({ + snapControllerHandleRequestActionHandler: mockHandleRequestHandler, + }); + const messenger = getMessenger(rootMessenger); + + const controller = new GatorPermissionsController({ + messenger, + state: { + isGatorPermissionsEnabled: true, + gatorPermissionsProviderSnapId: + MOCK_GATOR_PERMISSIONS_PROVIDER_SNAP_ID, + }, + }); + + const txId = 'test-tx-id'; + const permissionContext = '0x1234567890abcdef1234567890abcdef12345678'; + const hash = '0x-mock-hash'; + const blockTimestamp = '100000'; + + await controller.addPendingRevocation({ txId, permissionContext }); + + // Emit transaction approved event (user confirms) + rootMessenger.publish('TransactionController:transactionApproved', { + transactionMeta: { id: txId } as TransactionMeta, + }); + + // Emit transaction confirmed event + rootMessenger.publish('TransactionController:transactionConfirmed', { + id: txId, + hash, + blockTimestamp, + } as TransactionMeta); + + await flushPromises(); + + // Verify submitRevocation was called + expect(mockHandleRequestHandler).toHaveBeenCalledWith({ + snapId: MOCK_GATOR_PERMISSIONS_PROVIDER_SNAP_ID, + origin: 'metamask', + handler: 'onRpcRequest', + request: { + jsonrpc: '2.0', + method: 'permissionsProvider_submitRevocation', + params: { + permissionContext, + metadata: { + txHash: hash, + blockTimestamp, + }, + }, + }, + }); + + // Verify that permissions are refreshed after revocation (getGrantedPermissions is called) + expect(mockHandleRequestHandler).toHaveBeenCalledWith({ + snapId: MOCK_GATOR_PERMISSIONS_PROVIDER_SNAP_ID, + origin: 'metamask', + handler: 'onRpcRequest', + request: { + jsonrpc: '2.0', + method: 'permissionsProvider_getGrantedPermissions', + params: { isRevoked: false }, + }, + }); + }); + it('should cleanup without adding to state when transaction is rejected by user', async () => { const mockHandleRequestHandler = jest.fn().mockResolvedValue(undefined); const rootMessenger = getRootMessenger({ diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.ts index de0756c849d..18bd72e92a1 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.ts @@ -35,7 +35,10 @@ import { } from './errors'; import { controllerLog } from './logger'; import { GatorPermissionsSnapRpcMethod } from './types'; -import type { StoredGatorPermissionSanitized } from './types'; +import type { + RevocationMetadata, + StoredGatorPermissionSanitized, +} from './types'; import type { GatorPermissionsMap, PermissionTypesWithCustom, @@ -948,9 +951,31 @@ export default class GatorPermissionsController extends BaseController< controllerLog('Transaction confirmed, submitting revocation', { txId, permissionContext, + txHash: transactionMeta.hash, }); - this.submitRevocation({ permissionContext }) + // Attach metadata by parsing the confirmed transactionMeta + let metadata: RevocationMetadata | undefined; + const { hash, blockTimestamp } = transactionMeta; + if (hash === undefined || blockTimestamp === undefined) { + controllerLog( + 'Failed to attach transaction has after revocation transaction confirmed', + { + txId, + permissionContext, + error: new Error( + 'Confirmed transaction is missing revocation metadata', + ), + }, + ); + } else { + metadata = { + txHash: hash as Hex, + blockTimestamp, + }; + } + + this.submitRevocation({ permissionContext, metadata }) .catch((error) => { controllerLog( 'Failed to submit revocation after transaction confirmed', diff --git a/packages/gator-permissions-controller/src/types.ts b/packages/gator-permissions-controller/src/types.ts index b1f57419e26..5429126b91c 100644 --- a/packages/gator-permissions-controller/src/types.ts +++ b/packages/gator-permissions-controller/src/types.ts @@ -237,6 +237,14 @@ export type DelegationDetails = Pick< 'caveats' | 'delegator' | 'delegate' | 'authority' >; +/** + * Represents the metadata for confirmed transaction revocation. + */ +export type RevocationMetadata = { + txHash: Hex; + blockTimestamp: string; +}; + /** * Represents the parameters for submitting a revocation. */ @@ -245,6 +253,11 @@ export type RevocationParams = { * The permission context as a hex string that identifies the permission to revoke. */ permissionContext: Hex; + + /** + * The metadata associated with the permission revocation transaction. + */ + metadata?: RevocationMetadata; }; /** From 8df3ad640ab6ce69c3a2625ef901b8b35c25463b Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Wed, 17 Dec 2025 17:25:39 -0500 Subject: [PATCH 2/8] Update changelog --- packages/gator-permissions-controller/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/gator-permissions-controller/CHANGELOG.md b/packages/gator-permissions-controller/CHANGELOG.md index dcee094dd3a..f37c324d3ad 100644 --- a/packages/gator-permissions-controller/CHANGELOG.md +++ b/packages/gator-permissions-controller/CHANGELOG.md @@ -7,9 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Extends the `GatorPermissionsController` to enable attaching metadata(transaction hash, block timestamp) when submitting a permission revocation. [#7503](https://github.com/MetaMask/core/pull/7503) + ### Changed - Bump `@metamask/transaction-controller` from `^62.5.0` to `^62.7.0` ([#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) +- ## [0.8.0] From e06599250d28c83e8dce5db8428bde7f9599d198 Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Wed, 17 Dec 2025 17:30:36 -0500 Subject: [PATCH 3/8] Update changelog --- packages/gator-permissions-controller/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/gator-permissions-controller/CHANGELOG.md b/packages/gator-permissions-controller/CHANGELOG.md index f37c324d3ad..7d6430e0cb4 100644 --- a/packages/gator-permissions-controller/CHANGELOG.md +++ b/packages/gator-permissions-controller/CHANGELOG.md @@ -14,7 +14,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Bump `@metamask/transaction-controller` from `^62.5.0` to `^62.7.0` ([#7430](https://github.com/MetaMask/core/pull/7430), [#7494](https://github.com/MetaMask/core/pull/7494)) -- ## [0.8.0] From 970b7999a296ae381b22ac8677b9b73c08d44c4e Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Thu, 18 Dec 2025 10:32:17 -0500 Subject: [PATCH 4/8] bugfix: Undefined metadata sent in revocation params --- .../src/GatorPermissionsController.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.ts index 18bd72e92a1..3ddfe532758 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.ts @@ -975,7 +975,10 @@ export default class GatorPermissionsController extends BaseController< }; } - this.submitRevocation({ permissionContext, metadata }) + const revocationParams = metadata + ? { permissionContext, metadata } + : { permissionContext }; + this.submitRevocation(revocationParams) .catch((error) => { controllerLog( 'Failed to submit revocation after transaction confirmed', From 8b709c05b4378ab9303d957efde9b9a74d9d8838 Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:13:27 -0500 Subject: [PATCH 5/8] Update changelog --- packages/gator-permissions-controller/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gator-permissions-controller/CHANGELOG.md b/packages/gator-permissions-controller/CHANGELOG.md index 7d6430e0cb4..95a8d927fde 100644 --- a/packages/gator-permissions-controller/CHANGELOG.md +++ b/packages/gator-permissions-controller/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Extends the `GatorPermissionsController` to enable attaching metadata(transaction hash, block timestamp) when submitting a permission revocation. [#7503](https://github.com/MetaMask/core/pull/7503) +- Extends the `GatorPermissionsController` to enable attaching metadata(transaction hash, block timestamp) when submitting a permission revocation. ([#7503](https://github.com/MetaMask/core/pull/7503)) ### Changed From 85210a0575ec415b1fdae1fed0083eeea50d309f Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Fri, 19 Dec 2025 10:25:14 -0500 Subject: [PATCH 6/8] Update comment --- .../src/GatorPermissionsController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.ts index 3ddfe532758..6261f3249e8 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.ts @@ -959,7 +959,7 @@ export default class GatorPermissionsController extends BaseController< const { hash, blockTimestamp } = transactionMeta; if (hash === undefined || blockTimestamp === undefined) { controllerLog( - 'Failed to attach transaction has after revocation transaction confirmed', + 'Failed to attach transaction hash after revocation transaction confirmed', { txId, permissionContext, From 85570cfc1ada7fbe45482cdfcecfecd573740309 Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Fri, 19 Dec 2025 12:27:04 -0500 Subject: [PATCH 7/8] Drop block timestamp and change name from metadata to revocationMetadata --- .../src/GatorPermissionsController.test.ts | 5 +---- .../src/GatorPermissionsController.ts | 15 +++++++-------- .../gator-permissions-controller/src/types.ts | 3 +-- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts index 51f42ddb327..02e8ed02089 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.test.ts @@ -1254,7 +1254,6 @@ describe('GatorPermissionsController', () => { const txId = 'test-tx-id'; const permissionContext = '0x1234567890abcdef1234567890abcdef12345678'; const hash = '0x-mock-hash'; - const blockTimestamp = '100000'; await controller.addPendingRevocation({ txId, permissionContext }); @@ -1267,7 +1266,6 @@ describe('GatorPermissionsController', () => { rootMessenger.publish('TransactionController:transactionConfirmed', { id: txId, hash, - blockTimestamp, } as TransactionMeta); await flushPromises(); @@ -1282,9 +1280,8 @@ describe('GatorPermissionsController', () => { method: 'permissionsProvider_submitRevocation', params: { permissionContext, - metadata: { + revocationMetadata: { txHash: hash, - blockTimestamp, }, }, }, diff --git a/packages/gator-permissions-controller/src/GatorPermissionsController.ts b/packages/gator-permissions-controller/src/GatorPermissionsController.ts index 6261f3249e8..76a94f41e2f 100644 --- a/packages/gator-permissions-controller/src/GatorPermissionsController.ts +++ b/packages/gator-permissions-controller/src/GatorPermissionsController.ts @@ -955,28 +955,27 @@ export default class GatorPermissionsController extends BaseController< }); // Attach metadata by parsing the confirmed transactionMeta - let metadata: RevocationMetadata | undefined; - const { hash, blockTimestamp } = transactionMeta; - if (hash === undefined || blockTimestamp === undefined) { + let revocationMetadata: RevocationMetadata | undefined; + const { hash } = transactionMeta; + if (hash === undefined) { controllerLog( 'Failed to attach transaction hash after revocation transaction confirmed', { txId, permissionContext, error: new Error( - 'Confirmed transaction is missing revocation metadata', + 'Confirmed transaction is missing transaction hash', ), }, ); } else { - metadata = { + revocationMetadata = { txHash: hash as Hex, - blockTimestamp, }; } - const revocationParams = metadata - ? { permissionContext, metadata } + const revocationParams = revocationMetadata + ? { permissionContext, revocationMetadata } : { permissionContext }; this.submitRevocation(revocationParams) .catch((error) => { diff --git a/packages/gator-permissions-controller/src/types.ts b/packages/gator-permissions-controller/src/types.ts index 5429126b91c..5f527327c0a 100644 --- a/packages/gator-permissions-controller/src/types.ts +++ b/packages/gator-permissions-controller/src/types.ts @@ -242,7 +242,6 @@ export type DelegationDetails = Pick< */ export type RevocationMetadata = { txHash: Hex; - blockTimestamp: string; }; /** @@ -257,7 +256,7 @@ export type RevocationParams = { /** * The metadata associated with the permission revocation transaction. */ - metadata?: RevocationMetadata; + metadata: RevocationMetadata; }; /** From 378443a5bb37b94e480fe2ab2196ebd876da8b28 Mon Sep 17 00:00:00 2001 From: Idris Bowman <34751375+V00D00-child@users.noreply.github.com> Date: Fri, 19 Dec 2025 12:36:43 -0500 Subject: [PATCH 8/8] Change name from metadata to revocationMetadata in RevocationParams --- packages/gator-permissions-controller/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gator-permissions-controller/src/types.ts b/packages/gator-permissions-controller/src/types.ts index 5f527327c0a..f71f67cd033 100644 --- a/packages/gator-permissions-controller/src/types.ts +++ b/packages/gator-permissions-controller/src/types.ts @@ -256,7 +256,7 @@ export type RevocationParams = { /** * The metadata associated with the permission revocation transaction. */ - metadata: RevocationMetadata; + revocationMetadata?: RevocationMetadata; }; /**