Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 packages/json-rpc-engine/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `JsonRpcEngineV2` ([#6176](https://github.com/MetaMask/core/pull/6176), [#6971](https://github.com/MetaMask/core/pull/6971))
- `JsonRpcEngineV2` ([#6176](https://github.com/MetaMask/core/pull/6176), [#6971](https://github.com/MetaMask/core/pull/6971), [#6975](https://github.com/MetaMask/core/pull/6975))
- This is a complete rewrite of `JsonRpcEngine`, intended to replace the original implementation.
See the readme for details.

Expand Down
2 changes: 0 additions & 2 deletions packages/json-rpc-engine/src/v2/JsonRpcEngineV2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -770,8 +770,6 @@ describe('JsonRpcEngineV2', () => {
middleware: [inflightMiddleware, resultMiddleware],
});

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - Jest blows up here, but there's no error at dev time.
const requests: JsonRpcRequest[] = Array.from({ length: N }, (_, i) =>
makeRequest({
id: `${i}`,
Expand Down
4 changes: 2 additions & 2 deletions packages/json-rpc-engine/src/v2/JsonRpcEngineV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export type Next<Request extends JsonRpcCall> = (
) => Promise<Readonly<ResultConstraint<Request>> | undefined>;

export type MiddlewareParams<
Request extends JsonRpcCall,
Context extends MiddlewareContext,
Request extends JsonRpcCall = JsonRpcCall,
Context extends MiddlewareContext = MiddlewareContext,
> = {
request: Readonly<Request>;
context: Context;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { rpcErrors } from '@metamask/rpc-errors';

import type { MiddlewareScaffold } from './createScaffoldMiddleware';
import { createScaffoldMiddleware } from './createScaffoldMiddleware';
import { JsonRpcEngineV2 } from './JsonRpcEngineV2';
import { makeRequest } from '../../tests/utils';

describe('createScaffoldMiddleware', () => {
it('basic middleware test', async () => {
const scaffold: MiddlewareScaffold = {
method1: 'foo',
method2: () => 42,
method3: () => {
throw rpcErrors.internal({ message: 'method3' });
},
};

const engine = JsonRpcEngineV2.create({
middleware: [createScaffoldMiddleware(scaffold), () => 'passthrough'],
});

const result1 = await engine.handle(makeRequest({ method: 'method1' }));
const result2 = await engine.handle(makeRequest({ method: 'method2' }));
const promise3 = engine.handle(makeRequest({ method: 'method3' }));
const result4 = await engine.handle(makeRequest({ method: 'unknown' }));

expect(result1).toBe('foo');

expect(result2).toBe(42);

await expect(promise3).rejects.toThrow(
rpcErrors.internal({ message: 'method3' }),
);

expect(result4).toBe('passthrough');
});
});
44 changes: 44 additions & 0 deletions packages/json-rpc-engine/src/v2/createScaffoldMiddleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';

import type { JsonRpcMiddleware } from './JsonRpcEngineV2';

// Only permit primitive values as hard-coded scaffold middleware results.
type JsonPrimitive = string | number | boolean | null;

export type ScaffoldMiddlewareHandler<
Params extends JsonRpcParams,
Result extends Json,
> = JsonRpcMiddleware<JsonRpcRequest<Params>, Result> | JsonPrimitive;

/**
* A record of RPC method handler functions or hard-coded results, keyed to particular method names.
* Only primitive JSON values are permitted as hard-coded results.
*/
export type MiddlewareScaffold = Record<
string,
ScaffoldMiddlewareHandler<JsonRpcParams, Json>
>;

/**
* Creates a middleware function from an object of RPC method handler functions,
* keyed to particular method names. If a method corresponding to a key of this
* object is requested, this middleware will pass it to the corresponding
* handler and return the result.
*
* @param handlers - The RPC method handler functions.
* @returns The scaffold middleware function.
*/
export function createScaffoldMiddleware(
handlers: MiddlewareScaffold,
): JsonRpcMiddleware<JsonRpcRequest, Json> {
return ({ request, context, next }) => {
const handlerOrResult = handlers[request.method];
if (handlerOrResult === undefined) {
return next();
}

return typeof handlerOrResult === 'function'
? handlerOrResult({ request, context, next })
: handlerOrResult;
};
}
1 change: 1 addition & 0 deletions packages/json-rpc-engine/src/v2/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ describe('@metamask/json-rpc-engine/v2', () => {
"JsonRpcServer",
"MiddlewareContext",
"asLegacyMiddleware",
"createScaffoldMiddleware",
"getUniqueId",
"isNotification",
"isRequest",
Expand Down
1 change: 1 addition & 0 deletions packages/json-rpc-engine/src/v2/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { asLegacyMiddleware } from './asLegacyMiddleware';
export { getUniqueId } from '../getUniqueId';
export { createScaffoldMiddleware } from './createScaffoldMiddleware';
export * from './JsonRpcEngineV2';
export { JsonRpcServer } from './JsonRpcServer';
export { MiddlewareContext } from './MiddlewareContext';
Expand Down
24 changes: 15 additions & 9 deletions packages/json-rpc-engine/tests/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@ import type { JsonRpcMiddleware } from 'src/v2/JsonRpcEngineV2';
import { requestProps } from '../src/v2/compatibility-utils';
import type { JsonRpcNotification } from '../src/v2/utils';

export const makeRequest = <Request extends Partial<JsonRpcRequest>>(
params: Request = {} as Request,
const jsonrpc = '2.0' as const;

export const makeRequest = <
Input extends Partial<JsonRpcRequest>,
Output extends Input & JsonRpcRequest,
>(
request: Input = {} as Input,
) =>
({
jsonrpc: '2.0',
id: '1',
method: 'test_request',
params: [],
...params,
}) as const satisfies JsonRpcRequest;
jsonrpc,
id: request.id ?? '1',
method: request.method ?? 'test_request',

params: request.params === undefined ? [] : request.params,
...request,
}) as Output;

export const makeNotification = <Request extends Partial<JsonRpcRequest>>(
params: Request = {} as Request,
) =>
({
jsonrpc: '2.0',
jsonrpc,
method: 'test_request',
params: [],
...params,
Expand Down
Loading