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

cherry-pick(v12.1.1): Bump @metamask/eth-json-rpc-middleware to ^14.0.0 (#26143) #26626

Merged
merged 12 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 9 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
33 changes: 33 additions & 0 deletions .yarn/patches/@trezor-connect-web-npm-9.3.0-040ab10d9a.patch
Gudahtt marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
diff --git a/lib/impl/core-in-iframe.js b/lib/impl/core-in-iframe.js
index c47cf3bff860d6b1855341c00b80fc6c40f9d6d5..275eb0f312ff396819fa406c154a3562842db49d 100644
--- a/lib/impl/core-in-iframe.js
+++ b/lib/impl/core-in-iframe.js
@@ -116,7 +116,9 @@ class CoreInIframe {
this._log.enabled = !!this._settings.debug;
window.addEventListener('message', this.boundHandleMessage);
window.addEventListener('unload', this.boundDispose);
- await iframe.init(this._settings);
+ const modifiedSettings = Object.assign({}, this.settings);
+ modifiedSettings.env = 'webextension';
+ await iframe.init(modifiedSettings);
if (this._settings.sharedLogger !== false) {
iframe.initIframeLogger();
}
diff --git a/lib/popup/index.js b/lib/popup/index.js
index 9b13c370a5ac8b4e4fc0315ed40cdf615d0bb0cb..4dbd97fc28df49beb73379451974ec48a8a42ea7 100644
--- a/lib/popup/index.js
+++ b/lib/popup/index.js
@@ -229,10 +229,12 @@ class PopupManager extends events_1.default {
}
else if (message.type === events_2.POPUP.LOADED) {
this.handleMessage(message);
+ const modifiedSettings = Object.assign({}, this.settings);
+ modifiedSettings.env = 'webextension';
this.channel.postMessage({
type: events_2.POPUP.INIT,
payload: {
- settings: this.settings,
+ settings: modifiedSettings,
useCore: true,
},
});
1 change: 0 additions & 1 deletion app/scripts/lib/accounts/BalancesController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import { Poller } from './Poller';
const mockBtcAccount = createMockInternalAccount({
address: '',
name: 'Btc Account',
// @ts-expect-error - account type may be btc or eth, mock file is not typed
type: BtcAccountType.P2wpkh,
snapOptions: {
id: 'mock-btc-snap',
Expand Down
27 changes: 17 additions & 10 deletions app/scripts/lib/createDupeReqFilterStream.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import OurReadableStream from 'readable-stream';
import ReadableStream2 from 'readable-stream-2';
import ReadableStream3 from 'readable-stream-3';

import type { JsonRpcRequest } from '@metamask/utils';
import type { JsonRpcNotification, JsonRpcRequest } from '@metamask/utils';
import createDupeReqFilterStream, {
THREE_MINUTES,
} from './createDupeReqFilterStream';
Expand All @@ -26,7 +26,7 @@ function createTestStream(output: JsonRpcRequest[] = [], S = Transform) {
}

function runStreamTest(
requests: JsonRpcRequest[] = [],
requests: (JsonRpcRequest | JsonRpcNotification)[] = [],
advanceTimersTime = 10,
S = Transform,
) {
Expand Down Expand Up @@ -54,12 +54,12 @@ describe('createDupeReqFilterStream', () => {
const requests = [
{ id: 1, method: 'foo' },
{ id: 2, method: 'bar' },
];
].map((request) => ({ ...request, jsonrpc: '2.0' as const }));

const expectedOutput = [
{ id: 1, method: 'foo' },
{ id: 2, method: 'bar' },
];
].map((output) => ({ ...output, jsonrpc: '2.0' }));

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
Expand All @@ -69,18 +69,25 @@ describe('createDupeReqFilterStream', () => {
const requests = [
{ id: 1, method: 'foo' },
{ id: 1, method: 'foo' }, // duplicate
];
].map((request) => ({ ...request, jsonrpc: '2.0' as const }));

const expectedOutput = [{ id: 1, method: 'foo' }];
const expectedOutput = [{ id: 1, method: 'foo' }].map((output) => ({
...output,
jsonrpc: '2.0',
}));

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
});

it("lets through requests if they don't have an id", async () => {
const requests = [{ method: 'notify1' }, { method: 'notify2' }];
const requests = [{ method: 'notify1' }, { method: 'notify2' }].map(
(request) => ({ ...request, jsonrpc: '2.0' as const }),
);

const expectedOutput = [{ method: 'notify1' }, { method: 'notify2' }];
const expectedOutput = [{ method: 'notify1' }, { method: 'notify2' }].map(
(output) => ({ ...output, jsonrpc: '2.0' }),
);

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
Expand All @@ -95,15 +102,15 @@ describe('createDupeReqFilterStream', () => {
{ method: 'notify2' },
{ id: 2, method: 'bar' },
{ id: 3, method: 'baz' },
];
].map((request) => ({ ...request, jsonrpc: '2.0' as const }));

const expectedOutput = [
{ id: 1, method: 'foo' },
{ method: 'notify1' },
{ id: 2, method: 'bar' },
{ method: 'notify2' },
{ id: 3, method: 'baz' },
];
].map((output) => ({ ...output, jsonrpc: '2.0' }));

const output = await runStreamTest(requests);
expect(output).toEqual(expectedOutput);
Expand Down
4 changes: 2 additions & 2 deletions app/scripts/lib/createDupeReqFilterStream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const THREE_MINUTES = MINUTE * 3;
* @returns The expiry set.
*/
const makeExpirySet = () => {
const map: Map<string | number, number> = new Map();
const map: Map<string | number | null, number> = new Map();

setInterval(() => {
const cutoffTime = Date.now() - THREE_MINUTES;
Expand All @@ -32,7 +32,7 @@ const makeExpirySet = () => {
* @param value - The value to add.
* @returns `true` if the value was added, and `false` if it already existed.
*/
add(value: string | number) {
add(value: string | number | null) {
if (!map.has(value)) {
map.set(value, Date.now());
return true;
Expand Down
50 changes: 26 additions & 24 deletions app/scripts/lib/ppom/ppom-middleware.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import {
type Hex,
JsonRpcRequestStruct,
JsonRpcResponseStruct,
} from '@metamask/utils';
import { type Hex, JsonRpcResponseStruct } from '@metamask/utils';
import { CHAIN_IDS } from '../../../../shared/constants/network';

import {
BlockaidReason,
BlockaidResultType,
} from '../../../../shared/constants/security-provider';
import { flushPromises } from '../../../../test/lib/timer-helpers';
import { createPPOMMiddleware } from './ppom-middleware';
import { createPPOMMiddleware, PPOMMiddlewareRequest } from './ppom-middleware';
import {
generateSecurityAlertId,
handlePPOMError,
Expand All @@ -28,6 +24,12 @@ const SECURITY_ALERT_RESPONSE_MOCK: SecurityAlertResponse = {
reason: BlockaidReason.permitFarming,
};

const REQUEST_MOCK = {
params: [],
id: '',
jsonrpc: '2.0' as const,
};

const createMiddleware = (
options: {
chainId?: Hex;
Expand All @@ -48,8 +50,7 @@ const createMiddleware = (
const preferenceController = {
store: {
getState: () => ({
securityAlertsEnabled:
securityAlertsEnabled === undefined ?? securityAlertsEnabled,
securityAlertsEnabled: securityAlertsEnabled ?? true,
}),
},
};
Expand Down Expand Up @@ -106,14 +107,14 @@ describe('PPOMMiddleware', () => {
});

const req = {
...JsonRpcRequestStruct,
...REQUEST_MOCK,
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};

await middlewareFunction(
req,
{ ...JsonRpcResponseStruct },
{ ...JsonRpcResponseStruct.TYPE },
() => undefined,
);

Expand All @@ -130,20 +131,20 @@ describe('PPOMMiddleware', () => {
it('adds loading response to confirmation requests while validation is in progress', async () => {
const middlewareFunction = createMiddleware();

const req = {
...JsonRpcRequestStruct,
const req: PPOMMiddlewareRequest<(string | { to: string })[]> = {
...REQUEST_MOCK,
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};

await middlewareFunction(
req,
{ ...JsonRpcResponseStruct },
{ ...JsonRpcResponseStruct.TYPE },
() => undefined,
);

expect(req.securityAlertResponse.reason).toBe(BlockaidReason.inProgress);
expect(req.securityAlertResponse.result_type).toBe(
expect(req.securityAlertResponse?.reason).toBe(BlockaidReason.inProgress);
expect(req.securityAlertResponse?.result_type).toBe(
BlockaidResultType.Loading,
);
});
Expand All @@ -154,11 +155,12 @@ describe('PPOMMiddleware', () => {
});

const req = {
...JsonRpcRequestStruct,
...REQUEST_MOCK,
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};

// @ts-expect-error Passing in invalid input for testing purposes
await middlewareFunction(req, undefined, () => undefined);

expect(req.securityAlertResponse).toBeUndefined();
Expand All @@ -171,14 +173,14 @@ describe('PPOMMiddleware', () => {
});

const req = {
...JsonRpcRequestStruct,
...REQUEST_MOCK,
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};

await middlewareFunction(
req,
{ ...JsonRpcResponseStruct },
{ ...JsonRpcResponseStruct.TYPE },
() => undefined,
);

Expand All @@ -190,14 +192,14 @@ describe('PPOMMiddleware', () => {
const middlewareFunction = createMiddleware();

const req = {
...JsonRpcRequestStruct,
...REQUEST_MOCK,
method: 'eth_someRequest',
securityAlertResponse: undefined,
};

await middlewareFunction(
req,
{ ...JsonRpcResponseStruct },
{ ...JsonRpcResponseStruct.TYPE },
() => undefined,
);

Expand All @@ -210,8 +212,8 @@ describe('PPOMMiddleware', () => {
const nextMock = jest.fn();

await middlewareFunction(
{ ...JsonRpcRequestStruct, method: 'eth_sendTransaction' },
{ ...JsonRpcResponseStruct },
{ ...REQUEST_MOCK, method: 'eth_sendTransaction' },
{ ...JsonRpcResponseStruct.TYPE },
nextMock,
);

Expand All @@ -227,12 +229,12 @@ describe('PPOMMiddleware', () => {
const middlewareFunction = createMiddleware({ error });

const req = {
...JsonRpcRequestStruct,
...REQUEST_MOCK,
method: 'eth_sendTransaction',
securityAlertResponse: undefined,
};

await middlewareFunction(req, { ...JsonRpcResponseStruct }, nextMock);
await middlewareFunction(req, { ...JsonRpcResponseStruct.TYPE }, nextMock);

expect(req.securityAlertResponse).toStrictEqual(
SECURITY_ALERT_RESPONSE_MOCK,
Expand Down
10 changes: 8 additions & 2 deletions app/scripts/lib/ppom/ppom-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ const CONFIRMATION_METHODS = Object.freeze([
...SIGNING_METHODS,
]);

export type PPOMMiddlewareRequest<
Params extends JsonRpcParams = JsonRpcParams,
> = Required<JsonRpcRequest<Params>> & {
securityAlertResponse?: SecurityAlertResponse | undefined;
};

/**
* Middleware function that handles JSON RPC requests.
* This function will be called for every JSON RPC request.
Expand All @@ -44,7 +50,7 @@ const CONFIRMATION_METHODS = Object.freeze([
* @returns PPOMMiddleware function.
*/
export function createPPOMMiddleware<
Params extends JsonRpcParams,
Params extends (string | { to: string })[],
Result extends Json,
>(
ppomController: PPOMController,
Expand All @@ -58,7 +64,7 @@ export function createPPOMMiddleware<
) => void,
) {
return async (
req: JsonRpcRequest<Params>,
req: PPOMMiddlewareRequest<Params>,
_res: JsonRpcResponse<Result>,
next: () => void,
) => {
Expand Down
2 changes: 2 additions & 0 deletions app/scripts/lib/ppom/ppom-util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const TRANSACTION_ID_MOCK = '123';
const REQUEST_MOCK = {
method: 'eth_signTypedData_v4',
params: [],
id: '',
jsonrpc: '2.0' as const,
};

const SECURITY_ALERT_RESPONSE_MOCK: SecurityAlertResponse = {
Expand Down
16 changes: 13 additions & 3 deletions app/scripts/lib/ppom/ppom-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const SECURITY_ALERT_RESPONSE_ERROR = {
reason: BlockaidReason.errored,
};

type PPOMRequest = Omit<JsonRpcRequest, 'method' | 'params'> & {
method: typeof METHOD_SEND_TRANSACTION;
params: [TransactionParams];
};
export async function validateRequestWithPPOM({
ppomController,
request,
Expand Down Expand Up @@ -115,12 +119,18 @@ async function usePPOM(
}
}

function normalizePPOMRequest(request: JsonRpcRequest): JsonRpcRequest {
if (request.method !== METHOD_SEND_TRANSACTION) {
function normalizePPOMRequest(
request: PPOMRequest | JsonRpcRequest,
): PPOMRequest | JsonRpcRequest {
if (
!((req): req is PPOMRequest => req.method === METHOD_SEND_TRANSACTION)(
request,
)
) {
return request;
}

const transactionParams = (request.params?.[0] || {}) as TransactionParams;
const transactionParams = request.params[0];
const normalizedParams = normalizeTransactionParams(transactionParams);

return {
Expand Down
7 changes: 4 additions & 3 deletions app/scripts/lib/transaction/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,12 @@ function validateSecurity(request: AddTransactionRequest) {
params: [
{
from,
to,
value,
data,
to: to ?? '',
value: value ?? '',
data: data ?? '',
},
],
jsonrpc: '2.0' as const,
};

const securityAlertId = generateSecurityAlertId();
Expand Down
2 changes: 1 addition & 1 deletion app/scripts/snaps/preinstalled-snaps.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { PreinstalledSnap } from '@metamask/snaps-controllers';
import MessageSigningSnap from '@metamask/message-signing-snap/dist/preinstalled-snap.json';

const PREINSTALLED_SNAPS: readonly PreinstalledSnap[] = Object.freeze([
const PREINSTALLED_SNAPS = Object.freeze<PreinstalledSnap[]>([
MessageSigningSnap as PreinstalledSnap,
]);

Expand Down
Loading