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

perf: Remove unnecessary proxy for provider globals #2850

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
8 changes: 4 additions & 4 deletions packages/snaps-execution-environments/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 80,
"functions": 90.06,
"lines": 90.77,
"statements": 90.15
"branches": 80.28,
"functions": 89.18,
"lines": 90.66,
"statements": 90.05
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createIdRemapMiddleware } from '@metamask/json-rpc-engine';
import type { RequestArguments } from '@metamask/providers';
import { StreamProvider } from '@metamask/providers/stream-provider';
import { errorCodes, rpcErrors, serializeError } from '@metamask/rpc-errors';
import type { SnapsProvider } from '@metamask/snaps-sdk';
import type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';
import { getErrorData } from '@metamask/snaps-sdk';
import type {
SnapExports,
Expand Down Expand Up @@ -45,7 +45,6 @@ import {
assertEthereumOutboundRequest,
assertSnapOutboundRequest,
sanitizeRequestArguments,
proxyStreamProvider,
withTeardown,
isValidResponse,
} from './utils';
Expand Down Expand Up @@ -497,9 +496,9 @@ export class BaseSnapExecutor {
);
};

const snapGlobalProxy = proxyStreamProvider(request) as SnapsProvider;
const snapsProvider = { request } as SnapsProvider;

return harden(snapGlobalProxy);
return harden(snapsProvider);
}

/**
Expand All @@ -508,7 +507,9 @@ export class BaseSnapExecutor {
* @param provider - A StreamProvider connected to MetaMask.
* @returns The EIP-1193 Ethereum provider object.
*/
private createEIP1193Provider(provider: StreamProvider): StreamProvider {
private createEIP1193Provider(
provider: StreamProvider,
): SnapsEthereumProvider {
const originalRequest = provider.request.bind(provider);

const request = async (args: RequestArguments) => {
Expand All @@ -533,9 +534,9 @@ export class BaseSnapExecutor {
);
};

const streamProviderProxy = proxyStreamProvider(request);
const ethereumProvider = { request };

return harden(streamProviderProxy);
return harden(ethereumProvider);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { StreamProvider } from '@metamask/providers';
import { rpcErrors } from '@metamask/rpc-errors';
import type { SnapsProvider } from '@metamask/snaps-sdk';
import type { SnapsEthereumProvider, SnapsProvider } from '@metamask/snaps-sdk';
import { logWarning } from '@metamask/snaps-utils';
import { hasProperty } from '@metamask/utils';

Expand Down Expand Up @@ -62,7 +61,7 @@ export function createEndowments({
notify,
}: {
snap: SnapsProvider;
ethereum: StreamProvider;
ethereum: SnapsEthereumProvider;
snapId: string;
endowments: string[];
notify: NotifyFunction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import { createIdRemapMiddleware } from '@metamask/json-rpc-engine';
import ObjectMultiplex from '@metamask/object-multiplex';
import type { RequestArguments } from '@metamask/providers';
import { StreamProvider } from '@metamask/providers/stream-provider';
import type { SnapsEthereumProvider } from '@metamask/snaps-sdk';
import { SNAP_STREAM_NAMES } from '@metamask/snaps-utils';

import {
assertEthereumOutboundRequest,
proxyStreamProvider,
withTeardown,
} from '../utils';
import { assertEthereumOutboundRequest, withTeardown } from '../utils';
import { SILENT_LOGGER } from './logger';

/**
Expand Down Expand Up @@ -42,7 +39,7 @@ export function walkAndSearch(subject: unknown, target: unknown) {
*
* @returns Proxy to StreamProvider instance.
*/
export function getMockedStreamProvider() {
export function getMockedStreamProvider(): SnapsEthereumProvider {
const mux = new ObjectMultiplex();
const rpcStream = mux.createStream(SNAP_STREAM_NAMES.JSON_RPC);

Expand All @@ -59,5 +56,5 @@ export function getMockedStreamProvider() {
return await withTeardown(originalRequest(args), { lastTeardown: 0 });
};

return proxyStreamProvider(request);
return { request };
}
31 changes: 1 addition & 30 deletions packages/snaps-execution-environments/src/common/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { StreamProvider, RequestArguments } from '@metamask/providers';
import type { RequestArguments } from '@metamask/providers';
import { rpcErrors } from '@metamask/rpc-errors';
import {
assert,
Expand Down Expand Up @@ -53,35 +53,6 @@ export async function withTeardown<Type>(
});
}

/**
* Returns a Proxy that only allows access to a `request` function.
* This is useful for replacing StreamProvider with an attenuated version.
*
* @param request - Custom attenuated request function.
* @returns Proxy that mimics a StreamProvider instance.
*/
export function proxyStreamProvider(request: unknown): StreamProvider {
// Proxy target is intentionally set to be an empty object, to ensure
// that access to the prototype chain is not possible.
const proxy = new Proxy(
{},
{
has(_target: object, prop: string | symbol) {
return typeof prop === 'string' && ['request'].includes(prop);
},
get(_target, prop: keyof StreamProvider) {
if (prop === 'request') {
return request;
}

return undefined;
},
},
);

return proxy as StreamProvider;
}

// We're blocking these RPC methods for v1, will revisit later.
export const BLOCKED_RPC_METHODS = Object.freeze([
'wallet_requestPermissions',
Expand Down
Loading