Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/snaps-controllers/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 93.67,
"functions": 98.16,
"branches": 93.68,
"functions": 98.17,
"lines": 98.51,
"statements": 98.34
"statements": 98.35
}
71 changes: 71 additions & 0 deletions packages/snaps-controllers/src/snaps/SnapController.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11581,4 +11581,75 @@ describe('SnapController', () => {
snapController.destroy();
});
});

describe('SnapController:isMinimumPlatformVersion', () => {
it('returns true or false depending on whether the minimum version is supported', async () => {
const messenger = getSnapControllerMessenger();

const manifest = getSnapManifest({
platformVersion: '6.0.0' as SemVerVersion,
});

const snapController = getSnapController(
getSnapControllerOptions({
messenger,
state: {
snaps: getPersistedSnapsState(getPersistedSnapObject({ manifest })),
},
}),
);

expect(
messenger.call(
'SnapController:isMinimumPlatformVersion',
MOCK_SNAP_ID,
'1.0.0' as SemVerVersion,
),
).toBe(true);

expect(
messenger.call(
'SnapController:isMinimumPlatformVersion',
MOCK_SNAP_ID,
manifest.platformVersion as SemVerVersion,
),
).toBe(true);

expect(
messenger.call(
'SnapController:isMinimumPlatformVersion',
MOCK_SNAP_ID,
'7.0.0' as SemVerVersion,
),
).toBe(false);

snapController.destroy();
});

it('returns false if the platformVersion is undefined', async () => {
const messenger = getSnapControllerMessenger();

const manifest = getSnapManifest();
delete manifest.platformVersion;

const snapController = getSnapController(
getSnapControllerOptions({
messenger,
state: {
snaps: getPersistedSnapsState(getPersistedSnapObject({ manifest })),
},
}),
);

expect(
messenger.call(
'SnapController:isMinimumPlatformVersion',
MOCK_SNAP_ID,
'999.0.0' as SemVerVersion,
),
).toBe(false);

snapController.destroy();
});
});
});
36 changes: 34 additions & 2 deletions packages/snaps-controllers/src/snaps/SnapController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ import type {
CaipAssetType,
JsonRpcRequest,
Hex,
SemVerVersion,
} from '@metamask/utils';
import {
hexToNumber,
Expand All @@ -134,7 +135,7 @@ import { createMachine, interpret } from '@xstate/fsm';
import { Mutex } from 'async-mutex';
import type { Patch } from 'immer';
import { nanoid } from 'nanoid';
import { gt } from 'semver';
import { gt, gte } from 'semver';

import {
ALLOWED_PERMISSIONS,
Expand Down Expand Up @@ -462,6 +463,11 @@ export type GetSnapFile = {
handler: SnapController['getSnapFile'];
};

export type IsMinimumPlatformVersion = {
type: `${typeof controllerName}:isMinimumPlatformVersion`;
handler: SnapController['isMinimumPlatformVersion'];
};

export type SnapControllerGetStateAction = ControllerGetStateAction<
typeof controllerName,
SnapControllerState
Expand All @@ -488,7 +494,8 @@ export type SnapControllerActions =
| RevokeDynamicPermissions
| GetSnapFile
| SnapControllerGetStateAction
| StopAllSnaps;
| StopAllSnaps
| IsMinimumPlatformVersion;

// Controller Messenger Events

Expand Down Expand Up @@ -1256,6 +1263,11 @@ export class SnapController extends BaseController<
`${controllerName}:stopAllSnaps`,
async (...args) => this.stopAllSnaps(...args),
);

this.messagingSystem.registerActionHandler(
`${controllerName}:isMinimumPlatformVersion`,
(...args) => this.isMinimumPlatformVersion(...args),
);
}

#handlePreinstalledSnaps(preinstalledSnaps: PreinstalledSnap[]) {
Expand Down Expand Up @@ -2178,6 +2190,26 @@ export class SnapController extends BaseController<
return encoded;
}

/**
* Determine if a given Snap ID supports a given miniumum version of the Snaps platform
* by inspecting the platformVersion in the Snap manifest.
*
* @param snapId - The Snap ID.
* @param version - The version.
* @returns True if the platform version is equal or greater to the passed version, false otherwise.
*/
isMinimumPlatformVersion(snapId: SnapId, version: SemVerVersion): boolean {
const snap = this.getExpect(snapId);

const { platformVersion } = snap.manifest;

if (!platformVersion) {
return false;
}

return gte(platformVersion, version);
}

/**
* Completely clear the controller's state: delete all associated data,
* handlers, event listeners, and permissions; tear down all snap providers.
Expand Down
Loading