Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@metamask/snaps-utils

Package Overview
Dependencies
Maintainers
12
Versions
77
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@metamask/snaps-utils - npm Package Compare versions

Comparing version 2.0.1 to 3.0.0

12

CHANGELOG.md

@@ -9,2 +9,11 @@ # Changelog

## [3.0.0]
### Added
- Add keyring export and endowment ([#1787](https://github.com/MetaMask/snaps/pull/1787))
- Add optional `allowedOrigins` field to `endowment:rpc` ([#1822](https://github.com/MetaMask/snaps/pull/1822))
- This can be used to only accept certain origins in your Snap.
### Changed
- **BREAKING:** Bump minimum Node.js version to `^18.16.0` ([#1741](https://github.com/MetaMask/snaps/pull/1741))
## [2.0.1]

@@ -54,3 +63,4 @@ ### Changed

[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.1...HEAD
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@3.0.0...HEAD
[3.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.1...@metamask/snaps-utils@3.0.0
[2.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.0...@metamask/snaps-utils@2.0.1

@@ -57,0 +67,0 @@ [2.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.4-flask.1...@metamask/snaps-utils@2.0.0

@@ -29,2 +29,5 @@ "use strict";

SnapCaveatType[/**
* The origins that a Snap can receive keyring messages from.
*/ "KeyringOrigin"] = 'keyringOrigin';
SnapCaveatType[/**
* Caveat specifying the snap IDs that can be interacted with.

@@ -31,0 +34,0 @@ */ "SnapIds"] = 'snapIds';

@@ -30,2 +30,3 @@ "use strict";

HandlerType["OnNameLookup"] = 'onNameLookup';
HandlerType["OnKeyringRequest"] = 'onKeyringRequest';
})(HandlerType || (HandlerType = {}));

@@ -74,2 +75,9 @@ const SNAP_EXPORTS = {

}
},
[HandlerType.OnKeyringRequest]: {
type: HandlerType.OnKeyringRequest,
required: true,
validator: (snapExport)=>{
return typeof snapExport === 'function';
}
}

@@ -76,0 +84,0 @@ };

@@ -18,2 +18,11 @@ "use strict";

},
KeyringOriginsStruct: function() {
return KeyringOriginsStruct;
},
assertIsKeyringOrigins: function() {
return assertIsKeyringOrigins;
},
isOriginAllowed: function() {
return isOriginAllowed;
},
assertIsJsonRpcSuccess: function() {

@@ -23,2 +32,3 @@ return assertIsJsonRpcSuccess;

});
const _permissioncontroller = require("@metamask/permission-controller");
const _utils = require("@metamask/utils");

@@ -28,8 +38,10 @@ const _superstruct = require("superstruct");

dapps: (0, _superstruct.optional)((0, _superstruct.boolean)()),
snaps: (0, _superstruct.optional)((0, _superstruct.boolean)())
snaps: (0, _superstruct.optional)((0, _superstruct.boolean)()),
allowedOrigins: (0, _superstruct.optional)((0, _superstruct.array)((0, _superstruct.string)()))
}), 'RPC origins', (value)=>{
if (!Object.values(value).some(Boolean)) {
throw new Error('Must specify at least one JSON-RPC origin');
const hasOrigins = Boolean(value.snaps === true || value.dapps === true || value.allowedOrigins && value.allowedOrigins.length > 0);
if (hasOrigins) {
return true;
}
return true;
return 'Must specify at least one JSON-RPC origin.';
});

@@ -40,2 +52,25 @@ function assertIsRpcOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention

}
const KeyringOriginsStruct = (0, _superstruct.object)({
allowedOrigins: (0, _superstruct.optional)((0, _superstruct.array)((0, _superstruct.string)()))
});
function assertIsKeyringOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention
ErrorWrapper) {
(0, _utils.assertStruct)(value, KeyringOriginsStruct, 'Invalid keyring origins', ErrorWrapper);
}
function isOriginAllowed(origins, subjectType, origin) {
// The MetaMask client is always allowed.
if (origin === 'metamask') {
return true;
}
// If the origin is in the `allowedOrigins` list, it is allowed.
if (origins.allowedOrigins?.includes(origin)) {
return true;
}
// If the origin is a website and `dapps` is true, it is allowed.
if (subjectType === _permissioncontroller.SubjectType.Website && origins.dapps) {
return true;
}
// If the origin is a snap and `snaps` is true, it is allowed.
return Boolean(subjectType === _permissioncontroller.SubjectType.Snap && origins.snaps);
}
function assertIsJsonRpcSuccess(value) {

@@ -42,0 +77,0 @@ if (!(0, _utils.isJsonRpcSuccess)(value)) {

@@ -137,2 +137,3 @@ "use strict";

'endowment:name-lookup': (0, _superstruct.optional)(ChainIdsStruct),
'endowment:keyring': (0, _superstruct.optional)(_jsonrpc.KeyringOriginsStruct),
snap_dialog: (0, _superstruct.optional)((0, _superstruct.object)({})),

@@ -139,0 +140,0 @@ // TODO: Remove

@@ -19,2 +19,5 @@ export var SnapCaveatType;

SnapCaveatType[/**
* The origins that a Snap can receive keyring messages from.
*/ "KeyringOrigin"] = 'keyringOrigin';
SnapCaveatType[/**
* Caveat specifying the snap IDs that can be interacted with.

@@ -21,0 +24,0 @@ */ "SnapIds"] = 'snapIds';

@@ -9,2 +9,3 @@ export var HandlerType;

HandlerType["OnNameLookup"] = 'onNameLookup';
HandlerType["OnKeyringRequest"] = 'onKeyringRequest';
})(HandlerType || (HandlerType = {}));

@@ -53,2 +54,9 @@ export const SNAP_EXPORTS = {

}
},
[HandlerType.OnKeyringRequest]: {
type: HandlerType.OnKeyringRequest,
required: true,
validator: (snapExport)=>{
return typeof snapExport === 'function';
}
}

@@ -55,0 +63,0 @@ };

@@ -1,11 +0,14 @@

import { isJsonRpcFailure, isJsonRpcSuccess, assertStruct } from '@metamask/utils';
import { boolean, object, optional, refine } from 'superstruct';
import { SubjectType } from '@metamask/permission-controller';
import { assertStruct, isJsonRpcFailure, isJsonRpcSuccess } from '@metamask/utils';
import { array, boolean, object, optional, refine, string } from 'superstruct';
export const RpcOriginsStruct = refine(object({
dapps: optional(boolean()),
snaps: optional(boolean())
snaps: optional(boolean()),
allowedOrigins: optional(array(string()))
}), 'RPC origins', (value)=>{
if (!Object.values(value).some(Boolean)) {
throw new Error('Must specify at least one JSON-RPC origin');
const hasOrigins = Boolean(value.snaps === true || value.dapps === true || value.allowedOrigins && value.allowedOrigins.length > 0);
if (hasOrigins) {
return true;
}
return true;
return 'Must specify at least one JSON-RPC origin.';
});

@@ -23,3 +26,40 @@ /**

}
export const KeyringOriginsStruct = object({
allowedOrigins: optional(array(string()))
});
/**
* Assert that the given value is a valid {@link KeyringOrigins} object.
*
* @param value - The value to assert.
* @param ErrorWrapper - An optional error wrapper to use. Defaults to
* {@link AssertionError}.
* @throws If the value is not a valid {@link KeyringOrigins} object.
*/ export function assertIsKeyringOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention
ErrorWrapper) {
assertStruct(value, KeyringOriginsStruct, 'Invalid keyring origins', ErrorWrapper);
}
/**
* Check if the given origin is allowed by the given JSON-RPC origins object.
*
* @param origins - The JSON-RPC origins object.
* @param subjectType - The type of the origin.
* @param origin - The origin to check.
* @returns Whether the origin is allowed.
*/ export function isOriginAllowed(origins, subjectType, origin) {
// The MetaMask client is always allowed.
if (origin === 'metamask') {
return true;
}
// If the origin is in the `allowedOrigins` list, it is allowed.
if (origins.allowedOrigins?.includes(origin)) {
return true;
}
// If the origin is a website and `dapps` is true, it is allowed.
if (subjectType === SubjectType.Website && origins.dapps) {
return true;
}
// If the origin is a snap and `snaps` is true, it is allowed.
return Boolean(subjectType === SubjectType.Snap && origins.snaps);
}
/**
* Assert that the given value is a successful JSON-RPC response. If the value

@@ -26,0 +66,0 @@ * is not a success response, an error is thrown. If the value is an JSON-RPC

3

dist/esm/manifest/validation.js

@@ -7,3 +7,3 @@ import { isValidBIP32PathSegment } from '@metamask/key-tree';

import { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';
import { RpcOriginsStruct } from '../json-rpc';
import { KeyringOriginsStruct, RpcOriginsStruct } from '../json-rpc';
import { ChainIdStruct } from '../namespace';

@@ -88,2 +88,3 @@ import { SnapIdStruct } from '../snaps';

'endowment:name-lookup': optional(ChainIdsStruct),
'endowment:keyring': optional(KeyringOriginsStruct),
snap_dialog: optional(object({})),

@@ -90,0 +91,0 @@ // TODO: Remove

@@ -23,2 +23,6 @@ export declare enum SnapCaveatType {

/**
* The origins that a Snap can receive keyring messages from.
*/
KeyringOrigin = "keyringOrigin",
/**
* Caveat specifying the snap IDs that can be interacted with.

@@ -25,0 +29,0 @@ */

@@ -11,3 +11,4 @@ import type { Component } from '@metamask/snaps-ui';

OnUpdate = "onUpdate",
OnNameLookup = "onNameLookup"
OnNameLookup = "onNameLookup",
OnKeyringRequest = "onKeyringRequest"
}

@@ -66,2 +67,7 @@ declare type SnapHandler = {

};
readonly onKeyringRequest: {
readonly type: HandlerType.OnKeyringRequest;
readonly required: true;
readonly validator: (snapExport: unknown) => snapExport is OnKeyringRequestHandler<JsonRpcParams>;
};
};

@@ -148,2 +154,15 @@ /**

/**
* The `onKeyringRequest` handler. This is called by the MetaMask client for
* privileged keyring actions.
*
* @param args - The request arguments.
* @param args.origin - The origin of the request. This can be the ID of
* another snap, or the URL of a dapp.
* @param args.request - The JSON-RPC request sent to the snap.
*/
export declare type OnKeyringRequestHandler<Params extends JsonRpcParams = JsonRpcParams> = (args: {
origin: string;
request: JsonRpcRequest<Params>;
}) => Promise<unknown>;
/**
* Utility type for getting the handler function type from a handler type.

@@ -193,3 +212,3 @@ */

export declare type SnapFunctionExports = {
[Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<typeof SNAP_EXPORTS[Key]>;
[Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<(typeof SNAP_EXPORTS)[Key]>;
};

@@ -196,0 +215,0 @@ /**

@@ -1,2 +0,3 @@

import type { Json, JsonRpcSuccess, AssertionErrorConstructor } from '@metamask/utils';
import { SubjectType } from '@metamask/permission-controller';
import type { AssertionErrorConstructor, Json, JsonRpcSuccess } from '@metamask/utils';
import type { Infer } from 'superstruct';

@@ -6,5 +7,7 @@ export declare const RpcOriginsStruct: import("superstruct").Struct<{

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
}, {
dapps: import("superstruct").Struct<boolean | undefined, null>;
snaps: import("superstruct").Struct<boolean | undefined, null>;
allowedOrigins: import("superstruct").Struct<string[] | undefined, import("superstruct").Struct<string, null>>;
}>;

@@ -21,3 +24,27 @@ export declare type RpcOrigins = Infer<typeof RpcOriginsStruct>;

export declare function assertIsRpcOrigins(value: unknown, ErrorWrapper?: AssertionErrorConstructor): asserts value is RpcOrigins;
export declare const KeyringOriginsStruct: import("superstruct").Struct<{
allowedOrigins?: string[] | undefined;
}, {
allowedOrigins: import("superstruct").Struct<string[] | undefined, import("superstruct").Struct<string, null>>;
}>;
export declare type KeyringOrigins = Infer<typeof KeyringOriginsStruct>;
/**
* Assert that the given value is a valid {@link KeyringOrigins} object.
*
* @param value - The value to assert.
* @param ErrorWrapper - An optional error wrapper to use. Defaults to
* {@link AssertionError}.
* @throws If the value is not a valid {@link KeyringOrigins} object.
*/
export declare function assertIsKeyringOrigins(value: unknown, ErrorWrapper?: AssertionErrorConstructor): asserts value is KeyringOrigins;
/**
* Check if the given origin is allowed by the given JSON-RPC origins object.
*
* @param origins - The JSON-RPC origins object.
* @param subjectType - The type of the origin.
* @param origin - The origin to check.
* @returns Whether the origin is allowed.
*/
export declare function isOriginAllowed(origins: RpcOrigins, subjectType: SubjectType, origin: string): boolean;
/**
* Assert that the given value is a successful JSON-RPC response. If the value

@@ -24,0 +51,0 @@ * is not a success response, an error is thrown. If the value is an JSON-RPC

@@ -58,4 +58,8 @@ import type { Infer, Struct } from 'superstruct';

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
} | undefined;
'endowment:name-lookup'?: string[] | undefined;
'endowment:keyring'?: {
allowedOrigins?: string[] | undefined;
} | undefined;
snap_dialog?: {} | undefined;

@@ -134,7 +138,14 @@ snap_confirm?: {} | undefined;

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
} | undefined, {
dapps: Struct<boolean | undefined, null>;
snaps: Struct<boolean | undefined, null>;
allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
}>;
'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
'endowment:keyring': Struct<{
allowedOrigins?: string[] | undefined;
} | undefined, {
allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
}>;
snap_dialog: Struct<{} | undefined, {}>;

@@ -219,4 +230,8 @@ snap_confirm: Struct<{} | undefined, {}>;

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
} | undefined;
'endowment:name-lookup'?: string[] | undefined;
'endowment:keyring'?: {
allowedOrigins?: string[] | undefined;
} | undefined;
snap_dialog?: {} | undefined;

@@ -313,4 +328,8 @@ snap_confirm?: {} | undefined;

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
} | undefined;
'endowment:name-lookup'?: string[] | undefined;
'endowment:keyring'?: {
allowedOrigins?: string[] | undefined;
} | undefined;
snap_dialog?: {} | undefined;

@@ -389,7 +408,14 @@ snap_confirm?: {} | undefined;

snaps?: boolean | undefined;
allowedOrigins?: string[] | undefined;
} | undefined, {
dapps: Struct<boolean | undefined, null>;
snaps: Struct<boolean | undefined, null>;
allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
}>;
'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
'endowment:keyring': Struct<{
allowedOrigins?: string[] | undefined;
} | undefined, {
allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
}>;
snap_dialog: Struct<{} | undefined, {}>;

@@ -396,0 +422,0 @@ snap_confirm: Struct<{} | undefined, {}>;

@@ -13,3 +13,3 @@ /// <reference types="node" />

export declare function readVirtualFile(path: string, encoding?: BufferEncoding | null): Promise<VirtualFile<unknown>>;
declare type WriteVFileOptions = Exclude<Parameters<typeof fsPromises['writeFile']>[2], undefined>;
declare type WriteVFileOptions = Exclude<Parameters<(typeof fsPromises)['writeFile']>[2], undefined>;
/**

@@ -16,0 +16,0 @@ * Writes vfile to filesystem.

{
"name": "@metamask/snaps-utils",
"version": "2.0.1",
"version": "3.0.0",
"repository": {

@@ -49,3 +49,3 @@ "type": "git",

"posttest": "ts-node scripts/coverage.ts && rimraf coverage/jest coverage/wdio",
"test:browser": "wdio run wdio.config.ts",
"test:browser": "wdio run wdio.config.js",
"test:ci": "yarn test",

@@ -74,5 +74,5 @@ "lint:eslint": "eslint . --cache --ext js,ts,jsx,tsx",

"@metamask/key-tree": "^9.0.0",
"@metamask/permission-controller": "^4.1.0",
"@metamask/permission-controller": "^4.1.2",
"@metamask/snaps-registry": "^2.0.0",
"@metamask/snaps-ui": "^2.0.0",
"@metamask/snaps-ui": "^3.0.0",
"@metamask/utils": "^8.1.0",

@@ -97,3 +97,3 @@ "@noble/hashes": "^1.3.1",

"@lavamoat/allow-scripts": "^2.5.1",
"@metamask/auto-changelog": "^3.1.0",
"@metamask/auto-changelog": "^3.3.0",
"@metamask/eslint-config": "^12.1.0",

@@ -150,3 +150,3 @@ "@metamask/eslint-config-jest": "^12.1.0",

"engines": {
"node": ">=16.0.0"
"node": "^18.16 || >=20"
},

@@ -153,0 +153,0 @@ "publishConfig": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc