@@ -111,6 +111,7 @@ import type {
111
111
NonEmptyArray ,
112
112
SemVerRange ,
113
113
CaipAssetType ,
114
+ JsonRpcRequest ,
114
115
} from '@metamask/utils' ;
115
116
import {
116
117
assert ,
@@ -213,7 +214,7 @@ export type PreinstalledSnap = {
213
214
} ;
214
215
215
216
type SnapRpcHandler = (
216
- options : SnapRpcHookArgs & { timeout : number } ,
217
+ options : SnapRpcHookArgs & { timeout : number ; request : JsonRpcRequest } ,
217
218
) => Promise < unknown > ;
218
219
219
220
/**
@@ -3513,7 +3514,7 @@ export class SnapController extends BaseController<
3513
3514
handler : handlerType ,
3514
3515
request,
3515
3516
timeout,
3516
- } : SnapRpcHookArgs & { timeout : number } ) => {
3517
+ } : SnapRpcHookArgs & { timeout : number ; request : JsonRpcRequest } ) => {
3517
3518
if ( ! this . state . snaps [ snapId ] . enabled ) {
3518
3519
throw new Error ( `Snap "${ snapId } " is disabled.` ) ;
3519
3520
}
@@ -3547,13 +3548,19 @@ export class SnapController extends BaseController<
3547
3548
}
3548
3549
}
3549
3550
3551
+ const transformedRequest = this . #transformSnapRpcRequest(
3552
+ snapId ,
3553
+ handlerType ,
3554
+ request ,
3555
+ ) ;
3556
+
3550
3557
const timer = new Timer ( timeout ) ;
3551
- this . #recordSnapRpcRequestStart( snapId , request . id , timer ) ;
3558
+ this . #recordSnapRpcRequestStart( snapId , transformedRequest . id , timer ) ;
3552
3559
3553
3560
const handleRpcRequestPromise = this . messagingSystem . call (
3554
3561
'ExecutionService:handleRpcRequest' ,
3555
3562
snapId ,
3556
- { origin, handler : handlerType , request } ,
3563
+ { origin, handler : handlerType , request : transformedRequest } ,
3557
3564
) ;
3558
3565
3559
3566
// This will either get the result or reject due to the timeout.
@@ -3566,21 +3573,21 @@ export class SnapController extends BaseController<
3566
3573
) ;
3567
3574
}
3568
3575
3569
- await this . #assertSnapRpcRequestResult ( snapId , handlerType , result ) ;
3576
+ await this . #assertSnapRpcResponse ( snapId , handlerType , result ) ;
3570
3577
3571
- const transformedResult = await this . #transformSnapRpcRequestResult (
3578
+ const transformedResult = await this . #transformSnapRpcResponse (
3572
3579
snapId ,
3573
3580
handlerType ,
3574
- request ,
3581
+ transformedRequest ,
3575
3582
result ,
3576
3583
) ;
3577
3584
3578
- this . #recordSnapRpcRequestFinish( snapId , request . id ) ;
3585
+ this . #recordSnapRpcRequestFinish( snapId , transformedRequest . id ) ;
3579
3586
3580
3587
return transformedResult ;
3581
3588
} catch ( error ) {
3582
3589
// 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 ) ;
3584
3591
const [ jsonRpcError , handled ] = unwrapError ( error ) ;
3585
3592
3586
3593
if ( ! handled ) {
@@ -3629,15 +3636,15 @@ export class SnapController extends BaseController<
3629
3636
}
3630
3637
3631
3638
/**
3632
- * Transform a RPC request result if necessary.
3639
+ * Transform a RPC response if necessary.
3633
3640
*
3634
3641
* @param snapId - The snap ID of the snap that produced the result.
3635
3642
* @param handlerType - The handler type that produced the result.
3636
3643
* @param request - The request that returned the result.
3637
- * @param result - The result .
3644
+ * @param result - The response .
3638
3645
* @returns The transformed result if applicable, otherwise the original result.
3639
3646
*/
3640
- async #transformSnapRpcRequestResult (
3647
+ async #transformSnapRpcResponse (
3641
3648
snapId : SnapId ,
3642
3649
handlerType : HandlerType ,
3643
3650
request : Record < string , unknown > ,
@@ -3763,14 +3770,50 @@ export class SnapController extends BaseController<
3763
3770
return { conversionRates : filteredConversionRates } ;
3764
3771
}
3765
3772
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
+
3766
3809
/**
3767
3810
* Assert that the returned result of a Snap RPC call is the expected shape.
3768
3811
*
3769
3812
* @param snapId - The snap ID.
3770
3813
* @param handlerType - The handler type of the RPC Request.
3771
3814
* @param result - The result of the RPC request.
3772
3815
*/
3773
- async #assertSnapRpcRequestResult (
3816
+ async #assertSnapRpcResponse (
3774
3817
snapId : SnapId ,
3775
3818
handlerType : HandlerType ,
3776
3819
result : unknown ,
0 commit comments