@@ -111,6 +111,7 @@ import type {
111111 NonEmptyArray ,
112112 SemVerRange ,
113113 CaipAssetType ,
114+ JsonRpcRequest ,
114115} from '@metamask/utils' ;
115116import {
116117 assert ,
@@ -213,7 +214,7 @@ export type PreinstalledSnap = {
213214} ;
214215
215216type 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 { context } = this . messagingSystem . call (
3793+ 'SnapInterfaceController:getInterface' ,
3794+ snapId ,
3795+ interfaceId ,
3796+ ) ;
3797+
3798+ return {
3799+ ...request ,
3800+ params : { ...request . params , 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