@metamask/snaps-utils 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.0.0]
10
+ ### Added
11
+ - Add keyring export and endowment ([#1787](https://github.com/MetaMask/snaps/pull/1787))
12
+ - Add optional `allowedOrigins` field to `endowment:rpc` ([#1822](https://github.com/MetaMask/snaps/pull/1822))
13
+ - This can be used to only accept certain origins in your Snap.
14
+
15
+ ### Changed
16
+ - **BREAKING:** Bump minimum Node.js version to `^18.16.0` ([#1741](https://github.com/MetaMask/snaps/pull/1741))
17
+
18
+ ## [2.0.1]
19
+ ### Changed
20
+ - Remove deprecated `endowment:long-running` ([#1751](https://github.com/MetaMask/snaps/pull/1751))
21
+
9
22
  ## [2.0.0]
10
23
  ### Changed
11
24
  - Initial stable release from main branch ([#1757](https://github.com/MetaMask/snaps/pull/1757))
@@ -46,7 +59,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
46
59
  - The version of the package no longer needs to match the version of all other
47
60
  MetaMask Snaps packages.
48
61
 
49
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.0...HEAD
62
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@3.0.0...HEAD
63
+ [3.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.1...@metamask/snaps-utils@3.0.0
64
+ [2.0.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@2.0.0...@metamask/snaps-utils@2.0.1
50
65
  [2.0.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.4-flask.1...@metamask/snaps-utils@2.0.0
51
66
  [0.38.4-flask.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.3-flask.1...@metamask/snaps-utils@0.38.4-flask.1
52
67
  [0.38.3-flask.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.2-flask.1...@metamask/snaps-utils@0.38.3-flask.1
@@ -26,6 +26,9 @@ var SnapCaveatType;
26
26
  * The origins that a Snap can receive JSON-RPC messages from.
27
27
  */ "RpcOrigin"] = 'rpcOrigin';
28
28
  SnapCaveatType[/**
29
+ * The origins that a Snap can receive keyring messages from.
30
+ */ "KeyringOrigin"] = 'keyringOrigin';
31
+ SnapCaveatType[/**
29
32
  * Caveat specifying the snap IDs that can be interacted with.
30
33
  */ "SnapIds"] = 'snapIds';
31
34
  SnapCaveatType[/**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/caveats.ts"],"sourcesContent":["export enum SnapCaveatType {\n /**\n * Permitted derivation paths, used by `snap_getBip32Entropy`.\n */\n PermittedDerivationPaths = 'permittedDerivationPaths',\n\n /**\n * Permitted coin types, used by `snap_getBip44Entropy`.\n */\n PermittedCoinTypes = 'permittedCoinTypes',\n\n /**\n * Caveat specifying a snap cronjob.\n */\n SnapCronjob = 'snapCronjob',\n\n /**\n * Caveat specifying access to the transaction origin, used by `endowment:transaction-insight`.\n */\n TransactionOrigin = 'transactionOrigin',\n\n /**\n * The origins that a Snap can receive JSON-RPC messages from.\n */\n RpcOrigin = 'rpcOrigin',\n\n /**\n * Caveat specifying the snap IDs that can be interacted with.\n */\n SnapIds = 'snapIds',\n\n /**\n * Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.\n */\n ChainIds = 'chainIds',\n}\n"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","SnapIds","ChainIds"],"mappings":";;;;;;;;;;IAAO;UAAKA,cAAc;IAAdA,eACV;;GAEC,GACDC,8BAA2B;IAJjBD,eAMV;;GAEC,GACDE,wBAAqB;IATXF,eAWV;;GAEC,GACDG,iBAAc;IAdJH,eAgBV;;GAEC,GACDI,uBAAoB;IAnBVJ,eAqBV;;GAEC,GACDK,eAAY;IAxBFL,eA0BV;;GAEC,GACDM,aAAU;IA7BAN,eA+BV;;GAEC,GACDO,cAAW;GAlCDP,mBAAAA"}
1
+ {"version":3,"sources":["../../src/caveats.ts"],"sourcesContent":["export enum SnapCaveatType {\n /**\n * Permitted derivation paths, used by `snap_getBip32Entropy`.\n */\n PermittedDerivationPaths = 'permittedDerivationPaths',\n\n /**\n * Permitted coin types, used by `snap_getBip44Entropy`.\n */\n PermittedCoinTypes = 'permittedCoinTypes',\n\n /**\n * Caveat specifying a snap cronjob.\n */\n SnapCronjob = 'snapCronjob',\n\n /**\n * Caveat specifying access to the transaction origin, used by `endowment:transaction-insight`.\n */\n TransactionOrigin = 'transactionOrigin',\n\n /**\n * The origins that a Snap can receive JSON-RPC messages from.\n */\n RpcOrigin = 'rpcOrigin',\n\n /**\n * The origins that a Snap can receive keyring messages from.\n */\n KeyringOrigin = 'keyringOrigin',\n\n /**\n * Caveat specifying the snap IDs that can be interacted with.\n */\n SnapIds = 'snapIds',\n\n /**\n * Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.\n */\n ChainIds = 'chainIds',\n}\n"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","KeyringOrigin","SnapIds","ChainIds"],"mappings":";;;;;;;;;;IAAO;UAAKA,cAAc;IAAdA,eACV;;GAEC,GACDC,8BAA2B;IAJjBD,eAMV;;GAEC,GACDE,wBAAqB;IATXF,eAWV;;GAEC,GACDG,iBAAc;IAdJH,eAgBV;;GAEC,GACDI,uBAAoB;IAnBVJ,eAqBV;;GAEC,GACDK,eAAY;IAxBFL,eA0BV;;GAEC,GACDM,mBAAgB;IA7BNN,eA+BV;;GAEC,GACDO,aAAU;IAlCAP,eAoCV;;GAEC,GACDQ,cAAW;GAvCDR,mBAAAA"}
@@ -27,6 +27,7 @@ var HandlerType;
27
27
  HandlerType["OnInstall"] = 'onInstall';
28
28
  HandlerType["OnUpdate"] = 'onUpdate';
29
29
  HandlerType["OnNameLookup"] = 'onNameLookup';
30
+ HandlerType["OnKeyringRequest"] = 'onKeyringRequest';
30
31
  })(HandlerType || (HandlerType = {}));
31
32
  const SNAP_EXPORTS = {
32
33
  [HandlerType.OnRpcRequest]: {
@@ -70,6 +71,13 @@ const SNAP_EXPORTS = {
70
71
  validator: (snapExport)=>{
71
72
  return typeof snapExport === 'function';
72
73
  }
74
+ },
75
+ [HandlerType.OnKeyringRequest]: {
76
+ type: HandlerType.OnKeyringRequest,
77
+ required: true,
78
+ validator: (snapExport)=>{
79
+ return typeof snapExport === 'function';
80
+ }
73
81
  }
74
82
  };
75
83
  var SeverityLevel;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/handlers.ts"],"sourcesContent":["import type { Component } from '@metamask/snaps-ui';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport type { EnumToUnion } from './enum';\nimport type { AccountAddress, Caip2ChainId } from './namespace';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\n OnNameLookup = 'onNameLookup',\n}\n\ntype SnapHandler = {\n /**\n * The type of handler.\n */\n type: HandlerType;\n\n /**\n * Whether the handler is required, i.e., whether the request will fail if the\n * handler is called, but the snap does not export it.\n *\n * This is primarily used for the lifecycle handlers, which are optional.\n */\n required: boolean;\n\n /**\n * Validate the given snap export. This should return a type guard for the\n * handler type.\n *\n * @param snapExport - The export to validate.\n * @returns Whether the export is valid.\n */\n validator: (snapExport: unknown) => boolean;\n};\n\nexport const SNAP_EXPORTS = {\n [HandlerType.OnRpcRequest]: {\n type: HandlerType.OnRpcRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnRpcRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnTransaction]: {\n type: HandlerType.OnTransaction,\n required: true,\n validator: (snapExport: unknown): snapExport is OnTransactionHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnCronjob]: {\n type: HandlerType.OnCronjob,\n required: true,\n validator: (snapExport: unknown): snapExport is OnCronjobHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnNameLookup]: {\n type: HandlerType.OnNameLookup,\n required: true,\n validator: (snapExport: unknown): snapExport is OnNameLookupHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnInstall]: {\n type: HandlerType.OnInstall,\n required: false,\n validator: (snapExport: unknown): snapExport is OnInstallHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnUpdate]: {\n type: HandlerType.OnUpdate,\n required: false,\n validator: (snapExport: unknown): snapExport is OnUpdateHandler => {\n return typeof snapExport === 'function';\n },\n },\n} as const;\n\n/**\n * The `onRpcRequest` handler. This is called whenever a JSON-RPC request is\n * made to the snap.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of another\n * snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n * @returns The JSON-RPC response. This must be a JSON-serializable value.\n */\nexport type OnRpcRequestHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n }) => Promise<unknown>;\n\n/**\n * Enum used to specify the severity level of content being returned from a transaction insight.\n */\nexport enum SeverityLevel {\n Critical = 'critical',\n}\n\n/**\n * The response from a snap's `onTransaction` handler.\n *\n * @property content - A custom UI component, that will be shown in MetaMask. Can be created using `@metamask/snaps-ui`.\n *\n * If the snap has no insights about the transaction, this should be `null`.\n */\nexport type OnTransactionResponse = {\n content: Component | null;\n severity?: EnumToUnion<SeverityLevel>;\n};\n\n/**\n * The `onTransaction` handler. This is called whenever a transaction is\n * submitted to the snap. It can return insights about the transaction, which\n * will be displayed to the user.\n *\n * @param args - The request arguments.\n * @param args.transaction - The transaction object.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.transactionOrigin - The origin of the transaction. This is the\n * URL of the dapp that submitted the transaction.\n * @returns Insights about the transaction. See {@link OnTransactionResponse}.\n */\n// TODO: Improve type.\nexport type OnTransactionHandler = (args: {\n transaction: { [key: string]: Json };\n chainId: string;\n transactionOrigin?: string;\n}) => Promise<OnTransactionResponse>;\n\n/**\n * The `onCronjob` handler. This is called on a regular interval, as defined by\n * the snap's manifest.\n *\n * @param args - The request arguments.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnCronjobHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: { request: JsonRpcRequest<Params> }) => Promise<unknown>;\n\n/**\n * A handler that can be used for the lifecycle hooks.\n */\nexport type LifecycleEventHandler = (args: {\n request: JsonRpcRequest;\n}) => Promise<unknown>;\n\n/**\n * The `onInstall` handler. This is called after the snap is installed.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnInstallHandler = LifecycleEventHandler;\n\n/**\n * The `onUpdate` handler. This is called after the snap is updated.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnUpdateHandler = LifecycleEventHandler;\n\n/**\n * Utility type for getting the handler function type from a handler type.\n */\nexport type HandlerFunction<Type extends SnapHandler> =\n Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler\n ? Handler\n : never;\n\n/**\n * The response from a snap's `onNameLookup` handler.\n *\n * @property resolvedAddress - The resolved address for a given domain.\n * @property resolvedDomain - The resolved domain for a given address.\n *\n *\n * If the snap has no resolved address/domain from its lookup, this should be `null`.\n */\nexport type OnNameLookupResponse =\n | {\n resolvedAddress: AccountAddress;\n resolvedDomain?: never;\n }\n | { resolvedDomain: string; resolvedAddress?: never }\n | null;\n\nexport type OnNameLookupArgs = {\n chainId: Caip2ChainId;\n} & ({ domain: string; address?: never } | { address: string; domain?: never });\n\n/**\n * The `onNameLookup` handler. This is called whenever content is entered\n * into the send to field for sending assets to an EOA address.\n *\n * @param args - The request arguments.\n * @param args.domain - The human-readable address that is to be resolved.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.address - The address that is to be resolved.\n * @returns Resolved address/domain from the lookup. See {@link OnNameLookupResponse}.\n */\nexport type OnNameLookupHandler = (\n args: OnNameLookupArgs,\n) => Promise<OnNameLookupResponse>;\n\n/**\n * All the function-based handlers that a snap can implement.\n */\nexport type SnapFunctionExports = {\n [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<\n typeof SNAP_EXPORTS[Key]\n >;\n};\n\n/**\n * All handlers that a snap can implement.\n */\nexport type SnapExports = SnapFunctionExports;\n"],"names":["SNAP_EXPORTS","HandlerType","OnRpcRequest","OnTransaction","OnCronjob","OnInstall","OnUpdate","OnNameLookup","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":";;;;;;;;;;;;;;;;;IAuCaA,YAAY;eAAZA;;;IAjCN;UAAKC,WAAW;IAAXA,YACVC,kBAAe;IADLD,YAEVE,mBAAgB;IAFNF,YAGVG,eAAY;IAHFH,YAIVI,eAAY;IAJFJ,YAKVK,cAAW;IALDL,YAMVM,kBAAe;GANLN,gBAAAA;AAiCL,MAAMD,eAAe;IAC1B,CAACC,YAAYC,YAAY,CAAC,EAAE;QAC1BM,MAAMP,YAAYC,YAAY;QAC9BO,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACV,YAAYE,aAAa,CAAC,EAAE;QAC3BK,MAAMP,YAAYE,aAAa;QAC/BM,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACV,YAAYG,SAAS,CAAC,EAAE;QACvBI,MAAMP,YAAYG,SAAS;QAC3BK,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACV,YAAYM,YAAY,CAAC,EAAE;QAC1BC,MAAMP,YAAYM,YAAY;QAC9BE,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACV,YAAYI,SAAS,CAAC,EAAE;QACvBG,MAAMP,YAAYI,SAAS;QAC3BI,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACV,YAAYK,QAAQ,CAAC,EAAE;QACtBE,MAAMP,YAAYK,QAAQ;QAC1BG,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;AACF;IAqBO;UAAKC,aAAa;IAAbA,cACVC,cAAW;GADDD,kBAAAA"}
1
+ {"version":3,"sources":["../../src/handlers.ts"],"sourcesContent":["import type { Component } from '@metamask/snaps-ui';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport type { EnumToUnion } from './enum';\nimport type { AccountAddress, Caip2ChainId } from './namespace';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\n OnNameLookup = 'onNameLookup',\n OnKeyringRequest = 'onKeyringRequest',\n}\n\ntype SnapHandler = {\n /**\n * The type of handler.\n */\n type: HandlerType;\n\n /**\n * Whether the handler is required, i.e., whether the request will fail if the\n * handler is called, but the snap does not export it.\n *\n * This is primarily used for the lifecycle handlers, which are optional.\n */\n required: boolean;\n\n /**\n * Validate the given snap export. This should return a type guard for the\n * handler type.\n *\n * @param snapExport - The export to validate.\n * @returns Whether the export is valid.\n */\n validator: (snapExport: unknown) => boolean;\n};\n\nexport const SNAP_EXPORTS = {\n [HandlerType.OnRpcRequest]: {\n type: HandlerType.OnRpcRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnRpcRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnTransaction]: {\n type: HandlerType.OnTransaction,\n required: true,\n validator: (snapExport: unknown): snapExport is OnTransactionHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnCronjob]: {\n type: HandlerType.OnCronjob,\n required: true,\n validator: (snapExport: unknown): snapExport is OnCronjobHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnNameLookup]: {\n type: HandlerType.OnNameLookup,\n required: true,\n validator: (snapExport: unknown): snapExport is OnNameLookupHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnInstall]: {\n type: HandlerType.OnInstall,\n required: false,\n validator: (snapExport: unknown): snapExport is OnInstallHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnUpdate]: {\n type: HandlerType.OnUpdate,\n required: false,\n validator: (snapExport: unknown): snapExport is OnUpdateHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnKeyringRequest]: {\n type: HandlerType.OnKeyringRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnKeyringRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n} as const;\n\n/**\n * The `onRpcRequest` handler. This is called whenever a JSON-RPC request is\n * made to the snap.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of another\n * snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n * @returns The JSON-RPC response. This must be a JSON-serializable value.\n */\nexport type OnRpcRequestHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n }) => Promise<unknown>;\n\n/**\n * Enum used to specify the severity level of content being returned from a transaction insight.\n */\nexport enum SeverityLevel {\n Critical = 'critical',\n}\n\n/**\n * The response from a snap's `onTransaction` handler.\n *\n * @property content - A custom UI component, that will be shown in MetaMask. Can be created using `@metamask/snaps-ui`.\n *\n * If the snap has no insights about the transaction, this should be `null`.\n */\nexport type OnTransactionResponse = {\n content: Component | null;\n severity?: EnumToUnion<SeverityLevel>;\n};\n\n/**\n * The `onTransaction` handler. This is called whenever a transaction is\n * submitted to the snap. It can return insights about the transaction, which\n * will be displayed to the user.\n *\n * @param args - The request arguments.\n * @param args.transaction - The transaction object.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.transactionOrigin - The origin of the transaction. This is the\n * URL of the dapp that submitted the transaction.\n * @returns Insights about the transaction. See {@link OnTransactionResponse}.\n */\n// TODO: Improve type.\nexport type OnTransactionHandler = (args: {\n transaction: { [key: string]: Json };\n chainId: string;\n transactionOrigin?: string;\n}) => Promise<OnTransactionResponse>;\n\n/**\n * The `onCronjob` handler. This is called on a regular interval, as defined by\n * the snap's manifest.\n *\n * @param args - The request arguments.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnCronjobHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: { request: JsonRpcRequest<Params> }) => Promise<unknown>;\n\n/**\n * A handler that can be used for the lifecycle hooks.\n */\nexport type LifecycleEventHandler = (args: {\n request: JsonRpcRequest;\n}) => Promise<unknown>;\n\n/**\n * The `onInstall` handler. This is called after the snap is installed.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnInstallHandler = LifecycleEventHandler;\n\n/**\n * The `onUpdate` handler. This is called after the snap is updated.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnUpdateHandler = LifecycleEventHandler;\n\n/**\n * The `onKeyringRequest` handler. This is called by the MetaMask client for\n * privileged keyring actions.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of\n * another snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnKeyringRequestHandler<\n Params extends JsonRpcParams = JsonRpcParams,\n> = (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n}) => Promise<unknown>;\n\n/**\n * Utility type for getting the handler function type from a handler type.\n */\nexport type HandlerFunction<Type extends SnapHandler> =\n Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler\n ? Handler\n : never;\n\n/**\n * The response from a snap's `onNameLookup` handler.\n *\n * @property resolvedAddress - The resolved address for a given domain.\n * @property resolvedDomain - The resolved domain for a given address.\n *\n *\n * If the snap has no resolved address/domain from its lookup, this should be `null`.\n */\nexport type OnNameLookupResponse =\n | {\n resolvedAddress: AccountAddress;\n resolvedDomain?: never;\n }\n | { resolvedDomain: string; resolvedAddress?: never }\n | null;\n\nexport type OnNameLookupArgs = {\n chainId: Caip2ChainId;\n} & ({ domain: string; address?: never } | { address: string; domain?: never });\n\n/**\n * The `onNameLookup` handler. This is called whenever content is entered\n * into the send to field for sending assets to an EOA address.\n *\n * @param args - The request arguments.\n * @param args.domain - The human-readable address that is to be resolved.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.address - The address that is to be resolved.\n * @returns Resolved address/domain from the lookup. See {@link OnNameLookupResponse}.\n */\nexport type OnNameLookupHandler = (\n args: OnNameLookupArgs,\n) => Promise<OnNameLookupResponse>;\n\n/**\n * All the function-based handlers that a snap can implement.\n */\nexport type SnapFunctionExports = {\n [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<\n (typeof SNAP_EXPORTS)[Key]\n >;\n};\n\n/**\n * All handlers that a snap can implement.\n */\nexport type SnapExports = SnapFunctionExports;\n"],"names":["SNAP_EXPORTS","HandlerType","OnRpcRequest","OnTransaction","OnCronjob","OnInstall","OnUpdate","OnNameLookup","OnKeyringRequest","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":";;;;;;;;;;;;;;;;;IAwCaA,YAAY;eAAZA;;;IAlCN;UAAKC,WAAW;IAAXA,YACVC,kBAAe;IADLD,YAEVE,mBAAgB;IAFNF,YAGVG,eAAY;IAHFH,YAIVI,eAAY;IAJFJ,YAKVK,cAAW;IALDL,YAMVM,kBAAe;IANLN,YAOVO,sBAAmB;GAPTP,gBAAAA;AAkCL,MAAMD,eAAe;IAC1B,CAACC,YAAYC,YAAY,CAAC,EAAE;QAC1BO,MAAMR,YAAYC,YAAY;QAC9BQ,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYE,aAAa,CAAC,EAAE;QAC3BM,MAAMR,YAAYE,aAAa;QAC/BO,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYG,SAAS,CAAC,EAAE;QACvBK,MAAMR,YAAYG,SAAS;QAC3BM,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYM,YAAY,CAAC,EAAE;QAC1BE,MAAMR,YAAYM,YAAY;QAC9BG,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYI,SAAS,CAAC,EAAE;QACvBI,MAAMR,YAAYI,SAAS;QAC3BK,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYK,QAAQ,CAAC,EAAE;QACtBG,MAAMR,YAAYK,QAAQ;QAC1BI,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYO,gBAAgB,CAAC,EAAE;QAC9BC,MAAMR,YAAYO,gBAAgB;QAClCE,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;AACF;IAqBO;UAAKC,aAAa;IAAbA,cACVC,cAAW;GADDD,kBAAAA"}
@@ -15,25 +15,60 @@ _export(exports, {
15
15
  assertIsRpcOrigins: function() {
16
16
  return assertIsRpcOrigins;
17
17
  },
18
+ KeyringOriginsStruct: function() {
19
+ return KeyringOriginsStruct;
20
+ },
21
+ assertIsKeyringOrigins: function() {
22
+ return assertIsKeyringOrigins;
23
+ },
24
+ isOriginAllowed: function() {
25
+ return isOriginAllowed;
26
+ },
18
27
  assertIsJsonRpcSuccess: function() {
19
28
  return assertIsJsonRpcSuccess;
20
29
  }
21
30
  });
31
+ const _permissioncontroller = require("@metamask/permission-controller");
22
32
  const _utils = require("@metamask/utils");
23
33
  const _superstruct = require("superstruct");
24
34
  const RpcOriginsStruct = (0, _superstruct.refine)((0, _superstruct.object)({
25
35
  dapps: (0, _superstruct.optional)((0, _superstruct.boolean)()),
26
- snaps: (0, _superstruct.optional)((0, _superstruct.boolean)())
36
+ snaps: (0, _superstruct.optional)((0, _superstruct.boolean)()),
37
+ allowedOrigins: (0, _superstruct.optional)((0, _superstruct.array)((0, _superstruct.string)()))
27
38
  }), 'RPC origins', (value)=>{
28
- if (!Object.values(value).some(Boolean)) {
29
- throw new Error('Must specify at least one JSON-RPC origin');
39
+ const hasOrigins = Boolean(value.snaps === true || value.dapps === true || value.allowedOrigins && value.allowedOrigins.length > 0);
40
+ if (hasOrigins) {
41
+ return true;
30
42
  }
31
- return true;
43
+ return 'Must specify at least one JSON-RPC origin.';
32
44
  });
33
45
  function assertIsRpcOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention
34
46
  ErrorWrapper) {
35
47
  (0, _utils.assertStruct)(value, RpcOriginsStruct, 'Invalid JSON-RPC origins', ErrorWrapper);
36
48
  }
49
+ const KeyringOriginsStruct = (0, _superstruct.object)({
50
+ allowedOrigins: (0, _superstruct.optional)((0, _superstruct.array)((0, _superstruct.string)()))
51
+ });
52
+ function assertIsKeyringOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention
53
+ ErrorWrapper) {
54
+ (0, _utils.assertStruct)(value, KeyringOriginsStruct, 'Invalid keyring origins', ErrorWrapper);
55
+ }
56
+ function isOriginAllowed(origins, subjectType, origin) {
57
+ // The MetaMask client is always allowed.
58
+ if (origin === 'metamask') {
59
+ return true;
60
+ }
61
+ // If the origin is in the `allowedOrigins` list, it is allowed.
62
+ if (origins.allowedOrigins?.includes(origin)) {
63
+ return true;
64
+ }
65
+ // If the origin is a website and `dapps` is true, it is allowed.
66
+ if (subjectType === _permissioncontroller.SubjectType.Website && origins.dapps) {
67
+ return true;
68
+ }
69
+ // If the origin is a snap and `snaps` is true, it is allowed.
70
+ return Boolean(subjectType === _permissioncontroller.SubjectType.Snap && origins.snaps);
71
+ }
37
72
  function assertIsJsonRpcSuccess(value) {
38
73
  if (!(0, _utils.isJsonRpcSuccess)(value)) {
39
74
  if ((0, _utils.isJsonRpcFailure)(value)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/json-rpc.ts"],"sourcesContent":["import type {\n Json,\n JsonRpcSuccess,\n AssertionErrorConstructor,\n} from '@metamask/utils';\nimport {\n isJsonRpcFailure,\n isJsonRpcSuccess,\n assertStruct,\n} from '@metamask/utils';\nimport type { Infer } from 'superstruct';\nimport { boolean, object, optional, refine } from 'superstruct';\n\nexport const RpcOriginsStruct = refine(\n object({\n dapps: optional(boolean()),\n snaps: optional(boolean()),\n }),\n 'RPC origins',\n (value) => {\n if (!Object.values(value).some(Boolean)) {\n throw new Error('Must specify at least one JSON-RPC origin');\n }\n\n return true;\n },\n);\n\nexport type RpcOrigins = Infer<typeof RpcOriginsStruct>;\n\n/**\n * Asserts that the given value is a valid {@link RpcOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link RpcOrigins} object.\n */\nexport function assertIsRpcOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is RpcOrigins {\n assertStruct(\n value,\n RpcOriginsStruct,\n 'Invalid JSON-RPC origins',\n ErrorWrapper,\n );\n}\n\n/**\n * Assert that the given value is a successful JSON-RPC response. If the value\n * is not a success response, an error is thrown. If the value is an JSON-RPC\n * error, the error message is included in the thrown error.\n *\n * @param value - The value to check.\n * @throws If the value is not a JSON-RPC success response.\n */\nexport function assertIsJsonRpcSuccess(\n value: unknown,\n): asserts value is JsonRpcSuccess<Json> {\n if (!isJsonRpcSuccess(value)) {\n if (isJsonRpcFailure(value)) {\n throw new Error(`JSON-RPC request failed: ${value.error.message}`);\n }\n\n throw new Error('Invalid JSON-RPC response.');\n }\n}\n"],"names":["RpcOriginsStruct","assertIsRpcOrigins","assertIsJsonRpcSuccess","refine","object","dapps","optional","boolean","snaps","value","Object","values","some","Boolean","Error","ErrorWrapper","assertStruct","isJsonRpcSuccess","isJsonRpcFailure","error","message"],"mappings":";;;;;;;;;;;IAaaA,gBAAgB;eAAhBA;;IAyBGC,kBAAkB;eAAlBA;;IAqBAC,sBAAsB;eAAtBA;;;uBAlDT;6BAE2C;AAE3C,MAAMF,mBAAmBG,IAAAA,mBAAM,EACpCC,IAAAA,mBAAM,EAAC;IACLC,OAAOC,IAAAA,qBAAQ,EAACC,IAAAA,oBAAO;IACvBC,OAAOF,IAAAA,qBAAQ,EAACC,IAAAA,oBAAO;AACzB,IACA,eACA,CAACE;IACC,IAAI,CAACC,OAAOC,MAAM,CAACF,OAAOG,IAAI,CAACC,UAAU;QACvC,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;AACT;AAaK,SAASb,mBACdQ,KAAc,EACd,gEAAgE;AAChEM,YAAwC;IAExCC,IAAAA,mBAAY,EACVP,OACAT,kBACA,4BACAe;AAEJ;AAUO,SAASb,uBACdO,KAAc;IAEd,IAAI,CAACQ,IAAAA,uBAAgB,EAACR,QAAQ;QAC5B,IAAIS,IAAAA,uBAAgB,EAACT,QAAQ;YAC3B,MAAM,IAAIK,MAAM,CAAC,yBAAyB,EAAEL,MAAMU,KAAK,CAACC,OAAO,CAAC,CAAC;QACnE;QAEA,MAAM,IAAIN,MAAM;IAClB;AACF"}
1
+ {"version":3,"sources":["../../src/json-rpc.ts"],"sourcesContent":["import { SubjectType } from '@metamask/permission-controller';\nimport type {\n AssertionErrorConstructor,\n Json,\n JsonRpcSuccess,\n} from '@metamask/utils';\nimport {\n assertStruct,\n isJsonRpcFailure,\n isJsonRpcSuccess,\n} from '@metamask/utils';\nimport type { Infer } from 'superstruct';\nimport { array, boolean, object, optional, refine, string } from 'superstruct';\n\nexport const RpcOriginsStruct = refine(\n object({\n dapps: optional(boolean()),\n snaps: optional(boolean()),\n allowedOrigins: optional(array(string())),\n }),\n 'RPC origins',\n (value) => {\n const hasOrigins = Boolean(\n value.snaps === true ||\n value.dapps === true ||\n (value.allowedOrigins && value.allowedOrigins.length > 0),\n );\n\n if (hasOrigins) {\n return true;\n }\n\n return 'Must specify at least one JSON-RPC origin.';\n },\n);\n\nexport type RpcOrigins = Infer<typeof RpcOriginsStruct>;\n\n/**\n * Asserts that the given value is a valid {@link RpcOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link RpcOrigins} object.\n */\nexport function assertIsRpcOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is RpcOrigins {\n assertStruct(\n value,\n RpcOriginsStruct,\n 'Invalid JSON-RPC origins',\n ErrorWrapper,\n );\n}\n\nexport const KeyringOriginsStruct = object({\n allowedOrigins: optional(array(string())),\n});\n\nexport type KeyringOrigins = Infer<typeof KeyringOriginsStruct>;\n\n/**\n * Assert that the given value is a valid {@link KeyringOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link KeyringOrigins} object.\n */\nexport function assertIsKeyringOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is KeyringOrigins {\n assertStruct(\n value,\n KeyringOriginsStruct,\n 'Invalid keyring origins',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given origin is allowed by the given JSON-RPC origins object.\n *\n * @param origins - The JSON-RPC origins object.\n * @param subjectType - The type of the origin.\n * @param origin - The origin to check.\n * @returns Whether the origin is allowed.\n */\nexport function isOriginAllowed(\n origins: RpcOrigins,\n subjectType: SubjectType,\n origin: string,\n) {\n // The MetaMask client is always allowed.\n if (origin === 'metamask') {\n return true;\n }\n\n // If the origin is in the `allowedOrigins` list, it is allowed.\n if (origins.allowedOrigins?.includes(origin)) {\n return true;\n }\n\n // If the origin is a website and `dapps` is true, it is allowed.\n if (subjectType === SubjectType.Website && origins.dapps) {\n return true;\n }\n\n // If the origin is a snap and `snaps` is true, it is allowed.\n return Boolean(subjectType === SubjectType.Snap && origins.snaps);\n}\n\n/**\n * Assert that the given value is a successful JSON-RPC response. If the value\n * is not a success response, an error is thrown. If the value is an JSON-RPC\n * error, the error message is included in the thrown error.\n *\n * @param value - The value to check.\n * @throws If the value is not a JSON-RPC success response.\n */\nexport function assertIsJsonRpcSuccess(\n value: unknown,\n): asserts value is JsonRpcSuccess<Json> {\n if (!isJsonRpcSuccess(value)) {\n if (isJsonRpcFailure(value)) {\n throw new Error(`JSON-RPC request failed: ${value.error.message}`);\n }\n\n throw new Error('Invalid JSON-RPC response.');\n }\n}\n"],"names":["RpcOriginsStruct","assertIsRpcOrigins","KeyringOriginsStruct","assertIsKeyringOrigins","isOriginAllowed","assertIsJsonRpcSuccess","refine","object","dapps","optional","boolean","snaps","allowedOrigins","array","string","value","hasOrigins","Boolean","length","ErrorWrapper","assertStruct","origins","subjectType","origin","includes","SubjectType","Website","Snap","isJsonRpcSuccess","isJsonRpcFailure","Error","error","message"],"mappings":";;;;;;;;;;;IAcaA,gBAAgB;eAAhBA;;IAgCGC,kBAAkB;eAAlBA;;IAaHC,oBAAoB;eAApBA;;IAcGC,sBAAsB;eAAtBA;;IAqBAC,eAAe;eAAfA;;IAgCAC,sBAAsB;eAAtBA;;;sCA9HY;uBAUrB;6BAE0D;AAE1D,MAAML,mBAAmBM,IAAAA,mBAAM,EACpCC,IAAAA,mBAAM,EAAC;IACLC,OAAOC,IAAAA,qBAAQ,EAACC,IAAAA,oBAAO;IACvBC,OAAOF,IAAAA,qBAAQ,EAACC,IAAAA,oBAAO;IACvBE,gBAAgBH,IAAAA,qBAAQ,EAACI,IAAAA,kBAAK,EAACC,IAAAA,mBAAM;AACvC,IACA,eACA,CAACC;IACC,MAAMC,aAAaC,QACjBF,MAAMJ,KAAK,KAAK,QACdI,MAAMP,KAAK,KAAK,QACfO,MAAMH,cAAc,IAAIG,MAAMH,cAAc,CAACM,MAAM,GAAG;IAG3D,IAAIF,YAAY;QACd,OAAO;IACT;IAEA,OAAO;AACT;AAaK,SAASf,mBACdc,KAAc,EACd,gEAAgE;AAChEI,YAAwC;IAExCC,IAAAA,mBAAY,EACVL,OACAf,kBACA,4BACAmB;AAEJ;AAEO,MAAMjB,uBAAuBK,IAAAA,mBAAM,EAAC;IACzCK,gBAAgBH,IAAAA,qBAAQ,EAACI,IAAAA,kBAAK,EAACC,IAAAA,mBAAM;AACvC;AAYO,SAASX,uBACdY,KAAc,EACd,gEAAgE;AAChEI,YAAwC;IAExCC,IAAAA,mBAAY,EACVL,OACAb,sBACA,2BACAiB;AAEJ;AAUO,SAASf,gBACdiB,OAAmB,EACnBC,WAAwB,EACxBC,MAAc;IAEd,yCAAyC;IACzC,IAAIA,WAAW,YAAY;QACzB,OAAO;IACT;IAEA,gEAAgE;IAChE,IAAIF,QAAQT,cAAc,EAAEY,SAASD,SAAS;QAC5C,OAAO;IACT;IAEA,iEAAiE;IACjE,IAAID,gBAAgBG,iCAAW,CAACC,OAAO,IAAIL,QAAQb,KAAK,EAAE;QACxD,OAAO;IACT;IAEA,8DAA8D;IAC9D,OAAOS,QAAQK,gBAAgBG,iCAAW,CAACE,IAAI,IAAIN,QAAQV,KAAK;AAClE;AAUO,SAASN,uBACdU,KAAc;IAEd,IAAI,CAACa,IAAAA,uBAAgB,EAACb,QAAQ;QAC5B,IAAIc,IAAAA,uBAAgB,EAACd,QAAQ;YAC3B,MAAM,IAAIe,MAAM,CAAC,yBAAyB,EAAEf,MAAMgB,KAAK,CAACC,OAAO,CAAC,CAAC;QACnE;QAEA,MAAM,IAAIF,MAAM;IAClB;AACF"}
@@ -124,7 +124,6 @@ const SnapIdsStruct = (0, _superstruct.refine)((0, _superstruct.record)(_snaps.S
124
124
  });
125
125
  const ChainIdsStruct = (0, _superstruct.array)(_namespace.ChainIdStruct);
126
126
  const PermissionsStruct = (0, _superstruct.type)({
127
- 'endowment:long-running': (0, _superstruct.optional)((0, _superstruct.object)({})),
128
127
  'endowment:network-access': (0, _superstruct.optional)((0, _superstruct.object)({})),
129
128
  'endowment:webassembly': (0, _superstruct.optional)((0, _superstruct.object)({})),
130
129
  'endowment:transaction-insight': (0, _superstruct.optional)((0, _superstruct.object)({
@@ -135,6 +134,7 @@ const PermissionsStruct = (0, _superstruct.type)({
135
134
  })),
136
135
  'endowment:rpc': (0, _superstruct.optional)(_jsonrpc.RpcOriginsStruct),
137
136
  'endowment:name-lookup': (0, _superstruct.optional)(ChainIdsStruct),
137
+ 'endowment:keyring': (0, _superstruct.optional)(_jsonrpc.KeyringOriginsStruct),
138
138
  snap_dialog: (0, _superstruct.optional)((0, _superstruct.object)({})),
139
139
  // TODO: Remove
140
140
  snap_confirm: (0, _superstruct.optional)((0, _superstruct.object)({})),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/manifest/validation.ts"],"sourcesContent":["import { isValidBIP32PathSegment } from '@metamask/key-tree';\nimport {\n assertStruct,\n ChecksumStruct,\n VersionStruct,\n isValidSemVerRange,\n} from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n enums,\n integer,\n is,\n literal,\n object,\n optional,\n pattern,\n refine,\n record,\n size,\n string,\n type,\n union,\n} from 'superstruct';\n\nimport { isEqual } from '../array';\nimport { CronjobSpecificationArrayStruct } from '../cronjob';\nimport { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';\nimport { RpcOriginsStruct } from '../json-rpc';\nimport { ChainIdStruct } from '../namespace';\nimport { SnapIdStruct } from '../snaps';\nimport { NameStruct, NpmSnapFileNames } from '../types';\n\n// BIP-43 purposes that cannot be used for entropy derivation. These are in the\n// string form, ending with `'`.\nconst FORBIDDEN_PURPOSES: string[] = [\n SIP_6_MAGIC_VALUE,\n STATE_ENCRYPTION_MAGIC_VALUE,\n];\n\nexport const FORBIDDEN_COIN_TYPES: number[] = [60];\nconst FORBIDDEN_PATHS: string[][] = FORBIDDEN_COIN_TYPES.map((coinType) => [\n 'm',\n \"44'\",\n `${coinType}'`,\n]);\n\nexport const Bip32PathStruct = refine(\n array(string()),\n 'BIP-32 path',\n (path: string[]) => {\n if (path.length === 0) {\n return 'Path must be a non-empty BIP-32 derivation path array';\n }\n\n if (path[0] !== 'm') {\n return 'Path must start with \"m\".';\n }\n\n if (path.length < 3) {\n return 'Paths must have a length of at least three.';\n }\n\n if (path.slice(1).some((part) => !isValidBIP32PathSegment(part))) {\n return 'Path must be a valid BIP-32 derivation path array.';\n }\n\n if (FORBIDDEN_PURPOSES.includes(path[1])) {\n return `The purpose \"${path[1]}\" is not allowed for entropy derivation.`;\n }\n\n if (\n FORBIDDEN_PATHS.some((forbiddenPath) =>\n isEqual(path.slice(0, forbiddenPath.length), forbiddenPath),\n )\n ) {\n return `The path \"${path.join(\n '/',\n )}\" is not allowed for entropy derivation.`;\n }\n\n return true;\n },\n);\n\nexport const bip32entropy = <\n Type extends { path: string[]; curve: string },\n Schema,\n>(\n struct: Struct<Type, Schema>,\n) =>\n refine(struct, 'BIP-32 entropy', (value) => {\n if (\n value.curve === 'ed25519' &&\n value.path.slice(1).some((part) => !part.endsWith(\"'\"))\n ) {\n return 'Ed25519 does not support unhardened paths.';\n }\n\n return true;\n });\n\n// Used outside @metamask/snap-utils\nexport const Bip32EntropyStruct = bip32entropy(\n type({\n path: Bip32PathStruct,\n curve: enums(['ed25519', 'secp256k1']),\n }),\n);\n\nexport type Bip32Entropy = Infer<typeof Bip32EntropyStruct>;\n\nexport const SnapGetBip32EntropyPermissionsStruct = size(\n array(Bip32EntropyStruct),\n 1,\n Infinity,\n);\n\nexport const SemVerRangeStruct = refine(string(), 'SemVer range', (value) => {\n if (isValidSemVerRange(value)) {\n return true;\n }\n return 'Expected a valid SemVer range.';\n});\n\nexport const SnapIdsStruct = refine(\n record(SnapIdStruct, object({ version: optional(SemVerRangeStruct) })),\n 'SnapIds',\n (value) => {\n if (Object.keys(value).length === 0) {\n return false;\n }\n\n return true;\n },\n);\n\nexport type SnapIds = Infer<typeof SnapIdsStruct>;\n\nexport const ChainIdsStruct = array(ChainIdStruct);\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport const PermissionsStruct = type({\n 'endowment:long-running': optional(object({})),\n 'endowment:network-access': optional(object({})),\n 'endowment:webassembly': optional(object({})),\n 'endowment:transaction-insight': optional(\n object({\n allowTransactionOrigin: optional(boolean()),\n }),\n ),\n 'endowment:cronjob': optional(\n object({ jobs: CronjobSpecificationArrayStruct }),\n ),\n 'endowment:rpc': optional(RpcOriginsStruct),\n 'endowment:name-lookup': optional(ChainIdsStruct),\n snap_dialog: optional(object({})),\n // TODO: Remove\n snap_confirm: optional(object({})),\n snap_manageState: optional(object({})),\n snap_manageAccounts: optional(object({})),\n snap_notify: optional(object({})),\n snap_getBip32Entropy: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip32PublicKey: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip44Entropy: optional(\n size(\n array(object({ coinType: size(integer(), 0, 2 ** 32 - 1) })),\n 1,\n Infinity,\n ),\n ),\n snap_getEntropy: optional(object({})),\n wallet_snap: optional(SnapIdsStruct),\n});\n/* eslint-enable @typescript-eslint/naming-convention */\n\nexport type SnapPermissions = Infer<typeof PermissionsStruct>;\n\nexport const SnapManifestStruct = object({\n version: VersionStruct,\n description: size(string(), 1, 280),\n proposedName: size(\n pattern(\n string(),\n /^(?:[A-Za-z0-9-_]+( [A-Za-z0-9-_]+)*)|(?:(?:@[A-Za-z0-9-*~][A-Za-z0-9-*._~]*\\/)?[A-Za-z0-9-~][A-Za-z0-9-._~]*)$/u,\n ),\n 1,\n 214,\n ),\n repository: optional(\n object({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n source: object({\n shasum: ChecksumStruct,\n location: object({\n npm: object({\n filePath: size(string(), 1, Infinity),\n iconPath: optional(size(string(), 1, Infinity)),\n packageName: NameStruct,\n registry: union([\n literal('https://registry.npmjs.org'),\n literal('https://registry.npmjs.org/'),\n ]),\n }),\n }),\n }),\n initialPermissions: PermissionsStruct,\n manifestVersion: literal('0.1'),\n $schema: optional(string()), // enables JSON-Schema linting in VSC and other IDEs\n});\n\nexport type SnapManifest = Infer<typeof SnapManifestStruct>;\n\n/**\n * Check if the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @returns Whether the value is a valid {@link SnapManifest} object.\n */\nexport function isSnapManifest(value: unknown): value is SnapManifest {\n return is(value, SnapManifestStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid {@link SnapManifest} object.\n */\nexport function assertIsSnapManifest(\n value: unknown,\n): asserts value is SnapManifest {\n assertStruct(\n value,\n SnapManifestStruct,\n `\"${NpmSnapFileNames.Manifest}\" is invalid`,\n );\n}\n\n/**\n * Creates a {@link SnapManifest} object from JSON.\n *\n * @param value - The value to check.\n * @throws If the value cannot be coerced to a {@link SnapManifest} object.\n * @returns The created {@link SnapManifest} object.\n */\nexport function createSnapManifest(value: unknown): SnapManifest {\n // TODO: Add a utility to prefix these errors similar to assertStruct\n return create(value, SnapManifestStruct);\n}\n"],"names":["FORBIDDEN_COIN_TYPES","Bip32PathStruct","bip32entropy","Bip32EntropyStruct","SnapGetBip32EntropyPermissionsStruct","SemVerRangeStruct","SnapIdsStruct","ChainIdsStruct","PermissionsStruct","SnapManifestStruct","isSnapManifest","assertIsSnapManifest","createSnapManifest","FORBIDDEN_PURPOSES","SIP_6_MAGIC_VALUE","STATE_ENCRYPTION_MAGIC_VALUE","FORBIDDEN_PATHS","map","coinType","refine","array","string","path","length","slice","some","part","isValidBIP32PathSegment","includes","forbiddenPath","isEqual","join","struct","value","curve","endsWith","type","enums","size","Infinity","isValidSemVerRange","record","SnapIdStruct","object","version","optional","Object","keys","ChainIdStruct","allowTransactionOrigin","boolean","jobs","CronjobSpecificationArrayStruct","RpcOriginsStruct","snap_dialog","snap_confirm","snap_manageState","snap_manageAccounts","snap_notify","snap_getBip32Entropy","snap_getBip32PublicKey","snap_getBip44Entropy","integer","snap_getEntropy","wallet_snap","VersionStruct","description","proposedName","pattern","repository","url","source","shasum","ChecksumStruct","location","npm","filePath","iconPath","packageName","NameStruct","registry","union","literal","initialPermissions","manifestVersion","$schema","is","assertStruct","NpmSnapFileNames","Manifest","create"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/manifest/validation.ts"],"sourcesContent":["import { isValidBIP32PathSegment } from '@metamask/key-tree';\nimport {\n assertStruct,\n ChecksumStruct,\n VersionStruct,\n isValidSemVerRange,\n} from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n enums,\n integer,\n is,\n literal,\n object,\n optional,\n pattern,\n refine,\n record,\n size,\n string,\n type,\n union,\n} from 'superstruct';\n\nimport { isEqual } from '../array';\nimport { CronjobSpecificationArrayStruct } from '../cronjob';\nimport { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';\nimport { KeyringOriginsStruct, RpcOriginsStruct } from '../json-rpc';\nimport { ChainIdStruct } from '../namespace';\nimport { SnapIdStruct } from '../snaps';\nimport { NameStruct, NpmSnapFileNames } from '../types';\n\n// BIP-43 purposes that cannot be used for entropy derivation. These are in the\n// string form, ending with `'`.\nconst FORBIDDEN_PURPOSES: string[] = [\n SIP_6_MAGIC_VALUE,\n STATE_ENCRYPTION_MAGIC_VALUE,\n];\n\nexport const FORBIDDEN_COIN_TYPES: number[] = [60];\nconst FORBIDDEN_PATHS: string[][] = FORBIDDEN_COIN_TYPES.map((coinType) => [\n 'm',\n \"44'\",\n `${coinType}'`,\n]);\n\nexport const Bip32PathStruct = refine(\n array(string()),\n 'BIP-32 path',\n (path: string[]) => {\n if (path.length === 0) {\n return 'Path must be a non-empty BIP-32 derivation path array';\n }\n\n if (path[0] !== 'm') {\n return 'Path must start with \"m\".';\n }\n\n if (path.length < 3) {\n return 'Paths must have a length of at least three.';\n }\n\n if (path.slice(1).some((part) => !isValidBIP32PathSegment(part))) {\n return 'Path must be a valid BIP-32 derivation path array.';\n }\n\n if (FORBIDDEN_PURPOSES.includes(path[1])) {\n return `The purpose \"${path[1]}\" is not allowed for entropy derivation.`;\n }\n\n if (\n FORBIDDEN_PATHS.some((forbiddenPath) =>\n isEqual(path.slice(0, forbiddenPath.length), forbiddenPath),\n )\n ) {\n return `The path \"${path.join(\n '/',\n )}\" is not allowed for entropy derivation.`;\n }\n\n return true;\n },\n);\n\nexport const bip32entropy = <\n Type extends { path: string[]; curve: string },\n Schema,\n>(\n struct: Struct<Type, Schema>,\n) =>\n refine(struct, 'BIP-32 entropy', (value) => {\n if (\n value.curve === 'ed25519' &&\n value.path.slice(1).some((part) => !part.endsWith(\"'\"))\n ) {\n return 'Ed25519 does not support unhardened paths.';\n }\n\n return true;\n });\n\n// Used outside @metamask/snap-utils\nexport const Bip32EntropyStruct = bip32entropy(\n type({\n path: Bip32PathStruct,\n curve: enums(['ed25519', 'secp256k1']),\n }),\n);\n\nexport type Bip32Entropy = Infer<typeof Bip32EntropyStruct>;\n\nexport const SnapGetBip32EntropyPermissionsStruct = size(\n array(Bip32EntropyStruct),\n 1,\n Infinity,\n);\n\nexport const SemVerRangeStruct = refine(string(), 'SemVer range', (value) => {\n if (isValidSemVerRange(value)) {\n return true;\n }\n return 'Expected a valid SemVer range.';\n});\n\nexport const SnapIdsStruct = refine(\n record(SnapIdStruct, object({ version: optional(SemVerRangeStruct) })),\n 'SnapIds',\n (value) => {\n if (Object.keys(value).length === 0) {\n return false;\n }\n\n return true;\n },\n);\n\nexport type SnapIds = Infer<typeof SnapIdsStruct>;\n\nexport const ChainIdsStruct = array(ChainIdStruct);\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport const PermissionsStruct = type({\n 'endowment:network-access': optional(object({})),\n 'endowment:webassembly': optional(object({})),\n 'endowment:transaction-insight': optional(\n object({\n allowTransactionOrigin: optional(boolean()),\n }),\n ),\n 'endowment:cronjob': optional(\n object({ jobs: CronjobSpecificationArrayStruct }),\n ),\n 'endowment:rpc': optional(RpcOriginsStruct),\n 'endowment:name-lookup': optional(ChainIdsStruct),\n 'endowment:keyring': optional(KeyringOriginsStruct),\n snap_dialog: optional(object({})),\n // TODO: Remove\n snap_confirm: optional(object({})),\n snap_manageState: optional(object({})),\n snap_manageAccounts: optional(object({})),\n snap_notify: optional(object({})),\n snap_getBip32Entropy: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip32PublicKey: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip44Entropy: optional(\n size(\n array(object({ coinType: size(integer(), 0, 2 ** 32 - 1) })),\n 1,\n Infinity,\n ),\n ),\n snap_getEntropy: optional(object({})),\n wallet_snap: optional(SnapIdsStruct),\n});\n/* eslint-enable @typescript-eslint/naming-convention */\n\nexport type SnapPermissions = Infer<typeof PermissionsStruct>;\n\nexport const SnapManifestStruct = object({\n version: VersionStruct,\n description: size(string(), 1, 280),\n proposedName: size(\n pattern(\n string(),\n /^(?:[A-Za-z0-9-_]+( [A-Za-z0-9-_]+)*)|(?:(?:@[A-Za-z0-9-*~][A-Za-z0-9-*._~]*\\/)?[A-Za-z0-9-~][A-Za-z0-9-._~]*)$/u,\n ),\n 1,\n 214,\n ),\n repository: optional(\n object({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n source: object({\n shasum: ChecksumStruct,\n location: object({\n npm: object({\n filePath: size(string(), 1, Infinity),\n iconPath: optional(size(string(), 1, Infinity)),\n packageName: NameStruct,\n registry: union([\n literal('https://registry.npmjs.org'),\n literal('https://registry.npmjs.org/'),\n ]),\n }),\n }),\n }),\n initialPermissions: PermissionsStruct,\n manifestVersion: literal('0.1'),\n $schema: optional(string()), // enables JSON-Schema linting in VSC and other IDEs\n});\n\nexport type SnapManifest = Infer<typeof SnapManifestStruct>;\n\n/**\n * Check if the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @returns Whether the value is a valid {@link SnapManifest} object.\n */\nexport function isSnapManifest(value: unknown): value is SnapManifest {\n return is(value, SnapManifestStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid {@link SnapManifest} object.\n */\nexport function assertIsSnapManifest(\n value: unknown,\n): asserts value is SnapManifest {\n assertStruct(\n value,\n SnapManifestStruct,\n `\"${NpmSnapFileNames.Manifest}\" is invalid`,\n );\n}\n\n/**\n * Creates a {@link SnapManifest} object from JSON.\n *\n * @param value - The value to check.\n * @throws If the value cannot be coerced to a {@link SnapManifest} object.\n * @returns The created {@link SnapManifest} object.\n */\nexport function createSnapManifest(value: unknown): SnapManifest {\n // TODO: Add a utility to prefix these errors similar to assertStruct\n return create(value, SnapManifestStruct);\n}\n"],"names":["FORBIDDEN_COIN_TYPES","Bip32PathStruct","bip32entropy","Bip32EntropyStruct","SnapGetBip32EntropyPermissionsStruct","SemVerRangeStruct","SnapIdsStruct","ChainIdsStruct","PermissionsStruct","SnapManifestStruct","isSnapManifest","assertIsSnapManifest","createSnapManifest","FORBIDDEN_PURPOSES","SIP_6_MAGIC_VALUE","STATE_ENCRYPTION_MAGIC_VALUE","FORBIDDEN_PATHS","map","coinType","refine","array","string","path","length","slice","some","part","isValidBIP32PathSegment","includes","forbiddenPath","isEqual","join","struct","value","curve","endsWith","type","enums","size","Infinity","isValidSemVerRange","record","SnapIdStruct","object","version","optional","Object","keys","ChainIdStruct","allowTransactionOrigin","boolean","jobs","CronjobSpecificationArrayStruct","RpcOriginsStruct","KeyringOriginsStruct","snap_dialog","snap_confirm","snap_manageState","snap_manageAccounts","snap_notify","snap_getBip32Entropy","snap_getBip32PublicKey","snap_getBip44Entropy","integer","snap_getEntropy","wallet_snap","VersionStruct","description","proposedName","pattern","repository","url","source","shasum","ChecksumStruct","location","npm","filePath","iconPath","packageName","NameStruct","registry","union","literal","initialPermissions","manifestVersion","$schema","is","assertStruct","NpmSnapFileNames","Manifest","create"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/virtual-file/toVirtualFile.ts"],"sourcesContent":["import { promises as fsPromises } from 'fs';\n\nimport { VirtualFile } from './VirtualFile';\n\n/**\n * Reads a file from filesystem and creates a vfile.\n *\n * @param path - Filesystem path to load the contents from.\n * @param encoding - Optional encoding to pass down to fs.readFile.\n * @returns Promise returning VFile with loaded file contents.\n */\nexport async function readVirtualFile(\n path: string,\n encoding: BufferEncoding | null = null,\n) {\n return new VirtualFile({\n path,\n value: await fsPromises.readFile(path, { encoding }),\n });\n}\n\ntype WriteVFileOptions = Exclude<\n Parameters<typeof fsPromises['writeFile']>[2],\n undefined\n>;\n\n/**\n * Writes vfile to filesystem.\n *\n * @param vfile - The vfile to write.\n * @param options - Options to pass down to fs.writeFile.\n */\nexport async function writeVirtualFile(\n vfile: VirtualFile,\n options?: WriteVFileOptions,\n) {\n return fsPromises.writeFile(vfile.path, vfile.value, options);\n}\n"],"names":["readVirtualFile","writeVirtualFile","path","encoding","VirtualFile","value","fsPromises","readFile","vfile","options","writeFile"],"mappings":";;;;;;;;;;;IAWsBA,eAAe;eAAfA;;IAqBAC,gBAAgB;eAAhBA;;;oBAhCiB;6BAEX;AASrB,eAAeD,gBACpBE,IAAY,EACZC,WAAkC,IAAI;IAEtC,OAAO,IAAIC,wBAAW,CAAC;QACrBF;QACAG,OAAO,MAAMC,YAAU,CAACC,QAAQ,CAACL,MAAM;YAAEC;QAAS;IACpD;AACF;AAaO,eAAeF,iBACpBO,KAAkB,EAClBC,OAA2B;IAE3B,OAAOH,YAAU,CAACI,SAAS,CAACF,MAAMN,IAAI,EAAEM,MAAMH,KAAK,EAAEI;AACvD"}
1
+ {"version":3,"sources":["../../../src/virtual-file/toVirtualFile.ts"],"sourcesContent":["import { promises as fsPromises } from 'fs';\n\nimport { VirtualFile } from './VirtualFile';\n\n/**\n * Reads a file from filesystem and creates a vfile.\n *\n * @param path - Filesystem path to load the contents from.\n * @param encoding - Optional encoding to pass down to fs.readFile.\n * @returns Promise returning VFile with loaded file contents.\n */\nexport async function readVirtualFile(\n path: string,\n encoding: BufferEncoding | null = null,\n) {\n return new VirtualFile({\n path,\n value: await fsPromises.readFile(path, { encoding }),\n });\n}\n\ntype WriteVFileOptions = Exclude<\n Parameters<(typeof fsPromises)['writeFile']>[2],\n undefined\n>;\n\n/**\n * Writes vfile to filesystem.\n *\n * @param vfile - The vfile to write.\n * @param options - Options to pass down to fs.writeFile.\n */\nexport async function writeVirtualFile(\n vfile: VirtualFile,\n options?: WriteVFileOptions,\n) {\n return fsPromises.writeFile(vfile.path, vfile.value, options);\n}\n"],"names":["readVirtualFile","writeVirtualFile","path","encoding","VirtualFile","value","fsPromises","readFile","vfile","options","writeFile"],"mappings":";;;;;;;;;;;IAWsBA,eAAe;eAAfA;;IAqBAC,gBAAgB;eAAhBA;;;oBAhCiB;6BAEX;AASrB,eAAeD,gBACpBE,IAAY,EACZC,WAAkC,IAAI;IAEtC,OAAO,IAAIC,wBAAW,CAAC;QACrBF;QACAG,OAAO,MAAMC,YAAU,CAACC,QAAQ,CAACL,MAAM;YAAEC;QAAS;IACpD;AACF;AAaO,eAAeF,iBACpBO,KAAkB,EAClBC,OAA2B;IAE3B,OAAOH,YAAU,CAACI,SAAS,CAACF,MAAMN,IAAI,EAAEM,MAAMH,KAAK,EAAEI;AACvD"}
@@ -16,6 +16,9 @@ export var SnapCaveatType;
16
16
  * The origins that a Snap can receive JSON-RPC messages from.
17
17
  */ "RpcOrigin"] = 'rpcOrigin';
18
18
  SnapCaveatType[/**
19
+ * The origins that a Snap can receive keyring messages from.
20
+ */ "KeyringOrigin"] = 'keyringOrigin';
21
+ SnapCaveatType[/**
19
22
  * Caveat specifying the snap IDs that can be interacted with.
20
23
  */ "SnapIds"] = 'snapIds';
21
24
  SnapCaveatType[/**
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/caveats.ts"],"sourcesContent":["export enum SnapCaveatType {\n /**\n * Permitted derivation paths, used by `snap_getBip32Entropy`.\n */\n PermittedDerivationPaths = 'permittedDerivationPaths',\n\n /**\n * Permitted coin types, used by `snap_getBip44Entropy`.\n */\n PermittedCoinTypes = 'permittedCoinTypes',\n\n /**\n * Caveat specifying a snap cronjob.\n */\n SnapCronjob = 'snapCronjob',\n\n /**\n * Caveat specifying access to the transaction origin, used by `endowment:transaction-insight`.\n */\n TransactionOrigin = 'transactionOrigin',\n\n /**\n * The origins that a Snap can receive JSON-RPC messages from.\n */\n RpcOrigin = 'rpcOrigin',\n\n /**\n * Caveat specifying the snap IDs that can be interacted with.\n */\n SnapIds = 'snapIds',\n\n /**\n * Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.\n */\n ChainIds = 'chainIds',\n}\n"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","SnapIds","ChainIds"],"mappings":"WAAO;UAAKA,cAAc;IAAdA,eACV;;GAEC,GACDC,8BAA2B;IAJjBD,eAMV;;GAEC,GACDE,wBAAqB;IATXF,eAWV;;GAEC,GACDG,iBAAc;IAdJH,eAgBV;;GAEC,GACDI,uBAAoB;IAnBVJ,eAqBV;;GAEC,GACDK,eAAY;IAxBFL,eA0BV;;GAEC,GACDM,aAAU;IA7BAN,eA+BV;;GAEC,GACDO,cAAW;GAlCDP,mBAAAA"}
1
+ {"version":3,"sources":["../../src/caveats.ts"],"sourcesContent":["export enum SnapCaveatType {\n /**\n * Permitted derivation paths, used by `snap_getBip32Entropy`.\n */\n PermittedDerivationPaths = 'permittedDerivationPaths',\n\n /**\n * Permitted coin types, used by `snap_getBip44Entropy`.\n */\n PermittedCoinTypes = 'permittedCoinTypes',\n\n /**\n * Caveat specifying a snap cronjob.\n */\n SnapCronjob = 'snapCronjob',\n\n /**\n * Caveat specifying access to the transaction origin, used by `endowment:transaction-insight`.\n */\n TransactionOrigin = 'transactionOrigin',\n\n /**\n * The origins that a Snap can receive JSON-RPC messages from.\n */\n RpcOrigin = 'rpcOrigin',\n\n /**\n * The origins that a Snap can receive keyring messages from.\n */\n KeyringOrigin = 'keyringOrigin',\n\n /**\n * Caveat specifying the snap IDs that can be interacted with.\n */\n SnapIds = 'snapIds',\n\n /**\n * Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.\n */\n ChainIds = 'chainIds',\n}\n"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","KeyringOrigin","SnapIds","ChainIds"],"mappings":"WAAO;UAAKA,cAAc;IAAdA,eACV;;GAEC,GACDC,8BAA2B;IAJjBD,eAMV;;GAEC,GACDE,wBAAqB;IATXF,eAWV;;GAEC,GACDG,iBAAc;IAdJH,eAgBV;;GAEC,GACDI,uBAAoB;IAnBVJ,eAqBV;;GAEC,GACDK,eAAY;IAxBFL,eA0BV;;GAEC,GACDM,mBAAgB;IA7BNN,eA+BV;;GAEC,GACDO,aAAU;IAlCAP,eAoCV;;GAEC,GACDQ,cAAW;GAvCDR,mBAAAA"}
@@ -6,6 +6,7 @@ export var HandlerType;
6
6
  HandlerType["OnInstall"] = 'onInstall';
7
7
  HandlerType["OnUpdate"] = 'onUpdate';
8
8
  HandlerType["OnNameLookup"] = 'onNameLookup';
9
+ HandlerType["OnKeyringRequest"] = 'onKeyringRequest';
9
10
  })(HandlerType || (HandlerType = {}));
10
11
  export const SNAP_EXPORTS = {
11
12
  [HandlerType.OnRpcRequest]: {
@@ -49,6 +50,13 @@ export const SNAP_EXPORTS = {
49
50
  validator: (snapExport)=>{
50
51
  return typeof snapExport === 'function';
51
52
  }
53
+ },
54
+ [HandlerType.OnKeyringRequest]: {
55
+ type: HandlerType.OnKeyringRequest,
56
+ required: true,
57
+ validator: (snapExport)=>{
58
+ return typeof snapExport === 'function';
59
+ }
52
60
  }
53
61
  };
54
62
  export var SeverityLevel;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/handlers.ts"],"sourcesContent":["import type { Component } from '@metamask/snaps-ui';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport type { EnumToUnion } from './enum';\nimport type { AccountAddress, Caip2ChainId } from './namespace';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\n OnNameLookup = 'onNameLookup',\n}\n\ntype SnapHandler = {\n /**\n * The type of handler.\n */\n type: HandlerType;\n\n /**\n * Whether the handler is required, i.e., whether the request will fail if the\n * handler is called, but the snap does not export it.\n *\n * This is primarily used for the lifecycle handlers, which are optional.\n */\n required: boolean;\n\n /**\n * Validate the given snap export. This should return a type guard for the\n * handler type.\n *\n * @param snapExport - The export to validate.\n * @returns Whether the export is valid.\n */\n validator: (snapExport: unknown) => boolean;\n};\n\nexport const SNAP_EXPORTS = {\n [HandlerType.OnRpcRequest]: {\n type: HandlerType.OnRpcRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnRpcRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnTransaction]: {\n type: HandlerType.OnTransaction,\n required: true,\n validator: (snapExport: unknown): snapExport is OnTransactionHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnCronjob]: {\n type: HandlerType.OnCronjob,\n required: true,\n validator: (snapExport: unknown): snapExport is OnCronjobHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnNameLookup]: {\n type: HandlerType.OnNameLookup,\n required: true,\n validator: (snapExport: unknown): snapExport is OnNameLookupHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnInstall]: {\n type: HandlerType.OnInstall,\n required: false,\n validator: (snapExport: unknown): snapExport is OnInstallHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnUpdate]: {\n type: HandlerType.OnUpdate,\n required: false,\n validator: (snapExport: unknown): snapExport is OnUpdateHandler => {\n return typeof snapExport === 'function';\n },\n },\n} as const;\n\n/**\n * The `onRpcRequest` handler. This is called whenever a JSON-RPC request is\n * made to the snap.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of another\n * snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n * @returns The JSON-RPC response. This must be a JSON-serializable value.\n */\nexport type OnRpcRequestHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n }) => Promise<unknown>;\n\n/**\n * Enum used to specify the severity level of content being returned from a transaction insight.\n */\nexport enum SeverityLevel {\n Critical = 'critical',\n}\n\n/**\n * The response from a snap's `onTransaction` handler.\n *\n * @property content - A custom UI component, that will be shown in MetaMask. Can be created using `@metamask/snaps-ui`.\n *\n * If the snap has no insights about the transaction, this should be `null`.\n */\nexport type OnTransactionResponse = {\n content: Component | null;\n severity?: EnumToUnion<SeverityLevel>;\n};\n\n/**\n * The `onTransaction` handler. This is called whenever a transaction is\n * submitted to the snap. It can return insights about the transaction, which\n * will be displayed to the user.\n *\n * @param args - The request arguments.\n * @param args.transaction - The transaction object.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.transactionOrigin - The origin of the transaction. This is the\n * URL of the dapp that submitted the transaction.\n * @returns Insights about the transaction. See {@link OnTransactionResponse}.\n */\n// TODO: Improve type.\nexport type OnTransactionHandler = (args: {\n transaction: { [key: string]: Json };\n chainId: string;\n transactionOrigin?: string;\n}) => Promise<OnTransactionResponse>;\n\n/**\n * The `onCronjob` handler. This is called on a regular interval, as defined by\n * the snap's manifest.\n *\n * @param args - The request arguments.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnCronjobHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: { request: JsonRpcRequest<Params> }) => Promise<unknown>;\n\n/**\n * A handler that can be used for the lifecycle hooks.\n */\nexport type LifecycleEventHandler = (args: {\n request: JsonRpcRequest;\n}) => Promise<unknown>;\n\n/**\n * The `onInstall` handler. This is called after the snap is installed.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnInstallHandler = LifecycleEventHandler;\n\n/**\n * The `onUpdate` handler. This is called after the snap is updated.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnUpdateHandler = LifecycleEventHandler;\n\n/**\n * Utility type for getting the handler function type from a handler type.\n */\nexport type HandlerFunction<Type extends SnapHandler> =\n Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler\n ? Handler\n : never;\n\n/**\n * The response from a snap's `onNameLookup` handler.\n *\n * @property resolvedAddress - The resolved address for a given domain.\n * @property resolvedDomain - The resolved domain for a given address.\n *\n *\n * If the snap has no resolved address/domain from its lookup, this should be `null`.\n */\nexport type OnNameLookupResponse =\n | {\n resolvedAddress: AccountAddress;\n resolvedDomain?: never;\n }\n | { resolvedDomain: string; resolvedAddress?: never }\n | null;\n\nexport type OnNameLookupArgs = {\n chainId: Caip2ChainId;\n} & ({ domain: string; address?: never } | { address: string; domain?: never });\n\n/**\n * The `onNameLookup` handler. This is called whenever content is entered\n * into the send to field for sending assets to an EOA address.\n *\n * @param args - The request arguments.\n * @param args.domain - The human-readable address that is to be resolved.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.address - The address that is to be resolved.\n * @returns Resolved address/domain from the lookup. See {@link OnNameLookupResponse}.\n */\nexport type OnNameLookupHandler = (\n args: OnNameLookupArgs,\n) => Promise<OnNameLookupResponse>;\n\n/**\n * All the function-based handlers that a snap can implement.\n */\nexport type SnapFunctionExports = {\n [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<\n typeof SNAP_EXPORTS[Key]\n >;\n};\n\n/**\n * All handlers that a snap can implement.\n */\nexport type SnapExports = SnapFunctionExports;\n"],"names":["HandlerType","OnRpcRequest","OnTransaction","OnCronjob","OnInstall","OnUpdate","OnNameLookup","SNAP_EXPORTS","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":"WAMO;UAAKA,WAAW;IAAXA,YACVC,kBAAe;IADLD,YAEVE,mBAAgB;IAFNF,YAGVG,eAAY;IAHFH,YAIVI,eAAY;IAJFJ,YAKVK,cAAW;IALDL,YAMVM,kBAAe;GANLN,gBAAAA;AAiCZ,OAAO,MAAMO,eAAe;IAC1B,CAACP,YAAYC,YAAY,CAAC,EAAE;QAC1BO,MAAMR,YAAYC,YAAY;QAC9BQ,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYE,aAAa,CAAC,EAAE;QAC3BM,MAAMR,YAAYE,aAAa;QAC/BO,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYG,SAAS,CAAC,EAAE;QACvBK,MAAMR,YAAYG,SAAS;QAC3BM,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYM,YAAY,CAAC,EAAE;QAC1BE,MAAMR,YAAYM,YAAY;QAC9BG,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYI,SAAS,CAAC,EAAE;QACvBI,MAAMR,YAAYI,SAAS;QAC3BK,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACX,YAAYK,QAAQ,CAAC,EAAE;QACtBG,MAAMR,YAAYK,QAAQ;QAC1BI,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;AACF,EAAW;WAqBJ;UAAKC,aAAa;IAAbA,cACVC,cAAW;GADDD,kBAAAA"}
1
+ {"version":3,"sources":["../../src/handlers.ts"],"sourcesContent":["import type { Component } from '@metamask/snaps-ui';\nimport type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';\n\nimport type { EnumToUnion } from './enum';\nimport type { AccountAddress, Caip2ChainId } from './namespace';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\n OnNameLookup = 'onNameLookup',\n OnKeyringRequest = 'onKeyringRequest',\n}\n\ntype SnapHandler = {\n /**\n * The type of handler.\n */\n type: HandlerType;\n\n /**\n * Whether the handler is required, i.e., whether the request will fail if the\n * handler is called, but the snap does not export it.\n *\n * This is primarily used for the lifecycle handlers, which are optional.\n */\n required: boolean;\n\n /**\n * Validate the given snap export. This should return a type guard for the\n * handler type.\n *\n * @param snapExport - The export to validate.\n * @returns Whether the export is valid.\n */\n validator: (snapExport: unknown) => boolean;\n};\n\nexport const SNAP_EXPORTS = {\n [HandlerType.OnRpcRequest]: {\n type: HandlerType.OnRpcRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnRpcRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnTransaction]: {\n type: HandlerType.OnTransaction,\n required: true,\n validator: (snapExport: unknown): snapExport is OnTransactionHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnCronjob]: {\n type: HandlerType.OnCronjob,\n required: true,\n validator: (snapExport: unknown): snapExport is OnCronjobHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnNameLookup]: {\n type: HandlerType.OnNameLookup,\n required: true,\n validator: (snapExport: unknown): snapExport is OnNameLookupHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnInstall]: {\n type: HandlerType.OnInstall,\n required: false,\n validator: (snapExport: unknown): snapExport is OnInstallHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnUpdate]: {\n type: HandlerType.OnUpdate,\n required: false,\n validator: (snapExport: unknown): snapExport is OnUpdateHandler => {\n return typeof snapExport === 'function';\n },\n },\n [HandlerType.OnKeyringRequest]: {\n type: HandlerType.OnKeyringRequest,\n required: true,\n validator: (snapExport: unknown): snapExport is OnKeyringRequestHandler => {\n return typeof snapExport === 'function';\n },\n },\n} as const;\n\n/**\n * The `onRpcRequest` handler. This is called whenever a JSON-RPC request is\n * made to the snap.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of another\n * snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n * @returns The JSON-RPC response. This must be a JSON-serializable value.\n */\nexport type OnRpcRequestHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n }) => Promise<unknown>;\n\n/**\n * Enum used to specify the severity level of content being returned from a transaction insight.\n */\nexport enum SeverityLevel {\n Critical = 'critical',\n}\n\n/**\n * The response from a snap's `onTransaction` handler.\n *\n * @property content - A custom UI component, that will be shown in MetaMask. Can be created using `@metamask/snaps-ui`.\n *\n * If the snap has no insights about the transaction, this should be `null`.\n */\nexport type OnTransactionResponse = {\n content: Component | null;\n severity?: EnumToUnion<SeverityLevel>;\n};\n\n/**\n * The `onTransaction` handler. This is called whenever a transaction is\n * submitted to the snap. It can return insights about the transaction, which\n * will be displayed to the user.\n *\n * @param args - The request arguments.\n * @param args.transaction - The transaction object.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.transactionOrigin - The origin of the transaction. This is the\n * URL of the dapp that submitted the transaction.\n * @returns Insights about the transaction. See {@link OnTransactionResponse}.\n */\n// TODO: Improve type.\nexport type OnTransactionHandler = (args: {\n transaction: { [key: string]: Json };\n chainId: string;\n transactionOrigin?: string;\n}) => Promise<OnTransactionResponse>;\n\n/**\n * The `onCronjob` handler. This is called on a regular interval, as defined by\n * the snap's manifest.\n *\n * @param args - The request arguments.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnCronjobHandler<Params extends JsonRpcParams = JsonRpcParams> =\n (args: { request: JsonRpcRequest<Params> }) => Promise<unknown>;\n\n/**\n * A handler that can be used for the lifecycle hooks.\n */\nexport type LifecycleEventHandler = (args: {\n request: JsonRpcRequest;\n}) => Promise<unknown>;\n\n/**\n * The `onInstall` handler. This is called after the snap is installed.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnInstallHandler = LifecycleEventHandler;\n\n/**\n * The `onUpdate` handler. This is called after the snap is updated.\n *\n * This type is an alias for {@link LifecycleEventHandler}.\n */\nexport type OnUpdateHandler = LifecycleEventHandler;\n\n/**\n * The `onKeyringRequest` handler. This is called by the MetaMask client for\n * privileged keyring actions.\n *\n * @param args - The request arguments.\n * @param args.origin - The origin of the request. This can be the ID of\n * another snap, or the URL of a dapp.\n * @param args.request - The JSON-RPC request sent to the snap.\n */\nexport type OnKeyringRequestHandler<\n Params extends JsonRpcParams = JsonRpcParams,\n> = (args: {\n origin: string;\n request: JsonRpcRequest<Params>;\n}) => Promise<unknown>;\n\n/**\n * Utility type for getting the handler function type from a handler type.\n */\nexport type HandlerFunction<Type extends SnapHandler> =\n Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler\n ? Handler\n : never;\n\n/**\n * The response from a snap's `onNameLookup` handler.\n *\n * @property resolvedAddress - The resolved address for a given domain.\n * @property resolvedDomain - The resolved domain for a given address.\n *\n *\n * If the snap has no resolved address/domain from its lookup, this should be `null`.\n */\nexport type OnNameLookupResponse =\n | {\n resolvedAddress: AccountAddress;\n resolvedDomain?: never;\n }\n | { resolvedDomain: string; resolvedAddress?: never }\n | null;\n\nexport type OnNameLookupArgs = {\n chainId: Caip2ChainId;\n} & ({ domain: string; address?: never } | { address: string; domain?: never });\n\n/**\n * The `onNameLookup` handler. This is called whenever content is entered\n * into the send to field for sending assets to an EOA address.\n *\n * @param args - The request arguments.\n * @param args.domain - The human-readable address that is to be resolved.\n * @param args.chainId - The CAIP-2 chain ID of the network the transaction is\n * being submitted to.\n * @param args.address - The address that is to be resolved.\n * @returns Resolved address/domain from the lookup. See {@link OnNameLookupResponse}.\n */\nexport type OnNameLookupHandler = (\n args: OnNameLookupArgs,\n) => Promise<OnNameLookupResponse>;\n\n/**\n * All the function-based handlers that a snap can implement.\n */\nexport type SnapFunctionExports = {\n [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<\n (typeof SNAP_EXPORTS)[Key]\n >;\n};\n\n/**\n * All handlers that a snap can implement.\n */\nexport type SnapExports = SnapFunctionExports;\n"],"names":["HandlerType","OnRpcRequest","OnTransaction","OnCronjob","OnInstall","OnUpdate","OnNameLookup","OnKeyringRequest","SNAP_EXPORTS","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":"WAMO;UAAKA,WAAW;IAAXA,YACVC,kBAAe;IADLD,YAEVE,mBAAgB;IAFNF,YAGVG,eAAY;IAHFH,YAIVI,eAAY;IAJFJ,YAKVK,cAAW;IALDL,YAMVM,kBAAe;IANLN,YAOVO,sBAAmB;GAPTP,gBAAAA;AAkCZ,OAAO,MAAMQ,eAAe;IAC1B,CAACR,YAAYC,YAAY,CAAC,EAAE;QAC1BQ,MAAMT,YAAYC,YAAY;QAC9BS,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYE,aAAa,CAAC,EAAE;QAC3BO,MAAMT,YAAYE,aAAa;QAC/BQ,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYG,SAAS,CAAC,EAAE;QACvBM,MAAMT,YAAYG,SAAS;QAC3BO,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYM,YAAY,CAAC,EAAE;QAC1BG,MAAMT,YAAYM,YAAY;QAC9BI,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYI,SAAS,CAAC,EAAE;QACvBK,MAAMT,YAAYI,SAAS;QAC3BM,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYK,QAAQ,CAAC,EAAE;QACtBI,MAAMT,YAAYK,QAAQ;QAC1BK,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;IACA,CAACZ,YAAYO,gBAAgB,CAAC,EAAE;QAC9BE,MAAMT,YAAYO,gBAAgB;QAClCG,UAAU;QACVC,WAAW,CAACC;YACV,OAAO,OAAOA,eAAe;QAC/B;IACF;AACF,EAAW;WAqBJ;UAAKC,aAAa;IAAbA,cACVC,cAAW;GADDD,kBAAAA"}
@@ -1,13 +1,16 @@
1
- import { isJsonRpcFailure, isJsonRpcSuccess, assertStruct } from '@metamask/utils';
2
- import { boolean, object, optional, refine } from 'superstruct';
1
+ import { SubjectType } from '@metamask/permission-controller';
2
+ import { assertStruct, isJsonRpcFailure, isJsonRpcSuccess } from '@metamask/utils';
3
+ import { array, boolean, object, optional, refine, string } from 'superstruct';
3
4
  export const RpcOriginsStruct = refine(object({
4
5
  dapps: optional(boolean()),
5
- snaps: optional(boolean())
6
+ snaps: optional(boolean()),
7
+ allowedOrigins: optional(array(string()))
6
8
  }), 'RPC origins', (value)=>{
7
- if (!Object.values(value).some(Boolean)) {
8
- throw new Error('Must specify at least one JSON-RPC origin');
9
+ const hasOrigins = Boolean(value.snaps === true || value.dapps === true || value.allowedOrigins && value.allowedOrigins.length > 0);
10
+ if (hasOrigins) {
11
+ return true;
9
12
  }
10
- return true;
13
+ return 'Must specify at least one JSON-RPC origin.';
11
14
  });
12
15
  /**
13
16
  * Asserts that the given value is a valid {@link RpcOrigins} object.
@@ -20,6 +23,43 @@ export const RpcOriginsStruct = refine(object({
20
23
  ErrorWrapper) {
21
24
  assertStruct(value, RpcOriginsStruct, 'Invalid JSON-RPC origins', ErrorWrapper);
22
25
  }
26
+ export const KeyringOriginsStruct = object({
27
+ allowedOrigins: optional(array(string()))
28
+ });
29
+ /**
30
+ * Assert that the given value is a valid {@link KeyringOrigins} object.
31
+ *
32
+ * @param value - The value to assert.
33
+ * @param ErrorWrapper - An optional error wrapper to use. Defaults to
34
+ * {@link AssertionError}.
35
+ * @throws If the value is not a valid {@link KeyringOrigins} object.
36
+ */ export function assertIsKeyringOrigins(value, // eslint-disable-next-line @typescript-eslint/naming-convention
37
+ ErrorWrapper) {
38
+ assertStruct(value, KeyringOriginsStruct, 'Invalid keyring origins', ErrorWrapper);
39
+ }
40
+ /**
41
+ * Check if the given origin is allowed by the given JSON-RPC origins object.
42
+ *
43
+ * @param origins - The JSON-RPC origins object.
44
+ * @param subjectType - The type of the origin.
45
+ * @param origin - The origin to check.
46
+ * @returns Whether the origin is allowed.
47
+ */ export function isOriginAllowed(origins, subjectType, origin) {
48
+ // The MetaMask client is always allowed.
49
+ if (origin === 'metamask') {
50
+ return true;
51
+ }
52
+ // If the origin is in the `allowedOrigins` list, it is allowed.
53
+ if (origins.allowedOrigins?.includes(origin)) {
54
+ return true;
55
+ }
56
+ // If the origin is a website and `dapps` is true, it is allowed.
57
+ if (subjectType === SubjectType.Website && origins.dapps) {
58
+ return true;
59
+ }
60
+ // If the origin is a snap and `snaps` is true, it is allowed.
61
+ return Boolean(subjectType === SubjectType.Snap && origins.snaps);
62
+ }
23
63
  /**
24
64
  * Assert that the given value is a successful JSON-RPC response. If the value
25
65
  * is not a success response, an error is thrown. If the value is an JSON-RPC
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/json-rpc.ts"],"sourcesContent":["import type {\n Json,\n JsonRpcSuccess,\n AssertionErrorConstructor,\n} from '@metamask/utils';\nimport {\n isJsonRpcFailure,\n isJsonRpcSuccess,\n assertStruct,\n} from '@metamask/utils';\nimport type { Infer } from 'superstruct';\nimport { boolean, object, optional, refine } from 'superstruct';\n\nexport const RpcOriginsStruct = refine(\n object({\n dapps: optional(boolean()),\n snaps: optional(boolean()),\n }),\n 'RPC origins',\n (value) => {\n if (!Object.values(value).some(Boolean)) {\n throw new Error('Must specify at least one JSON-RPC origin');\n }\n\n return true;\n },\n);\n\nexport type RpcOrigins = Infer<typeof RpcOriginsStruct>;\n\n/**\n * Asserts that the given value is a valid {@link RpcOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link RpcOrigins} object.\n */\nexport function assertIsRpcOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is RpcOrigins {\n assertStruct(\n value,\n RpcOriginsStruct,\n 'Invalid JSON-RPC origins',\n ErrorWrapper,\n );\n}\n\n/**\n * Assert that the given value is a successful JSON-RPC response. If the value\n * is not a success response, an error is thrown. If the value is an JSON-RPC\n * error, the error message is included in the thrown error.\n *\n * @param value - The value to check.\n * @throws If the value is not a JSON-RPC success response.\n */\nexport function assertIsJsonRpcSuccess(\n value: unknown,\n): asserts value is JsonRpcSuccess<Json> {\n if (!isJsonRpcSuccess(value)) {\n if (isJsonRpcFailure(value)) {\n throw new Error(`JSON-RPC request failed: ${value.error.message}`);\n }\n\n throw new Error('Invalid JSON-RPC response.');\n }\n}\n"],"names":["isJsonRpcFailure","isJsonRpcSuccess","assertStruct","boolean","object","optional","refine","RpcOriginsStruct","dapps","snaps","value","Object","values","some","Boolean","Error","assertIsRpcOrigins","ErrorWrapper","assertIsJsonRpcSuccess","error","message"],"mappings":"AAKA,SACEA,gBAAgB,EAChBC,gBAAgB,EAChBC,YAAY,QACP,kBAAkB;AAEzB,SAASC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,MAAM,QAAQ,cAAc;AAEhE,OAAO,MAAMC,mBAAmBD,OAC9BF,OAAO;IACLI,OAAOH,SAASF;IAChBM,OAAOJ,SAASF;AAClB,IACA,eACA,CAACO;IACC,IAAI,CAACC,OAAOC,MAAM,CAACF,OAAOG,IAAI,CAACC,UAAU;QACvC,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;AACT,GACA;AAIF;;;;;;;CAOC,GACD,OAAO,SAASC,mBACdN,KAAc,EACd,gEAAgE;AAChEO,YAAwC;IAExCf,aACEQ,OACAH,kBACA,4BACAU;AAEJ;AAEA;;;;;;;CAOC,GACD,OAAO,SAASC,uBACdR,KAAc;IAEd,IAAI,CAACT,iBAAiBS,QAAQ;QAC5B,IAAIV,iBAAiBU,QAAQ;YAC3B,MAAM,IAAIK,MAAM,CAAC,yBAAyB,EAAEL,MAAMS,KAAK,CAACC,OAAO,CAAC,CAAC;QACnE;QAEA,MAAM,IAAIL,MAAM;IAClB;AACF"}
1
+ {"version":3,"sources":["../../src/json-rpc.ts"],"sourcesContent":["import { SubjectType } from '@metamask/permission-controller';\nimport type {\n AssertionErrorConstructor,\n Json,\n JsonRpcSuccess,\n} from '@metamask/utils';\nimport {\n assertStruct,\n isJsonRpcFailure,\n isJsonRpcSuccess,\n} from '@metamask/utils';\nimport type { Infer } from 'superstruct';\nimport { array, boolean, object, optional, refine, string } from 'superstruct';\n\nexport const RpcOriginsStruct = refine(\n object({\n dapps: optional(boolean()),\n snaps: optional(boolean()),\n allowedOrigins: optional(array(string())),\n }),\n 'RPC origins',\n (value) => {\n const hasOrigins = Boolean(\n value.snaps === true ||\n value.dapps === true ||\n (value.allowedOrigins && value.allowedOrigins.length > 0),\n );\n\n if (hasOrigins) {\n return true;\n }\n\n return 'Must specify at least one JSON-RPC origin.';\n },\n);\n\nexport type RpcOrigins = Infer<typeof RpcOriginsStruct>;\n\n/**\n * Asserts that the given value is a valid {@link RpcOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link RpcOrigins} object.\n */\nexport function assertIsRpcOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is RpcOrigins {\n assertStruct(\n value,\n RpcOriginsStruct,\n 'Invalid JSON-RPC origins',\n ErrorWrapper,\n );\n}\n\nexport const KeyringOriginsStruct = object({\n allowedOrigins: optional(array(string())),\n});\n\nexport type KeyringOrigins = Infer<typeof KeyringOriginsStruct>;\n\n/**\n * Assert that the given value is a valid {@link KeyringOrigins} object.\n *\n * @param value - The value to assert.\n * @param ErrorWrapper - An optional error wrapper to use. Defaults to\n * {@link AssertionError}.\n * @throws If the value is not a valid {@link KeyringOrigins} object.\n */\nexport function assertIsKeyringOrigins(\n value: unknown,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n ErrorWrapper?: AssertionErrorConstructor,\n): asserts value is KeyringOrigins {\n assertStruct(\n value,\n KeyringOriginsStruct,\n 'Invalid keyring origins',\n ErrorWrapper,\n );\n}\n\n/**\n * Check if the given origin is allowed by the given JSON-RPC origins object.\n *\n * @param origins - The JSON-RPC origins object.\n * @param subjectType - The type of the origin.\n * @param origin - The origin to check.\n * @returns Whether the origin is allowed.\n */\nexport function isOriginAllowed(\n origins: RpcOrigins,\n subjectType: SubjectType,\n origin: string,\n) {\n // The MetaMask client is always allowed.\n if (origin === 'metamask') {\n return true;\n }\n\n // If the origin is in the `allowedOrigins` list, it is allowed.\n if (origins.allowedOrigins?.includes(origin)) {\n return true;\n }\n\n // If the origin is a website and `dapps` is true, it is allowed.\n if (subjectType === SubjectType.Website && origins.dapps) {\n return true;\n }\n\n // If the origin is a snap and `snaps` is true, it is allowed.\n return Boolean(subjectType === SubjectType.Snap && origins.snaps);\n}\n\n/**\n * Assert that the given value is a successful JSON-RPC response. If the value\n * is not a success response, an error is thrown. If the value is an JSON-RPC\n * error, the error message is included in the thrown error.\n *\n * @param value - The value to check.\n * @throws If the value is not a JSON-RPC success response.\n */\nexport function assertIsJsonRpcSuccess(\n value: unknown,\n): asserts value is JsonRpcSuccess<Json> {\n if (!isJsonRpcSuccess(value)) {\n if (isJsonRpcFailure(value)) {\n throw new Error(`JSON-RPC request failed: ${value.error.message}`);\n }\n\n throw new Error('Invalid JSON-RPC response.');\n }\n}\n"],"names":["SubjectType","assertStruct","isJsonRpcFailure","isJsonRpcSuccess","array","boolean","object","optional","refine","string","RpcOriginsStruct","dapps","snaps","allowedOrigins","value","hasOrigins","Boolean","length","assertIsRpcOrigins","ErrorWrapper","KeyringOriginsStruct","assertIsKeyringOrigins","isOriginAllowed","origins","subjectType","origin","includes","Website","Snap","assertIsJsonRpcSuccess","Error","error","message"],"mappings":"AAAA,SAASA,WAAW,QAAQ,kCAAkC;AAM9D,SACEC,YAAY,EACZC,gBAAgB,EAChBC,gBAAgB,QACX,kBAAkB;AAEzB,SAASC,KAAK,EAAEC,OAAO,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,MAAM,QAAQ,cAAc;AAE/E,OAAO,MAAMC,mBAAmBF,OAC9BF,OAAO;IACLK,OAAOJ,SAASF;IAChBO,OAAOL,SAASF;IAChBQ,gBAAgBN,SAASH,MAAMK;AACjC,IACA,eACA,CAACK;IACC,MAAMC,aAAaC,QACjBF,MAAMF,KAAK,KAAK,QACdE,MAAMH,KAAK,KAAK,QACfG,MAAMD,cAAc,IAAIC,MAAMD,cAAc,CAACI,MAAM,GAAG;IAG3D,IAAIF,YAAY;QACd,OAAO;IACT;IAEA,OAAO;AACT,GACA;AAIF;;;;;;;CAOC,GACD,OAAO,SAASG,mBACdJ,KAAc,EACd,gEAAgE;AAChEK,YAAwC;IAExClB,aACEa,OACAJ,kBACA,4BACAS;AAEJ;AAEA,OAAO,MAAMC,uBAAuBd,OAAO;IACzCO,gBAAgBN,SAASH,MAAMK;AACjC,GAAG;AAIH;;;;;;;CAOC,GACD,OAAO,SAASY,uBACdP,KAAc,EACd,gEAAgE;AAChEK,YAAwC;IAExClB,aACEa,OACAM,sBACA,2BACAD;AAEJ;AAEA;;;;;;;CAOC,GACD,OAAO,SAASG,gBACdC,OAAmB,EACnBC,WAAwB,EACxBC,MAAc;IAEd,yCAAyC;IACzC,IAAIA,WAAW,YAAY;QACzB,OAAO;IACT;IAEA,gEAAgE;IAChE,IAAIF,QAAQV,cAAc,EAAEa,SAASD,SAAS;QAC5C,OAAO;IACT;IAEA,iEAAiE;IACjE,IAAID,gBAAgBxB,YAAY2B,OAAO,IAAIJ,QAAQZ,KAAK,EAAE;QACxD,OAAO;IACT;IAEA,8DAA8D;IAC9D,OAAOK,QAAQQ,gBAAgBxB,YAAY4B,IAAI,IAAIL,QAAQX,KAAK;AAClE;AAEA;;;;;;;CAOC,GACD,OAAO,SAASiB,uBACdf,KAAc;IAEd,IAAI,CAACX,iBAAiBW,QAAQ;QAC5B,IAAIZ,iBAAiBY,QAAQ;YAC3B,MAAM,IAAIgB,MAAM,CAAC,yBAAyB,EAAEhB,MAAMiB,KAAK,CAACC,OAAO,CAAC,CAAC;QACnE;QAEA,MAAM,IAAIF,MAAM;IAClB;AACF"}
@@ -4,7 +4,7 @@ import { array, boolean, create, enums, integer, is, literal, object, optional,
4
4
  import { isEqual } from '../array';
5
5
  import { CronjobSpecificationArrayStruct } from '../cronjob';
6
6
  import { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';
7
- import { RpcOriginsStruct } from '../json-rpc';
7
+ import { KeyringOriginsStruct, RpcOriginsStruct } from '../json-rpc';
8
8
  import { ChainIdStruct } from '../namespace';
9
9
  import { SnapIdStruct } from '../snaps';
10
10
  import { NameStruct, NpmSnapFileNames } from '../types';
@@ -74,7 +74,6 @@ export const SnapIdsStruct = refine(record(SnapIdStruct, object({
74
74
  });
75
75
  export const ChainIdsStruct = array(ChainIdStruct);
76
76
  /* eslint-disable @typescript-eslint/naming-convention */ export const PermissionsStruct = type({
77
- 'endowment:long-running': optional(object({})),
78
77
  'endowment:network-access': optional(object({})),
79
78
  'endowment:webassembly': optional(object({})),
80
79
  'endowment:transaction-insight': optional(object({
@@ -85,6 +84,7 @@ export const ChainIdsStruct = array(ChainIdStruct);
85
84
  })),
86
85
  'endowment:rpc': optional(RpcOriginsStruct),
87
86
  'endowment:name-lookup': optional(ChainIdsStruct),
87
+ 'endowment:keyring': optional(KeyringOriginsStruct),
88
88
  snap_dialog: optional(object({})),
89
89
  // TODO: Remove
90
90
  snap_confirm: optional(object({})),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/manifest/validation.ts"],"sourcesContent":["import { isValidBIP32PathSegment } from '@metamask/key-tree';\nimport {\n assertStruct,\n ChecksumStruct,\n VersionStruct,\n isValidSemVerRange,\n} from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n enums,\n integer,\n is,\n literal,\n object,\n optional,\n pattern,\n refine,\n record,\n size,\n string,\n type,\n union,\n} from 'superstruct';\n\nimport { isEqual } from '../array';\nimport { CronjobSpecificationArrayStruct } from '../cronjob';\nimport { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';\nimport { RpcOriginsStruct } from '../json-rpc';\nimport { ChainIdStruct } from '../namespace';\nimport { SnapIdStruct } from '../snaps';\nimport { NameStruct, NpmSnapFileNames } from '../types';\n\n// BIP-43 purposes that cannot be used for entropy derivation. These are in the\n// string form, ending with `'`.\nconst FORBIDDEN_PURPOSES: string[] = [\n SIP_6_MAGIC_VALUE,\n STATE_ENCRYPTION_MAGIC_VALUE,\n];\n\nexport const FORBIDDEN_COIN_TYPES: number[] = [60];\nconst FORBIDDEN_PATHS: string[][] = FORBIDDEN_COIN_TYPES.map((coinType) => [\n 'm',\n \"44'\",\n `${coinType}'`,\n]);\n\nexport const Bip32PathStruct = refine(\n array(string()),\n 'BIP-32 path',\n (path: string[]) => {\n if (path.length === 0) {\n return 'Path must be a non-empty BIP-32 derivation path array';\n }\n\n if (path[0] !== 'm') {\n return 'Path must start with \"m\".';\n }\n\n if (path.length < 3) {\n return 'Paths must have a length of at least three.';\n }\n\n if (path.slice(1).some((part) => !isValidBIP32PathSegment(part))) {\n return 'Path must be a valid BIP-32 derivation path array.';\n }\n\n if (FORBIDDEN_PURPOSES.includes(path[1])) {\n return `The purpose \"${path[1]}\" is not allowed for entropy derivation.`;\n }\n\n if (\n FORBIDDEN_PATHS.some((forbiddenPath) =>\n isEqual(path.slice(0, forbiddenPath.length), forbiddenPath),\n )\n ) {\n return `The path \"${path.join(\n '/',\n )}\" is not allowed for entropy derivation.`;\n }\n\n return true;\n },\n);\n\nexport const bip32entropy = <\n Type extends { path: string[]; curve: string },\n Schema,\n>(\n struct: Struct<Type, Schema>,\n) =>\n refine(struct, 'BIP-32 entropy', (value) => {\n if (\n value.curve === 'ed25519' &&\n value.path.slice(1).some((part) => !part.endsWith(\"'\"))\n ) {\n return 'Ed25519 does not support unhardened paths.';\n }\n\n return true;\n });\n\n// Used outside @metamask/snap-utils\nexport const Bip32EntropyStruct = bip32entropy(\n type({\n path: Bip32PathStruct,\n curve: enums(['ed25519', 'secp256k1']),\n }),\n);\n\nexport type Bip32Entropy = Infer<typeof Bip32EntropyStruct>;\n\nexport const SnapGetBip32EntropyPermissionsStruct = size(\n array(Bip32EntropyStruct),\n 1,\n Infinity,\n);\n\nexport const SemVerRangeStruct = refine(string(), 'SemVer range', (value) => {\n if (isValidSemVerRange(value)) {\n return true;\n }\n return 'Expected a valid SemVer range.';\n});\n\nexport const SnapIdsStruct = refine(\n record(SnapIdStruct, object({ version: optional(SemVerRangeStruct) })),\n 'SnapIds',\n (value) => {\n if (Object.keys(value).length === 0) {\n return false;\n }\n\n return true;\n },\n);\n\nexport type SnapIds = Infer<typeof SnapIdsStruct>;\n\nexport const ChainIdsStruct = array(ChainIdStruct);\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport const PermissionsStruct = type({\n 'endowment:long-running': optional(object({})),\n 'endowment:network-access': optional(object({})),\n 'endowment:webassembly': optional(object({})),\n 'endowment:transaction-insight': optional(\n object({\n allowTransactionOrigin: optional(boolean()),\n }),\n ),\n 'endowment:cronjob': optional(\n object({ jobs: CronjobSpecificationArrayStruct }),\n ),\n 'endowment:rpc': optional(RpcOriginsStruct),\n 'endowment:name-lookup': optional(ChainIdsStruct),\n snap_dialog: optional(object({})),\n // TODO: Remove\n snap_confirm: optional(object({})),\n snap_manageState: optional(object({})),\n snap_manageAccounts: optional(object({})),\n snap_notify: optional(object({})),\n snap_getBip32Entropy: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip32PublicKey: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip44Entropy: optional(\n size(\n array(object({ coinType: size(integer(), 0, 2 ** 32 - 1) })),\n 1,\n Infinity,\n ),\n ),\n snap_getEntropy: optional(object({})),\n wallet_snap: optional(SnapIdsStruct),\n});\n/* eslint-enable @typescript-eslint/naming-convention */\n\nexport type SnapPermissions = Infer<typeof PermissionsStruct>;\n\nexport const SnapManifestStruct = object({\n version: VersionStruct,\n description: size(string(), 1, 280),\n proposedName: size(\n pattern(\n string(),\n /^(?:[A-Za-z0-9-_]+( [A-Za-z0-9-_]+)*)|(?:(?:@[A-Za-z0-9-*~][A-Za-z0-9-*._~]*\\/)?[A-Za-z0-9-~][A-Za-z0-9-._~]*)$/u,\n ),\n 1,\n 214,\n ),\n repository: optional(\n object({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n source: object({\n shasum: ChecksumStruct,\n location: object({\n npm: object({\n filePath: size(string(), 1, Infinity),\n iconPath: optional(size(string(), 1, Infinity)),\n packageName: NameStruct,\n registry: union([\n literal('https://registry.npmjs.org'),\n literal('https://registry.npmjs.org/'),\n ]),\n }),\n }),\n }),\n initialPermissions: PermissionsStruct,\n manifestVersion: literal('0.1'),\n $schema: optional(string()), // enables JSON-Schema linting in VSC and other IDEs\n});\n\nexport type SnapManifest = Infer<typeof SnapManifestStruct>;\n\n/**\n * Check if the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @returns Whether the value is a valid {@link SnapManifest} object.\n */\nexport function isSnapManifest(value: unknown): value is SnapManifest {\n return is(value, SnapManifestStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid {@link SnapManifest} object.\n */\nexport function assertIsSnapManifest(\n value: unknown,\n): asserts value is SnapManifest {\n assertStruct(\n value,\n SnapManifestStruct,\n `\"${NpmSnapFileNames.Manifest}\" is invalid`,\n );\n}\n\n/**\n * Creates a {@link SnapManifest} object from JSON.\n *\n * @param value - The value to check.\n * @throws If the value cannot be coerced to a {@link SnapManifest} object.\n * @returns The created {@link SnapManifest} object.\n */\nexport function createSnapManifest(value: unknown): SnapManifest {\n // TODO: Add a utility to prefix these errors similar to assertStruct\n return create(value, SnapManifestStruct);\n}\n"],"names":["isValidBIP32PathSegment","assertStruct","ChecksumStruct","VersionStruct","isValidSemVerRange","array","boolean","create","enums","integer","is","literal","object","optional","pattern","refine","record","size","string","type","union","isEqual","CronjobSpecificationArrayStruct","SIP_6_MAGIC_VALUE","STATE_ENCRYPTION_MAGIC_VALUE","RpcOriginsStruct","ChainIdStruct","SnapIdStruct","NameStruct","NpmSnapFileNames","FORBIDDEN_PURPOSES","FORBIDDEN_COIN_TYPES","FORBIDDEN_PATHS","map","coinType","Bip32PathStruct","path","length","slice","some","part","includes","forbiddenPath","join","bip32entropy","struct","value","curve","endsWith","Bip32EntropyStruct","SnapGetBip32EntropyPermissionsStruct","Infinity","SemVerRangeStruct","SnapIdsStruct","version","Object","keys","ChainIdsStruct","PermissionsStruct","allowTransactionOrigin","jobs","snap_dialog","snap_confirm","snap_manageState","snap_manageAccounts","snap_notify","snap_getBip32Entropy","snap_getBip32PublicKey","snap_getBip44Entropy","snap_getEntropy","wallet_snap","SnapManifestStruct","description","proposedName","repository","url","source","shasum","location","npm","filePath","iconPath","packageName","registry","initialPermissions","manifestVersion","$schema","isSnapManifest","assertIsSnapManifest","Manifest","createSnapManifest"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/manifest/validation.ts"],"sourcesContent":["import { isValidBIP32PathSegment } from '@metamask/key-tree';\nimport {\n assertStruct,\n ChecksumStruct,\n VersionStruct,\n isValidSemVerRange,\n} from '@metamask/utils';\nimport type { Infer, Struct } from 'superstruct';\nimport {\n array,\n boolean,\n create,\n enums,\n integer,\n is,\n literal,\n object,\n optional,\n pattern,\n refine,\n record,\n size,\n string,\n type,\n union,\n} from 'superstruct';\n\nimport { isEqual } from '../array';\nimport { CronjobSpecificationArrayStruct } from '../cronjob';\nimport { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';\nimport { KeyringOriginsStruct, RpcOriginsStruct } from '../json-rpc';\nimport { ChainIdStruct } from '../namespace';\nimport { SnapIdStruct } from '../snaps';\nimport { NameStruct, NpmSnapFileNames } from '../types';\n\n// BIP-43 purposes that cannot be used for entropy derivation. These are in the\n// string form, ending with `'`.\nconst FORBIDDEN_PURPOSES: string[] = [\n SIP_6_MAGIC_VALUE,\n STATE_ENCRYPTION_MAGIC_VALUE,\n];\n\nexport const FORBIDDEN_COIN_TYPES: number[] = [60];\nconst FORBIDDEN_PATHS: string[][] = FORBIDDEN_COIN_TYPES.map((coinType) => [\n 'm',\n \"44'\",\n `${coinType}'`,\n]);\n\nexport const Bip32PathStruct = refine(\n array(string()),\n 'BIP-32 path',\n (path: string[]) => {\n if (path.length === 0) {\n return 'Path must be a non-empty BIP-32 derivation path array';\n }\n\n if (path[0] !== 'm') {\n return 'Path must start with \"m\".';\n }\n\n if (path.length < 3) {\n return 'Paths must have a length of at least three.';\n }\n\n if (path.slice(1).some((part) => !isValidBIP32PathSegment(part))) {\n return 'Path must be a valid BIP-32 derivation path array.';\n }\n\n if (FORBIDDEN_PURPOSES.includes(path[1])) {\n return `The purpose \"${path[1]}\" is not allowed for entropy derivation.`;\n }\n\n if (\n FORBIDDEN_PATHS.some((forbiddenPath) =>\n isEqual(path.slice(0, forbiddenPath.length), forbiddenPath),\n )\n ) {\n return `The path \"${path.join(\n '/',\n )}\" is not allowed for entropy derivation.`;\n }\n\n return true;\n },\n);\n\nexport const bip32entropy = <\n Type extends { path: string[]; curve: string },\n Schema,\n>(\n struct: Struct<Type, Schema>,\n) =>\n refine(struct, 'BIP-32 entropy', (value) => {\n if (\n value.curve === 'ed25519' &&\n value.path.slice(1).some((part) => !part.endsWith(\"'\"))\n ) {\n return 'Ed25519 does not support unhardened paths.';\n }\n\n return true;\n });\n\n// Used outside @metamask/snap-utils\nexport const Bip32EntropyStruct = bip32entropy(\n type({\n path: Bip32PathStruct,\n curve: enums(['ed25519', 'secp256k1']),\n }),\n);\n\nexport type Bip32Entropy = Infer<typeof Bip32EntropyStruct>;\n\nexport const SnapGetBip32EntropyPermissionsStruct = size(\n array(Bip32EntropyStruct),\n 1,\n Infinity,\n);\n\nexport const SemVerRangeStruct = refine(string(), 'SemVer range', (value) => {\n if (isValidSemVerRange(value)) {\n return true;\n }\n return 'Expected a valid SemVer range.';\n});\n\nexport const SnapIdsStruct = refine(\n record(SnapIdStruct, object({ version: optional(SemVerRangeStruct) })),\n 'SnapIds',\n (value) => {\n if (Object.keys(value).length === 0) {\n return false;\n }\n\n return true;\n },\n);\n\nexport type SnapIds = Infer<typeof SnapIdsStruct>;\n\nexport const ChainIdsStruct = array(ChainIdStruct);\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport const PermissionsStruct = type({\n 'endowment:network-access': optional(object({})),\n 'endowment:webassembly': optional(object({})),\n 'endowment:transaction-insight': optional(\n object({\n allowTransactionOrigin: optional(boolean()),\n }),\n ),\n 'endowment:cronjob': optional(\n object({ jobs: CronjobSpecificationArrayStruct }),\n ),\n 'endowment:rpc': optional(RpcOriginsStruct),\n 'endowment:name-lookup': optional(ChainIdsStruct),\n 'endowment:keyring': optional(KeyringOriginsStruct),\n snap_dialog: optional(object({})),\n // TODO: Remove\n snap_confirm: optional(object({})),\n snap_manageState: optional(object({})),\n snap_manageAccounts: optional(object({})),\n snap_notify: optional(object({})),\n snap_getBip32Entropy: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip32PublicKey: optional(SnapGetBip32EntropyPermissionsStruct),\n snap_getBip44Entropy: optional(\n size(\n array(object({ coinType: size(integer(), 0, 2 ** 32 - 1) })),\n 1,\n Infinity,\n ),\n ),\n snap_getEntropy: optional(object({})),\n wallet_snap: optional(SnapIdsStruct),\n});\n/* eslint-enable @typescript-eslint/naming-convention */\n\nexport type SnapPermissions = Infer<typeof PermissionsStruct>;\n\nexport const SnapManifestStruct = object({\n version: VersionStruct,\n description: size(string(), 1, 280),\n proposedName: size(\n pattern(\n string(),\n /^(?:[A-Za-z0-9-_]+( [A-Za-z0-9-_]+)*)|(?:(?:@[A-Za-z0-9-*~][A-Za-z0-9-*._~]*\\/)?[A-Za-z0-9-~][A-Za-z0-9-._~]*)$/u,\n ),\n 1,\n 214,\n ),\n repository: optional(\n object({\n type: size(string(), 1, Infinity),\n url: size(string(), 1, Infinity),\n }),\n ),\n source: object({\n shasum: ChecksumStruct,\n location: object({\n npm: object({\n filePath: size(string(), 1, Infinity),\n iconPath: optional(size(string(), 1, Infinity)),\n packageName: NameStruct,\n registry: union([\n literal('https://registry.npmjs.org'),\n literal('https://registry.npmjs.org/'),\n ]),\n }),\n }),\n }),\n initialPermissions: PermissionsStruct,\n manifestVersion: literal('0.1'),\n $schema: optional(string()), // enables JSON-Schema linting in VSC and other IDEs\n});\n\nexport type SnapManifest = Infer<typeof SnapManifestStruct>;\n\n/**\n * Check if the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @returns Whether the value is a valid {@link SnapManifest} object.\n */\nexport function isSnapManifest(value: unknown): value is SnapManifest {\n return is(value, SnapManifestStruct);\n}\n\n/**\n * Assert that the given value is a valid {@link SnapManifest} object.\n *\n * @param value - The value to check.\n * @throws If the value is not a valid {@link SnapManifest} object.\n */\nexport function assertIsSnapManifest(\n value: unknown,\n): asserts value is SnapManifest {\n assertStruct(\n value,\n SnapManifestStruct,\n `\"${NpmSnapFileNames.Manifest}\" is invalid`,\n );\n}\n\n/**\n * Creates a {@link SnapManifest} object from JSON.\n *\n * @param value - The value to check.\n * @throws If the value cannot be coerced to a {@link SnapManifest} object.\n * @returns The created {@link SnapManifest} object.\n */\nexport function createSnapManifest(value: unknown): SnapManifest {\n // TODO: Add a utility to prefix these errors similar to assertStruct\n return create(value, SnapManifestStruct);\n}\n"],"names":["isValidBIP32PathSegment","assertStruct","ChecksumStruct","VersionStruct","isValidSemVerRange","array","boolean","create","enums","integer","is","literal","object","optional","pattern","refine","record","size","string","type","union","isEqual","CronjobSpecificationArrayStruct","SIP_6_MAGIC_VALUE","STATE_ENCRYPTION_MAGIC_VALUE","KeyringOriginsStruct","RpcOriginsStruct","ChainIdStruct","SnapIdStruct","NameStruct","NpmSnapFileNames","FORBIDDEN_PURPOSES","FORBIDDEN_COIN_TYPES","FORBIDDEN_PATHS","map","coinType","Bip32PathStruct","path","length","slice","some","part","includes","forbiddenPath","join","bip32entropy","struct","value","curve","endsWith","Bip32EntropyStruct","SnapGetBip32EntropyPermissionsStruct","Infinity","SemVerRangeStruct","SnapIdsStruct","version","Object","keys","ChainIdsStruct","PermissionsStruct","allowTransactionOrigin","jobs","snap_dialog","snap_confirm","snap_manageState","snap_manageAccounts","snap_notify","snap_getBip32Entropy","snap_getBip32PublicKey","snap_getBip44Entropy","snap_getEntropy","wallet_snap","SnapManifestStruct","description","proposedName","repository","url","source","shasum","location","npm","filePath","iconPath","packageName","registry","initialPermissions","manifestVersion","$schema","isSnapManifest","assertIsSnapManifest","Manifest","createSnapManifest"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/virtual-file/toVirtualFile.ts"],"sourcesContent":["import { promises as fsPromises } from 'fs';\n\nimport { VirtualFile } from './VirtualFile';\n\n/**\n * Reads a file from filesystem and creates a vfile.\n *\n * @param path - Filesystem path to load the contents from.\n * @param encoding - Optional encoding to pass down to fs.readFile.\n * @returns Promise returning VFile with loaded file contents.\n */\nexport async function readVirtualFile(\n path: string,\n encoding: BufferEncoding | null = null,\n) {\n return new VirtualFile({\n path,\n value: await fsPromises.readFile(path, { encoding }),\n });\n}\n\ntype WriteVFileOptions = Exclude<\n Parameters<typeof fsPromises['writeFile']>[2],\n undefined\n>;\n\n/**\n * Writes vfile to filesystem.\n *\n * @param vfile - The vfile to write.\n * @param options - Options to pass down to fs.writeFile.\n */\nexport async function writeVirtualFile(\n vfile: VirtualFile,\n options?: WriteVFileOptions,\n) {\n return fsPromises.writeFile(vfile.path, vfile.value, options);\n}\n"],"names":["promises","fsPromises","VirtualFile","readVirtualFile","path","encoding","value","readFile","writeVirtualFile","vfile","options","writeFile"],"mappings":"AAAA,SAASA,YAAYC,UAAU,QAAQ,KAAK;AAE5C,SAASC,WAAW,QAAQ,gBAAgB;AAE5C;;;;;;CAMC,GACD,OAAO,eAAeC,gBACpBC,IAAY,EACZC,WAAkC,IAAI;IAEtC,OAAO,IAAIH,YAAY;QACrBE;QACAE,OAAO,MAAML,WAAWM,QAAQ,CAACH,MAAM;YAAEC;QAAS;IACpD;AACF;AAOA;;;;;CAKC,GACD,OAAO,eAAeG,iBACpBC,KAAkB,EAClBC,OAA2B;IAE3B,OAAOT,WAAWU,SAAS,CAACF,MAAML,IAAI,EAAEK,MAAMH,KAAK,EAAEI;AACvD"}
1
+ {"version":3,"sources":["../../../src/virtual-file/toVirtualFile.ts"],"sourcesContent":["import { promises as fsPromises } from 'fs';\n\nimport { VirtualFile } from './VirtualFile';\n\n/**\n * Reads a file from filesystem and creates a vfile.\n *\n * @param path - Filesystem path to load the contents from.\n * @param encoding - Optional encoding to pass down to fs.readFile.\n * @returns Promise returning VFile with loaded file contents.\n */\nexport async function readVirtualFile(\n path: string,\n encoding: BufferEncoding | null = null,\n) {\n return new VirtualFile({\n path,\n value: await fsPromises.readFile(path, { encoding }),\n });\n}\n\ntype WriteVFileOptions = Exclude<\n Parameters<(typeof fsPromises)['writeFile']>[2],\n undefined\n>;\n\n/**\n * Writes vfile to filesystem.\n *\n * @param vfile - The vfile to write.\n * @param options - Options to pass down to fs.writeFile.\n */\nexport async function writeVirtualFile(\n vfile: VirtualFile,\n options?: WriteVFileOptions,\n) {\n return fsPromises.writeFile(vfile.path, vfile.value, options);\n}\n"],"names":["promises","fsPromises","VirtualFile","readVirtualFile","path","encoding","value","readFile","writeVirtualFile","vfile","options","writeFile"],"mappings":"AAAA,SAASA,YAAYC,UAAU,QAAQ,KAAK;AAE5C,SAASC,WAAW,QAAQ,gBAAgB;AAE5C;;;;;;CAMC,GACD,OAAO,eAAeC,gBACpBC,IAAY,EACZC,WAAkC,IAAI;IAEtC,OAAO,IAAIH,YAAY;QACrBE;QACAE,OAAO,MAAML,WAAWM,QAAQ,CAACH,MAAM;YAAEC;QAAS;IACpD;AACF;AAOA;;;;;CAKC,GACD,OAAO,eAAeG,iBACpBC,KAAkB,EAClBC,OAA2B;IAE3B,OAAOT,WAAWU,SAAS,CAACF,MAAML,IAAI,EAAEK,MAAMH,KAAK,EAAEI;AACvD"}
@@ -19,6 +19,10 @@ export declare enum SnapCaveatType {
19
19
  * The origins that a Snap can receive JSON-RPC messages from.
20
20
  */
21
21
  RpcOrigin = "rpcOrigin",
22
+ /**
23
+ * The origins that a Snap can receive keyring messages from.
24
+ */
25
+ KeyringOrigin = "keyringOrigin",
22
26
  /**
23
27
  * Caveat specifying the snap IDs that can be interacted with.
24
28
  */
@@ -8,7 +8,8 @@ export declare enum HandlerType {
8
8
  OnCronjob = "onCronjob",
9
9
  OnInstall = "onInstall",
10
10
  OnUpdate = "onUpdate",
11
- OnNameLookup = "onNameLookup"
11
+ OnNameLookup = "onNameLookup",
12
+ OnKeyringRequest = "onKeyringRequest"
12
13
  }
13
14
  declare type SnapHandler = {
14
15
  /**
@@ -62,6 +63,11 @@ export declare const SNAP_EXPORTS: {
62
63
  readonly required: false;
63
64
  readonly validator: (snapExport: unknown) => snapExport is LifecycleEventHandler;
64
65
  };
66
+ readonly onKeyringRequest: {
67
+ readonly type: HandlerType.OnKeyringRequest;
68
+ readonly required: true;
69
+ readonly validator: (snapExport: unknown) => snapExport is OnKeyringRequestHandler<JsonRpcParams>;
70
+ };
65
71
  };
66
72
  /**
67
73
  * The `onRpcRequest` handler. This is called whenever a JSON-RPC request is
@@ -142,6 +148,19 @@ export declare type OnInstallHandler = LifecycleEventHandler;
142
148
  * This type is an alias for {@link LifecycleEventHandler}.
143
149
  */
144
150
  export declare type OnUpdateHandler = LifecycleEventHandler;
151
+ /**
152
+ * The `onKeyringRequest` handler. This is called by the MetaMask client for
153
+ * privileged keyring actions.
154
+ *
155
+ * @param args - The request arguments.
156
+ * @param args.origin - The origin of the request. This can be the ID of
157
+ * another snap, or the URL of a dapp.
158
+ * @param args.request - The JSON-RPC request sent to the snap.
159
+ */
160
+ export declare type OnKeyringRequestHandler<Params extends JsonRpcParams = JsonRpcParams> = (args: {
161
+ origin: string;
162
+ request: JsonRpcRequest<Params>;
163
+ }) => Promise<unknown>;
145
164
  /**
146
165
  * Utility type for getting the handler function type from a handler type.
147
166
  */
@@ -187,7 +206,7 @@ export declare type OnNameLookupHandler = (args: OnNameLookupArgs) => Promise<On
187
206
  * All the function-based handlers that a snap can implement.
188
207
  */
189
208
  export declare type SnapFunctionExports = {
190
- [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<typeof SNAP_EXPORTS[Key]>;
209
+ [Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<(typeof SNAP_EXPORTS)[Key]>;
191
210
  };
192
211
  /**
193
212
  * All handlers that a snap can implement.
@@ -1,11 +1,14 @@
1
- import type { Json, JsonRpcSuccess, AssertionErrorConstructor } from '@metamask/utils';
1
+ import { SubjectType } from '@metamask/permission-controller';
2
+ import type { AssertionErrorConstructor, Json, JsonRpcSuccess } from '@metamask/utils';
2
3
  import type { Infer } from 'superstruct';
3
4
  export declare const RpcOriginsStruct: import("superstruct").Struct<{
4
5
  dapps?: boolean | undefined;
5
6
  snaps?: boolean | undefined;
7
+ allowedOrigins?: string[] | undefined;
6
8
  }, {
7
9
  dapps: import("superstruct").Struct<boolean | undefined, null>;
8
10
  snaps: import("superstruct").Struct<boolean | undefined, null>;
11
+ allowedOrigins: import("superstruct").Struct<string[] | undefined, import("superstruct").Struct<string, null>>;
9
12
  }>;
10
13
  export declare type RpcOrigins = Infer<typeof RpcOriginsStruct>;
11
14
  /**
@@ -17,6 +20,30 @@ export declare type RpcOrigins = Infer<typeof RpcOriginsStruct>;
17
20
  * @throws If the value is not a valid {@link RpcOrigins} object.
18
21
  */
19
22
  export declare function assertIsRpcOrigins(value: unknown, ErrorWrapper?: AssertionErrorConstructor): asserts value is RpcOrigins;
23
+ export declare const KeyringOriginsStruct: import("superstruct").Struct<{
24
+ allowedOrigins?: string[] | undefined;
25
+ }, {
26
+ allowedOrigins: import("superstruct").Struct<string[] | undefined, import("superstruct").Struct<string, null>>;
27
+ }>;
28
+ export declare type KeyringOrigins = Infer<typeof KeyringOriginsStruct>;
29
+ /**
30
+ * Assert that the given value is a valid {@link KeyringOrigins} object.
31
+ *
32
+ * @param value - The value to assert.
33
+ * @param ErrorWrapper - An optional error wrapper to use. Defaults to
34
+ * {@link AssertionError}.
35
+ * @throws If the value is not a valid {@link KeyringOrigins} object.
36
+ */
37
+ export declare function assertIsKeyringOrigins(value: unknown, ErrorWrapper?: AssertionErrorConstructor): asserts value is KeyringOrigins;
38
+ /**
39
+ * Check if the given origin is allowed by the given JSON-RPC origins object.
40
+ *
41
+ * @param origins - The JSON-RPC origins object.
42
+ * @param subjectType - The type of the origin.
43
+ * @param origin - The origin to check.
44
+ * @returns Whether the origin is allowed.
45
+ */
46
+ export declare function isOriginAllowed(origins: RpcOrigins, subjectType: SubjectType, origin: string): boolean;
20
47
  /**
21
48
  * Assert that the given value is a successful JSON-RPC response. If the value
22
49
  * is not a success response, an error is thrown. If the value is an JSON-RPC
@@ -36,7 +36,6 @@ export declare const SnapIdsStruct: Struct<Record<string, {
36
36
  export declare type SnapIds = Infer<typeof SnapIdsStruct>;
37
37
  export declare const ChainIdsStruct: Struct<string[], Struct<string, null>>;
38
38
  export declare const PermissionsStruct: Struct<{
39
- 'endowment:long-running'?: {} | undefined;
40
39
  'endowment:network-access'?: {} | undefined;
41
40
  'endowment:webassembly'?: {} | undefined;
42
41
  'endowment:transaction-insight'?: {
@@ -56,8 +55,12 @@ export declare const PermissionsStruct: Struct<{
56
55
  'endowment:rpc'?: {
57
56
  dapps?: boolean | undefined;
58
57
  snaps?: boolean | undefined;
58
+ allowedOrigins?: string[] | undefined;
59
59
  } | undefined;
60
60
  'endowment:name-lookup'?: string[] | undefined;
61
+ 'endowment:keyring'?: {
62
+ allowedOrigins?: string[] | undefined;
63
+ } | undefined;
61
64
  snap_dialog?: {} | undefined;
62
65
  snap_confirm?: {} | undefined;
63
66
  snap_manageState?: {} | undefined;
@@ -79,7 +82,6 @@ export declare const PermissionsStruct: Struct<{
79
82
  version?: string | undefined;
80
83
  }> | undefined;
81
84
  }, {
82
- 'endowment:long-running': Struct<{} | undefined, {}>;
83
85
  'endowment:network-access': Struct<{} | undefined, {}>;
84
86
  'endowment:webassembly': Struct<{} | undefined, {}>;
85
87
  'endowment:transaction-insight': Struct<{
@@ -132,11 +134,18 @@ export declare const PermissionsStruct: Struct<{
132
134
  'endowment:rpc': Struct<{
133
135
  dapps?: boolean | undefined;
134
136
  snaps?: boolean | undefined;
137
+ allowedOrigins?: string[] | undefined;
135
138
  } | undefined, {
136
139
  dapps: Struct<boolean | undefined, null>;
137
140
  snaps: Struct<boolean | undefined, null>;
141
+ allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
138
142
  }>;
139
143
  'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
144
+ 'endowment:keyring': Struct<{
145
+ allowedOrigins?: string[] | undefined;
146
+ } | undefined, {
147
+ allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
148
+ }>;
140
149
  snap_dialog: Struct<{} | undefined, {}>;
141
150
  snap_confirm: Struct<{} | undefined, {}>;
142
151
  snap_manageState: Struct<{} | undefined, {}>;
@@ -197,7 +206,6 @@ export declare const SnapManifestStruct: Struct<{
197
206
  shasum: string;
198
207
  };
199
208
  initialPermissions: {
200
- 'endowment:long-running'?: {} | undefined;
201
209
  'endowment:network-access'?: {} | undefined;
202
210
  'endowment:webassembly'?: {} | undefined;
203
211
  'endowment:transaction-insight'?: {
@@ -217,8 +225,12 @@ export declare const SnapManifestStruct: Struct<{
217
225
  'endowment:rpc'?: {
218
226
  dapps?: boolean | undefined;
219
227
  snaps?: boolean | undefined;
228
+ allowedOrigins?: string[] | undefined;
220
229
  } | undefined;
221
230
  'endowment:name-lookup'?: string[] | undefined;
231
+ 'endowment:keyring'?: {
232
+ allowedOrigins?: string[] | undefined;
233
+ } | undefined;
222
234
  snap_dialog?: {} | undefined;
223
235
  snap_confirm?: {} | undefined;
224
236
  snap_manageState?: {} | undefined;
@@ -291,7 +303,6 @@ export declare const SnapManifestStruct: Struct<{
291
303
  }>;
292
304
  }>;
293
305
  initialPermissions: Struct<{
294
- 'endowment:long-running'?: {} | undefined;
295
306
  'endowment:network-access'?: {} | undefined;
296
307
  'endowment:webassembly'?: {} | undefined;
297
308
  'endowment:transaction-insight'?: {
@@ -311,8 +322,12 @@ export declare const SnapManifestStruct: Struct<{
311
322
  'endowment:rpc'?: {
312
323
  dapps?: boolean | undefined;
313
324
  snaps?: boolean | undefined;
325
+ allowedOrigins?: string[] | undefined;
314
326
  } | undefined;
315
327
  'endowment:name-lookup'?: string[] | undefined;
328
+ 'endowment:keyring'?: {
329
+ allowedOrigins?: string[] | undefined;
330
+ } | undefined;
316
331
  snap_dialog?: {} | undefined;
317
332
  snap_confirm?: {} | undefined;
318
333
  snap_manageState?: {} | undefined;
@@ -334,7 +349,6 @@ export declare const SnapManifestStruct: Struct<{
334
349
  version?: string | undefined;
335
350
  }> | undefined;
336
351
  }, {
337
- 'endowment:long-running': Struct<{} | undefined, {}>;
338
352
  'endowment:network-access': Struct<{} | undefined, {}>;
339
353
  'endowment:webassembly': Struct<{} | undefined, {}>;
340
354
  'endowment:transaction-insight': Struct<{
@@ -387,11 +401,18 @@ export declare const SnapManifestStruct: Struct<{
387
401
  'endowment:rpc': Struct<{
388
402
  dapps?: boolean | undefined;
389
403
  snaps?: boolean | undefined;
404
+ allowedOrigins?: string[] | undefined;
390
405
  } | undefined, {
391
406
  dapps: Struct<boolean | undefined, null>;
392
407
  snaps: Struct<boolean | undefined, null>;
408
+ allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
393
409
  }>;
394
410
  'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
411
+ 'endowment:keyring': Struct<{
412
+ allowedOrigins?: string[] | undefined;
413
+ } | undefined, {
414
+ allowedOrigins: Struct<string[] | undefined, Struct<string, null>>;
415
+ }>;
395
416
  snap_dialog: Struct<{} | undefined, {}>;
396
417
  snap_confirm: Struct<{} | undefined, {}>;
397
418
  snap_manageState: Struct<{} | undefined, {}>;
@@ -10,7 +10,7 @@ import { VirtualFile } from './VirtualFile';
10
10
  * @returns Promise returning VFile with loaded file contents.
11
11
  */
12
12
  export declare function readVirtualFile(path: string, encoding?: BufferEncoding | null): Promise<VirtualFile<unknown>>;
13
- declare type WriteVFileOptions = Exclude<Parameters<typeof fsPromises['writeFile']>[2], undefined>;
13
+ declare type WriteVFileOptions = Exclude<Parameters<(typeof fsPromises)['writeFile']>[2], undefined>;
14
14
  /**
15
15
  * Writes vfile to filesystem.
16
16
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask/snaps-utils",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/MetaMask/snaps.git"
@@ -46,7 +46,7 @@
46
46
  "scripts": {
47
47
  "test": "rimraf coverage && jest && yarn test:browser && yarn posttest",
48
48
  "posttest": "ts-node scripts/coverage.ts && rimraf coverage/jest coverage/wdio",
49
- "test:browser": "wdio run wdio.config.ts",
49
+ "test:browser": "wdio run wdio.config.js",
50
50
  "test:ci": "yarn test",
51
51
  "lint:eslint": "eslint . --cache --ext js,ts,jsx,tsx",
52
52
  "lint:misc": "prettier --no-error-on-unmatched-pattern --loglevel warn \"**/*.json\" \"**/*.md\" \"**/*.html\" \"!CHANGELOG.md\" --ignore-path ../../.gitignore",
@@ -70,9 +70,9 @@
70
70
  "@babel/types": "^7.18.7",
71
71
  "@metamask/base-controller": "^3.2.0",
72
72
  "@metamask/key-tree": "^9.0.0",
73
- "@metamask/permission-controller": "^4.1.0",
73
+ "@metamask/permission-controller": "^4.1.2",
74
74
  "@metamask/snaps-registry": "^2.0.0",
75
- "@metamask/snaps-ui": "^2.0.0",
75
+ "@metamask/snaps-ui": "^3.0.0",
76
76
  "@metamask/utils": "^8.1.0",
77
77
  "@noble/hashes": "^1.3.1",
78
78
  "@scure/base": "^1.1.1",
@@ -84,15 +84,15 @@
84
84
  "is-svg": "^4.4.0",
85
85
  "rfdc": "^1.3.0",
86
86
  "semver": "^7.5.4",
87
- "ses": "^0.18.7",
87
+ "ses": "^0.18.8",
88
88
  "superstruct": "^1.0.3",
89
89
  "validate-npm-package-name": "^5.0.0"
90
90
  },
91
91
  "devDependencies": {
92
92
  "@esbuild-plugins/node-globals-polyfill": "^0.2.3",
93
93
  "@esbuild-plugins/node-modules-polyfill": "^0.2.2",
94
- "@lavamoat/allow-scripts": "^2.3.1",
95
- "@metamask/auto-changelog": "^3.1.0",
94
+ "@lavamoat/allow-scripts": "^2.5.1",
95
+ "@metamask/auto-changelog": "^3.3.0",
96
96
  "@metamask/eslint-config": "^12.1.0",
97
97
  "@metamask/eslint-config-jest": "^12.1.0",
98
98
  "@metamask/eslint-config-nodejs": "^12.1.0",
@@ -144,7 +144,7 @@
144
144
  "webdriverio": "^8.15.9"
145
145
  },
146
146
  "engines": {
147
- "node": ">=16.0.0"
147
+ "node": "^18.16 || >=20"
148
148
  },
149
149
  "publishConfig": {
150
150
  "access": "public",