refactor: Use permission decoders from @metamask/7715-permission-types#9164
refactor: Use permission decoders from @metamask/7715-permission-types#9164jeffsmale90 wants to merge 14 commits into
@metamask/7715-permission-types#9164Conversation
7a4724f to
7eda56a
Compare
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
@metamask/gator-permissions-controller consumes Advanced Permission definitions from @metamask/7715-permission-types
cb23bf0 to
c3fbd8e
Compare
@metamask/gator-permissions-controller consumes Advanced Permission definitions from @metamask/7715-permission-types@metamask/7715-permission-types
2719213 to
c436c43
Compare
c436c43 to
174d64e
Compare
mj-kiwi
left a comment
There was a problem hiding this comment.
Solid refactor, just a few minor notes.
| @@ -26,7 +26,6 @@ const gatorPermissionsController = new GatorPermissionsController({ | |||
| 'native-token-periodic', | |||
There was a problem hiding this comment.
Minor doc nit — the example supportedPermissionTypes array dropped erc20-token-revocation but doesn't seem to have added token-approval-revocation in its place, even though that type still looks supported. Might just need one line added back so the example stays accurate.
There was a problem hiding this comment.
I don't think this example needs to include all implemented permission types - this is showing how the controller may be instantiated with a list of permission types that should be supported.
This list can be incomplete - it's actually highlighting the capability to restrict supported permissions, but also we probably don't want to update this every time we add permission types to the dependency.
| @@ -1,11 +1,9 @@ | |||
| import type { DeployedContractsByName } from '@metamask/7715-permission-types'; | |||
There was a problem hiding this comment.
Noticed DeployedContractsByName moved from the precise local alias (typeof DELEGATOR_CONTRACTS)[number][number] to the package's Record<string, Hex>. Not a big deal, but it does mean a typo'd contract name would only surface at runtime (via the Contract not found throw) rather than at compile time like before. Wanted to flag in case that tradeoff wasn't deliberate.
There was a problem hiding this comment.
I've improved @metamask/7715-permission-types in MetaMask/smart-accounts-kit#278 to define EnforcerAddressesByName as the API type for contract addresses (keyed contract names, with camelCase). I've updated this PR to assert the type of the @metamask/delegation-deployments contract addresses (exported as Record<string, Hex>) to DelegationDeploymentsEnforcerAddressesByName (keyed contract names, with PascalCase) and converts them to EnforcerAddressesByName in toEnforcerAddressesByName.
| @@ -9,12 +9,8 @@ import type { | |||
| ApprovalRevocationTerms, | |||
| Caveat, | |||
There was a problem hiding this comment.
While in here — it looks like Erc20TokenAllowancePermission, NativeTokenAllowancePermission, and TokenApprovalRevocationPermission (lines 23, 40, 53 below) are still declared locally with a "not yet defined in the package" comment, but @metamask/7715-permission-types@^0.8.0 seems to export all three now (worth double-checking, since the local TokenApprovalRevocationPermission shape looks slightly different from the package's version). If the package really does cover these now, importing them directly would avoid future drift.
There was a problem hiding this comment.
Good call - I've removed the 3 locally defined permission types, along with ExtendedPermissionTypes
| import { makeErc20TokenPeriodicDecoderConfig } from './erc20TokenPeriodic'; | ||
| import { makeErc20TokenRevocationDecoderConfig } from './erc20TokenRevocation'; | ||
| import { makeErc20TokenStreamDecoderConfig } from './erc20TokenStream'; | ||
| import { makePermissionDecoderConfigs } from '@metamask/7715-permission-types'; |
There was a problem hiding this comment.
Just flagging for awareness — with per-type validation logic now living in @metamask/7715-permission-types, this package's tests only exercise a synthetic specified-permission-type rather than the real permission types end-to-end. Might be worth a lightweight integration test here (or confirming coverage exists upstream) so a future bump of the dependency that loosens a validation rule wouldn't slip by unnoticed.
| @@ -1,45 +1,22 @@ | |||
| import type { Rule } from '@metamask/7715-permission-types'; | |||
| import type { | |||
There was a problem hiding this comment.
Small one — enforcer addresses look like they get checksummed once for matching, then re-checksummed again per candidate decoder inside validateAndDecodePermission on the ambiguous-type path. Probably not costly today, but could be worth reusing the already-checksummed set if this path gets exercised more.
There was a problem hiding this comment.
This is still the case.
My concern here is that it's difficult to ensure that addresses are checksummed (at the API interface) without checksumming them 😓 - we can't type them in such a way to enforce this (unless we switch to byteslike types where case mismatching isn't possible 🤔). So it's a balance between tight coupling, and more checksumming.
Because this only ever happens once per permission, and the number of candidates that pass the caveatAddressesMatch check is normally going to be only 1, I think for now it's a low cost.
I'm going to add a comment explaining it though - let me know if you think that we should actually address this now though.
| @@ -9,12 +9,8 @@ import type { | |||
| ApprovalRevocationTerms, | |||
There was a problem hiding this comment.
RuleDecoder looks like it's only referenced from a test file now, not from any production decoder — the real shape seems to live in the package's PermissionDecoderConfig. If that's right, might be simpler to move it into the test file (or drop it) so it doesn't read as something production code still relies on.
There was a problem hiding this comment.
Moved it into the test file. It does give us a little utility within the tests.
… narrow scope to just test this function
Also fix various linting issues
a4ef722 to
7bc7040
Compare
7bc7040 to
7cbbc65
Compare
| throw new Error(`Contracts not found for chainId: ${chainId}`); | ||
| } | ||
|
|
||
| const contracts = toEnforcerAddressesByName(deploymentContracts); |
There was a problem hiding this comment.
toEnforcerAddressesByName(deploymentContracts) is now called before the try block in decodePermissionFromPermissionContextForOrigin. This means a "Contract not found" error would escape unwrapped instead of being
caught and rethrown as PermissionDecodingError, which the method's @throws doc promises. Could we move this call back inside the try block, similar to how resolveGrantedPermissionOnChainStatus in permissionOnChainStatus.ts handles it?
Explanation
MetaMask/smart-accounts-kit#259 adds permission decoder definitions to @metamask/7715-permission-types released in 0.8.0.
This PR updates @metamask/gator-permissions-controller to consume these permission definitions instead of defining the permission decoders directly in the controller.
Note:
erc20-token-revocationpermission type is no longer supported.References
Checklist
Note
High Risk
Breaking removal of
erc20-token-revocationand a broad swap of delegation permission decoding logic affect how granted permissions are interpreted; incorrect decoding could misrepresent token limits or revocations.Overview
Moves Gator permission decoding onto
@metamask/7715-permission-types^1.0.0 by building decoders frommakePermissionDecoderConfigsand wrapping them with the localmakePermissionDecoder, instead of maintaining per-type decoder modules in this package.Breaking:
erc20-token-revocationis removed from default/READMEsupportedPermissionTypesand all related decoder/tests. Decoding now maps chain deployments throughtoEnforcerAddressesByName/delegationContractsByChainIdbefore invoking shared decoders.Large local decoder/rule implementations and their integration-style unit tests are deleted;
decodePermission.test.tsandmakePermissionDecoder.test.tsfocus on orchestration (findDecodersWithMatchingCaveatAddresses,selectUniqueDecoderAndDecodedPermission, factory behavior). Controller tests add end-to-end decode coverage for allowance andtoken-approval-revocationtypes and expand pending-revocation transaction listener edge cases.Reviewed by Cursor Bugbot for commit 59a1487. Bugbot is set up for automated code reviews on this repo. Configure here.