Skip to content

Commit 54735fa

Browse files
fix: Inject context into onUserInput calls
1 parent 7e6ad03 commit 54735fa

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
@@ -111,6 +111,7 @@ import type {
111111
NonEmptyArray,
112112
SemVerRange,
113113
CaipAssetType,
114+
JsonRpcRequest,
114115
} from '@metamask/utils';
115116
import {
116117
assert,
@@ -213,7 +214,7 @@ export type PreinstalledSnap = {
213214
};
214215

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

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

3551+
const transformedRequest = this.#transformSnapRpcRequest(
3552+
snapId,
3553+
handlerType,
3554+
request,
3555+
);
3556+
35503557
const timer = new Timer(timeout);
3551-
this.#recordSnapRpcRequestStart(snapId, request.id, timer);
3558+
this.#recordSnapRpcRequestStart(snapId, transformedRequest.id, timer);
35523559

35533560
const handleRpcRequestPromise = this.messagingSystem.call(
35543561
'ExecutionService:handleRpcRequest',
35553562
snapId,
3556-
{ origin, handler: handlerType, request },
3563+
{ origin, handler: handlerType, request: transformedRequest },
35573564
);
35583565

35593566
// This will either get the result or reject due to the timeout.
@@ -3566,21 +3573,21 @@ export class SnapController extends BaseController<
35663573
);
35673574
}
35683575

3569-
await this.#assertSnapRpcRequestResult(snapId, handlerType, result);
3576+
await this.#assertSnapRpcResponse(snapId, handlerType, result);
35703577

3571-
const transformedResult = await this.#transformSnapRpcRequestResult(
3578+
const transformedResult = await this.#transformSnapRpcResponse(
35723579
snapId,
35733580
handlerType,
3574-
request,
3581+
transformedRequest,
35753582
result,
35763583
);
35773584

3578-
this.#recordSnapRpcRequestFinish(snapId, request.id);
3585+
this.#recordSnapRpcRequestFinish(snapId, transformedRequest.id);
35793586

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

35863593
if (!handled) {
@@ -3629,15 +3636,15 @@ export class SnapController extends BaseController<
36293636
}
36303637

36313638
/**
3632-
* Transform a RPC request result if necessary.
3639+
* Transform a RPC response if necessary.
36333640
*
36343641
* @param snapId - The snap ID of the snap that produced the result.
36353642
* @param handlerType - The handler type that produced the result.
36363643
* @param request - The request that returned the result.
3637-
* @param result - The result.
3644+
* @param result - The response.
36383645
* @returns The transformed result if applicable, otherwise the original result.
36393646
*/
3640-
async #transformSnapRpcRequestResult(
3647+
async #transformSnapRpcResponse(
36413648
snapId: SnapId,
36423649
handlerType: HandlerType,
36433650
request: Record<string, unknown>,
@@ -3763,14 +3770,50 @@ export class SnapController extends BaseController<
37633770
return { conversionRates: filteredConversionRates };
37643771
}
37653772

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

0 commit comments

Comments
 (0)