Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use @metamask/json-rpc-engine #275

Closed
wants to merge 6 commits into from
Closed
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
247 changes: 247 additions & 0 deletions .yarn/patches/@metamask-rpc-errors-npm-5.1.1-dc76c26803.patch

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,19 @@
"test": "jest && jest-it-up",
"test:watch": "jest --watch"
},
"resolutions": {
"@metamask/rpc-errors@^5.1.1": "patch:@metamask/rpc-errors@npm:5.1.1#.yarn/patches/@metamask-rpc-errors-npm-5.1.1-dc76c26803.patch"
},
"dependencies": {
"@metamask/json-rpc-engine": "^7.0.0",
"@metamask/object-multiplex": "^1.1.0",
"@metamask/rpc-errors": "^5.1.1",
"@metamask/safe-event-emitter": "^3.0.0",
"@metamask/utils": "^7.1.0",
"detect-browser": "^5.2.0",
"eth-rpc-errors": "^4.0.2",
"extension-port-stream": "^2.0.1",
"fast-deep-equal": "^3.1.3",
"is-stream": "^2.0.0",
"json-rpc-engine": "^6.1.0",
"json-rpc-middleware-stream": "^4.2.1",
"pump": "^3.0.0",
"webextension-polyfill": "^0.10.0"
Expand Down
39 changes: 17 additions & 22 deletions src/BaseProvider.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { JsonRpcEngine, JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import { rpcErrors, JsonRpcError } from '@metamask/rpc-errors';
import SafeEventEmitter from '@metamask/safe-event-emitter';
import { ethErrors, EthereumRpcError } from 'eth-rpc-errors';
import dequal from 'fast-deep-equal';
import {
JsonRpcEngine,
JsonRpcRequest,
JsonRpcId,
JsonRpcVersion,
JsonRpcVersion2,
JsonRpcSuccess,
JsonRpcMiddleware,
} from 'json-rpc-engine';
JsonRpcParams,
Json,
} from '@metamask/utils';
import dequal from 'fast-deep-equal';

import messages from './messages';
import {
Expand All @@ -20,7 +21,7 @@ import {

export type UnvalidatedJsonRpcRequest = {
id?: JsonRpcId;
jsonrpc?: JsonRpcVersion;
jsonrpc?: JsonRpcVersion2;
method: string;
params?: unknown;
};
Expand All @@ -37,10 +38,10 @@ export type BaseProviderOptions = {
maxEventListeners?: number;

/**
* `json-rpc-engine` middleware. The middleware will be inserted in the given
* `@metamask/json-rpc-engine` middleware. The middleware will be inserted in the given
* order immediately after engine initialization.
*/
rpcMiddleware?: JsonRpcMiddleware<unknown, unknown>[];
rpcMiddleware?: JsonRpcMiddleware<JsonRpcParams, Json>[];
};

export type RequestArguments = {
Expand Down Expand Up @@ -169,7 +170,7 @@ export abstract class BaseProvider extends SafeEventEmitter {
*/
async request<T>(args: RequestArguments): Promise<Maybe<T>> {
if (!args || typeof args !== 'object' || Array.isArray(args)) {
throw ethErrors.rpc.invalidRequest({
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestArgs(),
data: args,
});
Expand All @@ -178,7 +179,7 @@ export abstract class BaseProvider extends SafeEventEmitter {
const { method, params } = args;

if (typeof method !== 'string' || method.length === 0) {
throw ethErrors.rpc.invalidRequest({
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestMethod(),
data: args,
});
Expand All @@ -189,7 +190,7 @@ export abstract class BaseProvider extends SafeEventEmitter {
!Array.isArray(params) &&
(typeof params !== 'object' || params === null)
) {
throw ethErrors.rpc.invalidRequest({
throw rpcErrors.invalidRequest({
message: messages.errors.invalidRequestParams(),
data: args,
});
Expand Down Expand Up @@ -285,15 +286,9 @@ export abstract class BaseProvider extends SafeEventEmitter {
callback(error, response);
};
}
return this._rpcEngine.handle(
payload as JsonRpcRequest<unknown>,
callbackWrapper,
);
return this._rpcEngine.handle(payload as JsonRpcRequest, callbackWrapper);
}
return this._rpcEngine.handle(
payload as JsonRpcRequest<unknown>[],
callbackWrapper,
);
return this._rpcEngine.handle(payload as JsonRpcRequest[], callbackWrapper);
}

/**
Expand Down Expand Up @@ -331,13 +326,13 @@ export abstract class BaseProvider extends SafeEventEmitter {

let error;
if (isRecoverable) {
error = new EthereumRpcError(
error = new JsonRpcError(
1013, // Try again later
errorMessage ?? messages.errors.disconnected(),
);
this._log.debug(error);
} else {
error = new EthereumRpcError(
error = new JsonRpcError(
1011, // Internal error
errorMessage ?? messages.errors.permanentlyDisconnected(),
);
Expand Down
4 changes: 2 additions & 2 deletions src/MetaMaskInpageProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JsonRpcRequest } from 'json-rpc-engine';
import { JsonRpcRequest } from '@metamask/utils';

import messages from './messages';
import {
Expand Down Expand Up @@ -58,7 +58,7 @@ async function getInitializedProvider({
onMethodCalled?: {
substream: string;
method: string;
callback: (data: JsonRpcRequest<unknown>) => void;
callback: (data: JsonRpcRequest) => void;
}[];
} = {}): Promise<InitializedProviderDetails> {
const onWrite = jest.fn();
Expand Down
27 changes: 15 additions & 12 deletions src/MetaMaskInpageProvider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ethErrors } from 'eth-rpc-errors';
import type { JsonRpcRequest, JsonRpcResponse } from 'json-rpc-engine';
import { rpcErrors } from '@metamask/rpc-errors';
import type { Json, JsonRpcRequest, JsonRpcResponse } from '@metamask/utils';
import type { Duplex } from 'stream';

import type { UnvalidatedJsonRpcRequest } from './BaseProvider';
import { UnvalidatedJsonRpcRequest } from './BaseProvider';
import messages from './messages';
import { sendSiteMetadata } from './siteMetadata';
import {
Expand All @@ -22,7 +22,7 @@ export type SendSyncJsonRpcRequest = {
| 'eth_coinbase'
| 'eth_uninstallFilter'
| 'net_version';
} & JsonRpcRequest<unknown>;
} & JsonRpcRequest;

type WarningEventName = keyof SentWarningsState['events'];

Expand Down Expand Up @@ -171,8 +171,8 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
* @param callback - The callback function.
*/
sendAsync(
payload: JsonRpcRequest<unknown>,
callback: (error: Error | null, result?: JsonRpcResponse<unknown>) => void,
payload: JsonRpcRequest,
callback: (error: Error | null, result?: JsonRpcResponse<Json>) => void,
): void {
this._rpcRequest(payload, callback);
}
Expand Down Expand Up @@ -283,7 +283,10 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
* @returns A Promise that resolves with the JSON-RPC response object for the
* request.
*/
send<T>(method: string, params?: T[]): Promise<JsonRpcResponse<T>>;
send<T extends Json>(
method: string,
params?: T[],
): Promise<JsonRpcResponse<T>>;

/**
* Submits an RPC request per the given JSON-RPC request object.
Expand All @@ -293,8 +296,8 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
* @param callback - An error-first callback that will receive the JSON-RPC
* response object.
*/
send<T>(
payload: JsonRpcRequest<unknown>,
send<T extends Json>(
payload: JsonRpcRequest,
callback: (error: Error | null, result?: JsonRpcResponse<T>) => void,
): void;

Expand All @@ -306,7 +309,7 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
* @param payload - A JSON-RPC request object.
* @returns A JSON-RPC response object.
*/
send<T>(payload: SendSyncJsonRpcRequest): JsonRpcResponse<T>;
send<T extends Json>(payload: SendSyncJsonRpcRequest): JsonRpcResponse<T>;

// eslint-disable-next-line @typescript-eslint/promise-function-async
send(methodOrPayload: unknown, callbackOrArgs?: unknown): unknown {
Expand Down Expand Up @@ -335,7 +338,7 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
typeof callbackOrArgs === 'function'
) {
return this._rpcRequest(
methodOrPayload as JsonRpcRequest<unknown>,
methodOrPayload as JsonRpcRequest,
callbackOrArgs as (...args: unknown[]) => void,
);
}
Expand Down Expand Up @@ -412,7 +415,7 @@ export class MetaMaskInpageProvider extends AbstractStreamProvider {
*/
requestBatch: async (requests: UnvalidatedJsonRpcRequest[]) => {
if (!Array.isArray(requests)) {
throw ethErrors.rpc.invalidRequest({
throw rpcErrors.invalidRequest({
message:
'Batch requests must be made with an array of request objects.',
data: requests,
Expand Down
5 changes: 3 additions & 2 deletions src/StreamProvider.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { JsonRpcMiddleware } from 'json-rpc-engine';
import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import { Json, JsonRpcParams } from '@metamask/utils';

import messages from './messages';
import { StreamProvider } from './StreamProvider';
Expand All @@ -15,7 +16,7 @@ const mockStreamName = 'mock-stream';
* @returns A tuple containing the StreamProvider instance and the mock stream.
*/
function getStreamProvider(
rpcMiddleware: JsonRpcMiddleware<unknown, unknown>[] = [],
rpcMiddleware: JsonRpcMiddleware<JsonRpcParams, Json>[] = [],
) {
const mockStream = new MockConnectionStream();
const streamProvider = new StreamProvider(mockStream, {
Expand Down
5 changes: 3 additions & 2 deletions src/StreamProvider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import ObjectMultiplex from '@metamask/object-multiplex';
import SafeEventEmitter from '@metamask/safe-event-emitter';
import { Json, JsonRpcParams } from '@metamask/utils';
import { duplex as isDuplex } from 'is-stream';
import type { JsonRpcMiddleware } from 'json-rpc-engine';
import { createStreamMiddleware } from 'json-rpc-middleware-stream';
import pump from 'pump';
import type { Duplex } from 'stream';
Expand All @@ -23,7 +24,7 @@ export type StreamProviderOptions = {

export type JsonRpcConnection = {
events: SafeEventEmitter;
middleware: JsonRpcMiddleware<unknown, unknown>;
middleware: JsonRpcMiddleware<JsonRpcParams, Json>;
stream: Duplex;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JsonRpcRequest } from 'json-rpc-engine';
import type { JsonRpcRequest } from '@metamask/utils';

import { createExternalExtensionProvider } from './createExternalExtensionProvider';
import config from './external-extension-config.json';
Expand Down Expand Up @@ -49,7 +49,7 @@ async function getInitializedProvider({
onMethodCalled?: {
substream: string;
method: string;
callback: (data: JsonRpcRequest<unknown>) => void;
callback: (data: JsonRpcRequest) => void;
}[];
} = {}): Promise<InitializedExtensionProviderDetails> {
const onWrite = jest.fn();
Expand Down
7 changes: 4 additions & 3 deletions src/middleware/createRpcWarningMiddleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { JsonRpcEngine, JsonRpcFailure, JsonRpcSuccess } from 'json-rpc-engine';
import { JsonRpcEngine } from '@metamask/json-rpc-engine';
import { Json, JsonRpcFailure, JsonRpcSuccess } from '@metamask/utils';

import { createRpcWarningMiddleware } from './createRpcWarningMiddleware';
import messages from '../messages';
Expand Down Expand Up @@ -89,7 +90,7 @@ describe('createRpcWarningMiddleware', () => {
jsonrpc: '2.0',
id: 1,
method,
})) as JsonRpcSuccess<unknown>;
})) as JsonRpcSuccess<Json>;

expect(response.result).toBe('success!');
});
Expand Down Expand Up @@ -138,7 +139,7 @@ describe('createRpcWarningMiddleware', () => {
id: 1,
method,
params,
})) as JsonRpcSuccess<unknown>;
})) as JsonRpcSuccess<Json>;

expect(response.result).toBe('success!');
});
Expand Down
5 changes: 3 additions & 2 deletions src/middleware/createRpcWarningMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { JsonRpcMiddleware, JsonRpcRequest } from 'json-rpc-engine';
import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine';
import type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';

import { ERC1155, ERC721 } from '../constants';
import messages from '../messages';
Expand All @@ -12,7 +13,7 @@ import type { ConsoleLike } from '../utils';
*/
export function createRpcWarningMiddleware(
log: ConsoleLike,
): JsonRpcMiddleware<unknown, unknown> {
): JsonRpcMiddleware<JsonRpcParams, Json> {
const sentWarnings = {
ethDecryptDeprecation: false,
ethGetEncryptionPublicKeyDeprecation: false,
Expand Down
2 changes: 1 addition & 1 deletion src/siteMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JsonRpcEngine } from 'json-rpc-engine';
import { JsonRpcEngine } from '@metamask/json-rpc-engine';

import messages from './messages';
import { ConsoleLike, NOOP } from './utils';
Expand Down
16 changes: 8 additions & 8 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { ethErrors } from 'eth-rpc-errors';
import {
createIdRemapMiddleware,
JsonRpcMiddleware,
PendingJsonRpcResponse,
} from 'json-rpc-engine';
} from '@metamask/json-rpc-engine';
import { rpcErrors } from '@metamask/rpc-errors';
import { Json, JsonRpcParams, PendingJsonRpcResponse } from '@metamask/utils';

import { createRpcWarningMiddleware } from './middleware/createRpcWarningMiddleware';

Expand All @@ -27,7 +27,7 @@
* remapping middleware and an error middleware.
*
* @param logger - The logger to use in the error middleware.
* @returns An array of json-rpc-engine middleware functions.
* @returns An array of @metamask/json-rpc-engine middleware functions.
*/
export const getDefaultExternalMiddleware = (logger: ConsoleLike = console) => [
createIdRemapMiddleware(),
Expand All @@ -40,15 +40,15 @@
* method.
*
* @param log - The logging API to use.
* @returns A json-rpc-engine middleware function.
* @returns A @metamask/json-rpc-engine middleware function.
*/
function createErrorMiddleware(
log: ConsoleLike,
): JsonRpcMiddleware<unknown, unknown> {
): JsonRpcMiddleware<JsonRpcParams, Json> {
return (request, response, next) => {
// json-rpc-engine will terminate the request when it notices this error
if (typeof request.method !== 'string' || !request.method) {
response.error = ethErrors.rpc.invalidRequest({
response.error = rpcErrors.invalidRequest({

Check failure on line 51 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Build (16.x)

Type 'JsonRpcError<JsonRpcRequest<Json[] | Record<string, Json> | undefined>>' is not assignable to type '{ code: number; message: string; data?: Json | undefined; stack?: string | undefined; }'.

Check failure on line 51 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Build (18.x)

Type 'JsonRpcError<JsonRpcRequest<Json[] | Record<string, Json> | undefined>>' is not assignable to type '{ code: number; message: string; data?: Json | undefined; stack?: string | undefined; }'.

Check failure on line 51 in src/utils.ts

View workflow job for this annotation

GitHub Actions / Build, lint, and test / Build (20.x)

Type 'JsonRpcError<JsonRpcRequest<Json[] | Record<string, Json> | undefined>>' is not assignable to type '{ code: number; message: string; data?: Json | undefined; stack?: string | undefined; }'.
message: `The request 'method' must be a non-empty string.`,
data: request,
});
Expand All @@ -72,7 +72,7 @@
reject: (error?: Error) => void,
unwrapResult = true,
) =>
(error: Error, response: PendingJsonRpcResponse<unknown>): void => {
(error: Error, response: PendingJsonRpcResponse<Json>): void => {
if (error || response.error) {
reject(error || response.error);
} else {
Expand Down
Loading
Loading