Skip to content

Commit 866ec92

Browse files
fix: Inject context into onUserInput calls
1 parent 48f76da commit 866ec92

File tree

1 file changed

+56
-13
lines changed

1 file changed

+56
-13
lines changed

packages/snaps-controllers/src/snaps/SnapController.ts

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import type {
110110
NonEmptyArray,
111111
SemVerRange,
112112
CaipAssetType,
113+
JsonRpcRequest,
113114
} from '@metamask/utils';
114115
import {
115116
assert,
@@ -212,7 +213,7 @@ export type PreinstalledSnap = {
212213
};
213214

214215
type SnapRpcHandler = (
215-
options: SnapRpcHookArgs & { timeout: number },
216+
options: SnapRpcHookArgs & { timeout: number; request: JsonRpcRequest },
216217
) => Promise<unknown>;
217218

218219
/**
@@ -3512,7 +3513,7 @@ export class SnapController extends BaseController<
35123513
handler: handlerType,
35133514
request,
35143515
timeout,
3515-
}: SnapRpcHookArgs & { timeout: number }) => {
3516+
}: SnapRpcHookArgs & { timeout: number; request: JsonRpcRequest }) => {
35163517
if (!this.state.snaps[snapId].enabled) {
35173518
throw new Error(`Snap "${snapId}" is disabled.`);
35183519
}
@@ -3546,13 +3547,19 @@ export class SnapController extends BaseController<
35463547
}
35473548
}
35483549

3550+
const transformedRequest = this.#transformSnapRpcRequest(
3551+
snapId,
3552+
handlerType,
3553+
request,
3554+
);
3555+
35493556
const timer = new Timer(timeout);
3550-
this.#recordSnapRpcRequestStart(snapId, request.id, timer);
3557+
this.#recordSnapRpcRequestStart(snapId, transformedRequest.id, timer);
35513558

35523559
const handleRpcRequestPromise = this.messagingSystem.call(
35533560
'ExecutionService:handleRpcRequest',
35543561
snapId,
3555-
{ origin, handler: handlerType, request },
3562+
{ origin, handler: handlerType, request: transformedRequest },
35563563
);
35573564

35583565
// This will either get the result or reject due to the timeout.
@@ -3565,21 +3572,21 @@ export class SnapController extends BaseController<
35653572
);
35663573
}
35673574

3568-
await this.#assertSnapRpcRequestResult(snapId, handlerType, result);
3575+
await this.#assertSnapRpcResponse(snapId, handlerType, result);
35693576

3570-
const transformedResult = await this.#transformSnapRpcRequestResult(
3577+
const transformedResult = await this.#transformSnapRpcResponse(
35713578
snapId,
35723579
handlerType,
3573-
request,
3580+
transformedRequest,
35743581
result,
35753582
);
35763583

3577-
this.#recordSnapRpcRequestFinish(snapId, request.id);
3584+
this.#recordSnapRpcRequestFinish(snapId, transformedRequest.id);
35783585

35793586
return transformedResult;
35803587
} catch (error) {
35813588
// We flag the RPC request as finished early since termination may affect pending requests
3582-
this.#recordSnapRpcRequestFinish(snapId, request.id);
3589+
this.#recordSnapRpcRequestFinish(snapId, transformedRequest.id);
35833590
const [jsonRpcError, handled] = unwrapError(error);
35843591

35853592
if (!handled) {
@@ -3628,15 +3635,15 @@ export class SnapController extends BaseController<
36283635
}
36293636

36303637
/**
3631-
* Transform a RPC request result if necessary.
3638+
* Transform a RPC response if necessary.
36323639
*
36333640
* @param snapId - The snap ID of the snap that produced the result.
36343641
* @param handlerType - The handler type that produced the result.
36353642
* @param request - The request that returned the result.
3636-
* @param result - The result.
3643+
* @param result - The response.
36373644
* @returns The transformed result if applicable, otherwise the original result.
36383645
*/
3639-
async #transformSnapRpcRequestResult(
3646+
async #transformSnapRpcResponse(
36403647
snapId: SnapId,
36413648
handlerType: HandlerType,
36423649
request: Record<string, unknown>,
@@ -3762,14 +3769,50 @@ export class SnapController extends BaseController<
37623769
return { conversionRates: filteredConversionRates };
37633770
}
37643771

3772+
/**
3773+
* Transforms a JSON-RPC request before sending it to the Snap, if required for a given handler.
3774+
*
3775+
* @param snapId - The Snap ID.
3776+
* @param handlerType - The handler being called.
3777+
* @param request - The JSON-RPC request.
3778+
* @returns The potentially transformed JSON-RPC request.
3779+
*/
3780+
#transformSnapRpcRequest(
3781+
snapId: SnapId,
3782+
handlerType: HandlerType,
3783+
request: JsonRpcRequest,
3784+
) {
3785+
switch (handlerType) {
3786+
// For onUserInput we inject context, so the client doesn't have to worry about keeping it in sync.
3787+
case HandlerType.OnUserInput: {
3788+
assert(request.params && hasProperty(request.params, 'id'));
3789+
3790+
const interfaceId = request.params.id as string;
3791+
const interfaceState = this.messagingSystem.call(
3792+
'SnapInterfaceController:getInterface',
3793+
snapId,
3794+
interfaceId,
3795+
);
3796+
3797+
return {
3798+
...request,
3799+
params: { ...request.params, context: interfaceState.context },
3800+
};
3801+
}
3802+
3803+
default:
3804+
return request;
3805+
}
3806+
}
3807+
37653808
/**
37663809
* Assert that the returned result of a Snap RPC call is the expected shape.
37673810
*
37683811
* @param snapId - The snap ID.
37693812
* @param handlerType - The handler type of the RPC Request.
37703813
* @param result - The result of the RPC request.
37713814
*/
3772-
async #assertSnapRpcRequestResult(
3815+
async #assertSnapRpcResponse(
37733816
snapId: SnapId,
37743817
handlerType: HandlerType,
37753818
result: unknown,

0 commit comments

Comments
 (0)