Skip to content

Commit b7c2567

Browse files
authored
refactor: decompose rule decoders, and refactor permission decoding (#8730)
## Explanation Refactor of permission decoding logic in order to: - clarify terminology (`decoders` rather than `rules` - rule is a highly overloaded term) - make rule (as in 7155 rules) more composable, rather than inherently part of the decoding process - prepare the permission decoders for potential decomposition into a separate package no functional change, therefore no changelog required <!-- Thanks for your contribution! Take a moment to answer these questions so that reviewers have the information they need to properly understand your changes: * What is the current state of things and why does it need to change? * What is the solution your changes offer and how does it work? * Are there any changes whose purpose might not obvious to those unfamiliar with the domain? * If your primary goal was to update one package but you found you had to update another one along the way, why did you do so? * If you had to upgrade a dependency, why did you do so? --> ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> ## 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](https://github.com/MetaMask/core/tree/main/docs/processes/updating-changelogs.md) - [ ] I've introduced [breaking changes](https://github.com/MetaMask/core/tree/main/docs/processes/breaking-changes.md) in this PR and have prepared draft pull requests for clients and consumer packages to resolve them <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Refactors the core permission identification/decoding path (rule matching, validation, and reconstructed output), so subtle mismatches in enforcer selection or rule extraction could change which permission type is detected or what `rules`/`expiry` are returned. > > **Overview** > Refactors permission decoding to use **permission decoders** (terminology change from “rules”) and removes the old `decodePermission/rules` implementation, including `findRuleWithMatchingCaveatAddresses`. > > Decoding is now driven by `createPermissionDecodersForContracts` + `findDecodersWithMatchingCaveatAddresses` and disambiguation via `selectUniqueDecoderAndDecodedPermission`, with rule extraction split into composable `RuleDecoder`s (new `expiry`, `redeemer`, and native/ERC20 `payee` decoders). > > Adds `EXECUTION_PERMISSION_EXPIRY_RULE_TYPE` and updates tests to reflect the new decoder APIs and to assert the new rule decoding behavior (including emitting an `expiry` rule and hoisting its timestamp to top-level `expiry`). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit f097d31. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 1142f20 commit b7c2567

35 files changed

Lines changed: 1541 additions & 1155 deletions

packages/gator-permissions-controller/src/GatorPermissionsController.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ import type { Hex } from '@metamask/utils';
3030
import { DELEGATION_FRAMEWORK_VERSION } from './constants';
3131
import type { DecodedPermission } from './decodePermission';
3232
import {
33-
createPermissionRulesForContracts,
34-
findRulesWithMatchingCaveatAddresses,
33+
createPermissionDecodersForContracts,
34+
findDecodersWithMatchingCaveatAddresses,
3535
reconstructDecodedPermission,
36-
selectUniqueRuleAndDecodedPermission,
36+
selectUniqueDecoderAndDecodedPermission,
3737
} from './decodePermission';
3838
import {
3939
GatorPermissionsFetchError,
@@ -592,22 +592,23 @@ export class GatorPermissionsController extends BaseController<
592592

593593
try {
594594
const enforcers = caveats.map((caveat) => caveat.enforcer);
595-
const permissionRules = createPermissionRulesForContracts(contracts);
595+
const permissionDecoders =
596+
createPermissionDecodersForContracts(contracts);
596597

597-
// Every rule where enforcer addresses match; multiple types may share the same
598-
// caveat pattern and are disambiguated by validateAndDecodePermission.
599-
const matchingRules = findRulesWithMatchingCaveatAddresses({
598+
// Every decoder where enforcer addresses match; multiple types may share the
599+
// same caveat pattern and are disambiguated by validateAndDecodePermission.
600+
const matchingDecoders = findDecodersWithMatchingCaveatAddresses({
600601
enforcers,
601-
permissionRules,
602+
permissionDecoders,
602603
});
603604

604605
const {
605-
rule: { permissionType },
606+
decoder: { permissionType },
606607
expiry,
607608
data,
608609
rules,
609-
} = selectUniqueRuleAndDecodedPermission({
610-
candidateRules: matchingRules,
610+
} = selectUniqueDecoderAndDecodedPermission({
611+
candidateDecoders: matchingDecoders,
611612
caveats,
612613
});
613614

packages/gator-permissions-controller/src/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,11 @@ export const EXECUTION_PERMISSION_REDEEMER_RULE_TYPE = 'redeemer' as const;
1818
* payee restrictions.
1919
*/
2020
export const EXECUTION_PERMISSION_PAYEE_RULE_TYPE = 'payee' as const;
21+
22+
/**
23+
* `Rule.type` / `wallet_getSupportedExecutionPermissions` `ruleTypes` entry for
24+
* permission expiry derived from a TimestampEnforcer caveat. The decoded
25+
* permission additionally hoists the expiry value onto its top-level `expiry`
26+
* field for convenience.
27+
*/
28+
export const EXECUTION_PERMISSION_EXPIRY_RULE_TYPE = 'expiry' as const;

0 commit comments

Comments
 (0)