@@ -110,6 +110,7 @@ import type {
110110 NonEmptyArray ,
111111 SemVerRange ,
112112 CaipAssetType ,
113+ JsonRpcRequest ,
113114} from '@metamask/utils' ;
114115import {
115116 assert ,
@@ -212,7 +213,7 @@ export type PreinstalledSnap = {
212213} ;
213214
214215type 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