Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e785683
refactor(permission-controller)!: Remove unrestricted rpc methods
rekmarks Apr 24, 2026
3b9f35a
feat(json-rpc-engine): consolidate legacy `createMethodMiddleware`
rekmarks Apr 24, 2026
b7faed3
refactor(json-rpc-engine)!: Support messenger handlers in legacy meth…
rekmarks Apr 24, 2026
be9aaca
chore: Update changelogs
rekmarks Apr 24, 2026
77f1777
refactor(json-rpc-engine): Pre-resolve hooks per handler in legacy me…
rekmarks Apr 27, 2026
09b26c5
refactor: Harmonize legacy middleware with v2 version
rekmarks Apr 27, 2026
f86425a
Merge branch 'main' into rekm/v2-permitted-handlers
rekmarks Apr 27, 2026
dc38a25
chore: Tweak permission-controller changelog
rekmarks Apr 27, 2026
fc5c197
refactor: Address review
rekmarks Apr 28, 2026
ce46bdb
feat(json-rpc-engine): optional root messenger for method middleware
rekmarks Apr 28, 2026
473387f
feat(json-rpc-engine): optional RequestExtras on legacy MethodHandler
rekmarks Apr 28, 2026
afad6dc
refactor(multichain-api-middleware): Migrate to new method handler pa…
rekmarks Apr 28, 2026
e7105fc
refactor(eip1193-permission-middleware): Migrate to new method handle…
rekmarks Apr 28, 2026
45a82ea
refactor: Minor fixups
rekmarks Apr 28, 2026
86dd857
fix: Fix legacy method middleware hook inference
rekmarks Apr 28, 2026
3763b57
chore: Lint
rekmarks Apr 28, 2026
c4a8339
refactor: Fix trackSessionCreatedEvent optionality
rekmarks Apr 28, 2026
f43f664
fix: Require hooks in createMethodMiddleware options
rekmarks Apr 29, 2026
7114b69
test: Round out v2 method middleware test suite
rekmarks Apr 29, 2026
897b1ae
chore: lint
rekmarks Apr 29, 2026
846bfc4
refactor: Address review feedback
rekmarks Apr 29, 2026
a1caffc
refactor: Rename method handler exports
rekmarks Apr 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eslint-suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1334,7 +1334,7 @@
},
"packages/multichain-api-middleware/src/handlers/wallet-createSession.ts": {
"@typescript-eslint/explicit-function-return-type": {
"count": 2
"count": 1
},
"@typescript-eslint/prefer-nullish-coalescing": {
"count": 2
Expand Down
3 changes: 3 additions & 0 deletions packages/eip1193-permission-middleware/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **BREAKING:** Consolidate method handlers into a single `methodHandlers` export ([#8583](https://github.com/MetaMask/core/pull/8583))
- The individual handler exports have been removed. They can still be accessed as properties on the `methodHandlers` export.
- The new handlers follow the format expected by `createMethodMiddleware` from `@metamask/json-rpc-engine@10.3.0`.
- Bump `@metamask/chain-agnostic-permission` from `^1.4.0` to `^1.5.0` ([#8290](https://github.com/MetaMask/core/pull/8290))
- Bump `@metamask/json-rpc-engine` from `^10.2.0` to `^10.2.4` ([#7642](https://github.com/MetaMask/core/pull/7642), [#7856](https://github.com/MetaMask/core/pull/7856), [#8078](https://github.com/MetaMask/core/pull/8078), [#8317](https://github.com/MetaMask/core/pull/8317))
- Upgrade `@metamask/utils` from `^11.8.1` to `^11.9.0` ([#7511](https://github.com/MetaMask/core/pull/7511))
Expand Down
33 changes: 30 additions & 3 deletions packages/eip1193-permission-middleware/src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
import { createMethodMiddleware } from '@metamask/json-rpc-engine';

import * as allExports from '.';
import type { GetPermissionsHooks } from './wallet-getPermissions';
import type { RequestPermissionsHooks } from './wallet-requestPermissions';
import type { RevokePermissionsHooks } from './wallet-revokePermissions';

type Hooks = GetPermissionsHooks &
RequestPermissionsHooks &
RevokePermissionsHooks;

/* eslint-disable @typescript-eslint/explicit-function-return-type */
const makeMockHooks = () =>
({
getPermissionsForOrigin: (() => ({})) as Hooks['getPermissionsForOrigin'],
getAccounts: () => ['0x123'],
requestPermissionsForOrigin: (() =>
Promise.resolve([{}])) as Hooks['requestPermissionsForOrigin'],
revokePermissionsForOrigin: () => undefined,
getCaip25PermissionFromLegacyPermissionsForOrigin: () => ({}),
}) satisfies Hooks;
/* eslint-enable @typescript-eslint/explicit-function-return-type */

describe('@metamask/eip1193-permission-middleware', () => {
it('has expected JavaScript exports', () => {
expect(Object.keys(allExports)).toMatchInlineSnapshot(`
[
"getPermissionsHandler",
"requestPermissionsHandler",
"revokePermissionsHandler",
"methodHandlers",
]
`);
});

it('constructs a method middleware from the handlers', () => {
const middleware = createMethodMiddleware({
handlers: allExports.methodHandlers,
hooks: makeMockHooks(),
});
expect(middleware).toBeDefined();
});
});
20 changes: 17 additions & 3 deletions packages/eip1193-permission-middleware/src/index.ts
Comment thread
FrederikBolding marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
export { getPermissionsHandler } from './wallet-getPermissions';
export { requestPermissionsHandler } from './wallet-requestPermissions';
export { revokePermissionsHandler } from './wallet-revokePermissions';
import { MethodNames } from '@metamask/permission-controller';

import { getPermissionsHandler } from './wallet-getPermissions';
import { requestPermissionsHandler } from './wallet-requestPermissions';
import { revokePermissionsHandler } from './wallet-revokePermissions';

type MethodHandlers = {
[MethodNames.GetPermissions]: typeof getPermissionsHandler;
[MethodNames.RequestPermissions]: typeof requestPermissionsHandler;
[MethodNames.RevokePermissions]: typeof revokePermissionsHandler;
};

export const methodHandlers: Readonly<MethodHandlers> = {
[MethodNames.GetPermissions]: getPermissionsHandler,
[MethodNames.RequestPermissions]: requestPermissionsHandler,
[MethodNames.RevokePermissions]: revokePermissionsHandler,
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
getPermittedEthChainIds,
} from '@metamask/chain-agnostic-permission';
import type {
AsyncJsonRpcEngineNextCallback,
JsonRpcEngineEndCallback,
JsonRpcEngineNextCallback,
MethodHandler,
} from '@metamask/json-rpc-engine';
import { MethodNames } from '@metamask/permission-controller';
import type {
CaveatSpecificationConstraint,
PermissionController,
Expand All @@ -22,14 +22,31 @@ import type {

import { CaveatTypes, EndowmentTypes, RestrictedMethods } from './types';

export type GetPermissionsHooks = {
getPermissionsForOrigin: () => ReturnType<
PermissionController<
PermissionSpecificationConstraint,
CaveatSpecificationConstraint
>['getPermissions']
>;
getAccounts: (options?: { ignoreLock?: boolean }) => string[];
};

export type GetPermissionsHandler = MethodHandler<
GetPermissionsHooks,
never,
Json[],
Json,
{ origin: string }
>;

export const getPermissionsHandler = {
methodNames: [MethodNames.GetPermissions],
implementation: getPermissionsImplementation,
hookNames: {
getPermissionsForOrigin: true,
getAccounts: true,
},
};
} satisfies GetPermissionsHandler;

/**
* Get Permissions implementation to be used in JsonRpcEngine middleware, specifically for `wallet_getPermissions` RPC method.
Expand All @@ -47,20 +64,9 @@ export const getPermissionsHandler = {
async function getPermissionsImplementation(
_req: JsonRpcRequest<Json[]>,
res: PendingJsonRpcResponse,
_next: AsyncJsonRpcEngineNextCallback,
_next: JsonRpcEngineNextCallback,
end: JsonRpcEngineEndCallback,
{
getPermissionsForOrigin,
getAccounts,
}: {
getPermissionsForOrigin: () => ReturnType<
PermissionController<
PermissionSpecificationConstraint,
CaveatSpecificationConstraint
>['getPermissions']
>;
getAccounts: (options?: { ignoreLock?: boolean }) => string[];
},
{ getPermissionsForOrigin, getAccounts }: GetPermissionsHooks,
) {
const permissions = { ...getPermissionsForOrigin() };
const caip25Endowment = permissions[Caip25EndowmentPermissionName];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
} from '@metamask/chain-agnostic-permission';
import { isPlainObject } from '@metamask/controller-utils';
import type {
AsyncJsonRpcEngineNextCallback,
JsonRpcEngineNextCallback,
JsonRpcEngineEndCallback,
MethodHandler,
} from '@metamask/json-rpc-engine';
import { invalidParams, MethodNames } from '@metamask/permission-controller';
import { invalidParams } from '@metamask/permission-controller';
import type {
Caveat,
CaveatSpecificationConstraint,
Expand All @@ -27,15 +28,32 @@ import { pick } from 'lodash';

import { CaveatTypes, EndowmentTypes, RestrictedMethods } from './types';

export type RequestPermissionsHooks = {
getAccounts: () => string[];
requestPermissionsForOrigin: (
requestedPermissions: RequestedPermissions,
) => Promise<[GrantedPermissions]>;
getCaip25PermissionFromLegacyPermissionsForOrigin: (
requestedPermissions?: RequestedPermissions,
) => RequestedPermissions;
};

export type RequestPermissionsHandler = MethodHandler<
RequestPermissionsHooks,
never,
[RequestedPermissions],
Json,
{ origin: string }
>;

export const requestPermissionsHandler = {
methodNames: [MethodNames.RequestPermissions],
implementation: requestPermissionsImplementation,
hookNames: {
getAccounts: true,
requestPermissionsForOrigin: true,
getCaip25PermissionFromLegacyPermissionsForOrigin: true,
},
};
} satisfies RequestPermissionsHandler;

type AbstractPermissionController = PermissionController<
PermissionSpecificationConstraint,
Expand Down Expand Up @@ -63,21 +81,13 @@ type GrantedPermissions = Awaited<
async function requestPermissionsImplementation(
req: JsonRpcRequest<[RequestedPermissions]> & { origin: string },
res: PendingJsonRpcResponse,
_next: AsyncJsonRpcEngineNextCallback,
_next: JsonRpcEngineNextCallback,
end: JsonRpcEngineEndCallback,
{
getAccounts,
requestPermissionsForOrigin,
getCaip25PermissionFromLegacyPermissionsForOrigin,
}: {
getAccounts: () => string[];
requestPermissionsForOrigin: (
requestedPermissions: RequestedPermissions,
) => Promise<[GrantedPermissions]>;
getCaip25PermissionFromLegacyPermissionsForOrigin: (
requestedPermissions?: RequestedPermissions,
) => RequestedPermissions;
},
}: RequestPermissionsHooks,
) {
const { params } = req;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission';
import type {
AsyncJsonRpcEngineNextCallback,
JsonRpcEngineNextCallback,
JsonRpcEngineEndCallback,
MethodHandler,
} from '@metamask/json-rpc-engine';
import { invalidParams, MethodNames } from '@metamask/permission-controller';
import { invalidParams } from '@metamask/permission-controller';
import { isNonEmptyArray } from '@metamask/utils';
import type {
Json,
Expand All @@ -13,14 +14,24 @@ import type {

import { EndowmentTypes, RestrictedMethods } from './types';

export type RevokePermissionsHooks = {
revokePermissionsForOrigin: (permissionKeys: string[]) => void;
};

export type RevokePermissionsHandler = MethodHandler<
RevokePermissionsHooks,
never,
Json[],
Json,
{ origin: string }
>;

export const revokePermissionsHandler = {
methodNames: [MethodNames.RevokePermissions],
implementation: revokePermissionsImplementation,
hookNames: {
revokePermissionsForOrigin: true,
updateCaveat: true,
},
};
} satisfies RevokePermissionsHandler;

/**
* Revoke Permissions implementation to be used in JsonRpcEngine middleware.
Expand All @@ -36,7 +47,7 @@ export const revokePermissionsHandler = {
function revokePermissionsImplementation(
req: JsonRpcRequest<Json[]>,
res: PendingJsonRpcResponse,
_next: AsyncJsonRpcEngineNextCallback,
_next: JsonRpcEngineNextCallback,
end: JsonRpcEngineEndCallback,
{
revokePermissionsForOrigin,
Expand Down
6 changes: 5 additions & 1 deletion packages/json-rpc-engine/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Add `createOriginMiddleware` utility to `v2` ([#8522](https://github.com/MetaMask/core/pull/8522))
- Add `createMethodMiddleware` utility to `v2` ([#8506](https://github.com/MetaMask/core/pull/8506))
- Add `createMethodMiddleware` utility to `v2` ([#8506](https://github.com/MetaMask/core/pull/8506), [#8583](https://github.com/MetaMask/core/pull/8583))
- This utility allows JSON-RPC method implementations to use both the hooks pattern and the messenger.
- Add legacy `createMethodMiddleware` ([#8583](https://github.com/MetaMask/core/pull/8583))
- Consolidates bespoke `makeMethodMiddlewareMaker` implementations from the MetaMask extension and mobile clients.
- Handlers may now declare `actionNames` and receive a delegated messenger as the sixth argument to `implementation`, mirroring the v2 `createMethodMiddleware`.
- Deprecated in favor of the v2 `createMethodMiddleware`.

## [10.2.4]

Expand Down
Loading
Loading