Skip to content

Commit

Permalink
Fix transaction insight snaps returning null (#1952)
Browse files Browse the repository at this point in the history
When RPC result assertions were added, we forgot to account for
transaction insight snaps returning null to signify no insight. This PR
fixes this problem.

---------

Co-authored-by: Maarten Zuidhoorn <[email protected]>
  • Loading branch information
FrederikBolding and Mrtenz authored Nov 10, 2023
1 parent 70269b6 commit f621a33
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 7 deletions.
2 changes: 1 addition & 1 deletion packages/snaps-controllers/coverage.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"branches": 90.23,
"branches": 90.26,
"functions": 96.32,
"lines": 97.22,
"statements": 96.9
Expand Down
52 changes: 52 additions & 0 deletions packages/snaps-controllers/src/snaps/SnapController.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,58 @@ describe('SnapController', () => {
});
});

it(`doesn't throw if onTransaction handler returns null`, async () => {
const rootMessenger = getControllerMessenger();
const messenger = getSnapControllerMessenger(rootMessenger);
const snapController = getSnapController(
getSnapControllerOptions({
messenger,
state: {
snaps: getPersistedSnapsState(),
},
}),
);

rootMessenger.registerActionHandler(
'PermissionController:getPermissions',
() => ({
[SnapEndowments.TransactionInsight]: {
caveats: [{ type: SnapCaveatType.TransactionOrigin, value: false }],
date: 1664187844588,
id: 'izn0WGUO8cvq_jqvLQuQP',
invoker: MOCK_SNAP_ID,
parentCapability: SnapEndowments.TransactionInsight,
},
}),
);

rootMessenger.registerActionHandler(
'SubjectMetadataController:getSubjectMetadata',
() => MOCK_SNAP_SUBJECT_METADATA,
);

rootMessenger.registerActionHandler(
'ExecutionService:handleRpcRequest',
async () => Promise.resolve(null),
);

expect(
await snapController.handleRequest({
snapId: MOCK_SNAP_ID,
origin: 'foo.com',
handler: HandlerType.OnTransaction,
request: {
jsonrpc: '2.0',
method: ' ',
params: {},
id: 1,
},
}),
).toBeNull();

snapController.destroy();
});

it('throws if onHomePage handler returns a phishing link', async () => {
const rootMessenger = getControllerMessenger();
const messenger = getSnapControllerMessenger(rootMessenger);
Expand Down
7 changes: 6 additions & 1 deletion packages/snaps-controllers/src/snaps/SnapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2701,8 +2701,12 @@ export class SnapController extends BaseController<
*/
async #assertSnapRpcRequestResult(handlerType: HandlerType, result: unknown) {
switch (handlerType) {
case HandlerType.OnTransaction:
case HandlerType.OnTransaction: {
assertStruct(result, OnTransactionResponseStruct);
// Null is an allowed return value here
if (result === null) {
return;
}

await this.#triggerPhishingListUpdate();

Expand All @@ -2711,6 +2715,7 @@ export class SnapController extends BaseController<
this.#checkPhishingList.bind(this),
);
break;
}
case HandlerType.OnHomePage:
assertStruct(result, OnHomePageResponseStruct);

Expand Down
12 changes: 7 additions & 5 deletions packages/snaps-utils/src/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type {
} from '@metamask/snaps-sdk';
import { SeverityLevel } from '@metamask/snaps-sdk';
import { ComponentStruct } from '@metamask/snaps-ui';
import { literal, object, optional } from 'superstruct';
import { literal, nullable, object, optional } from 'superstruct';

import type { SnapHandler } from './handler-types';
import { HandlerType } from './handler-types';
Expand Down Expand Up @@ -80,10 +80,12 @@ export const SNAP_EXPORTS = {
},
} as const;

export const OnTransactionResponseStruct = object({
content: ComponentStruct,
severity: optional(literal(SeverityLevel.Critical)),
});
export const OnTransactionResponseStruct = nullable(
object({
content: ComponentStruct,
severity: optional(literal(SeverityLevel.Critical)),
}),
);

export const OnHomePageResponseStruct = object({
content: ComponentStruct,
Expand Down

0 comments on commit f621a33

Please sign in to comment.