@metamask/snaps-utils 0.38.3-flask.1 → 0.38.4-flask.1
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 +9 -1
- package/dist/cjs/caveats.js +3 -0
- package/dist/cjs/caveats.js.map +1 -1
- package/dist/cjs/handlers.js +8 -0
- package/dist/cjs/handlers.js.map +1 -1
- package/dist/cjs/manifest/validation.js +6 -0
- package/dist/cjs/manifest/validation.js.map +1 -1
- package/dist/cjs/namespace.js +8 -0
- package/dist/cjs/namespace.js.map +1 -1
- package/dist/esm/caveats.js +3 -0
- package/dist/esm/caveats.js.map +1 -1
- package/dist/esm/handlers.js +8 -0
- package/dist/esm/handlers.js.map +1 -1
- package/dist/esm/manifest/validation.js +3 -0
- package/dist/esm/manifest/validation.js.map +1 -1
- package/dist/esm/namespace.js +2 -0
- package/dist/esm/namespace.js.map +1 -1
- package/dist/types/caveats.d.ts +5 -1
- package/dist/types/handlers.d.ts +47 -3
- package/dist/types/manifest/validation.d.ts +6 -0
- package/dist/types/namespace.d.ts +4 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.38.4-flask.1]
|
|
10
|
+
### Added
|
|
11
|
+
- Add `onNameLookup` export ([#1394](https://github.com/MetaMask/snaps/pull/1394), [#1759](https://github.com/MetaMask/snaps/pull/1759))
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
- Bump `metamask/utils` and `metamask/snaps-registry` ([#1738](https://github.com/MetaMask/snaps/pull/1738))
|
|
15
|
+
|
|
9
16
|
## [0.38.3-flask.1]
|
|
10
17
|
### Changed
|
|
11
18
|
- Bump `@metamask/post-message-stream` from 6.1.2 to 7.0.0 ([#1707](https://github.com/MetaMask/snaps/pull/1707), [#1724](https://github.com/MetaMask/snaps/pull/1724))
|
|
@@ -35,7 +42,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
35
42
|
- The version of the package no longer needs to match the version of all other
|
|
36
43
|
MetaMask Snaps packages.
|
|
37
44
|
|
|
38
|
-
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.
|
|
45
|
+
[Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.4-flask.1...HEAD
|
|
46
|
+
[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
|
|
39
47
|
[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
|
|
40
48
|
[0.38.2-flask.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.1-flask.1...@metamask/snaps-utils@0.38.2-flask.1
|
|
41
49
|
[0.38.1-flask.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@0.38.0-flask.1...@metamask/snaps-utils@0.38.1-flask.1
|
package/dist/cjs/caveats.js
CHANGED
|
@@ -28,6 +28,9 @@ var SnapCaveatType;
|
|
|
28
28
|
SnapCaveatType[/**
|
|
29
29
|
* Caveat specifying the snap IDs that can be interacted with.
|
|
30
30
|
*/ "SnapIds"] = 'snapIds';
|
|
31
|
+
SnapCaveatType[/**
|
|
32
|
+
* Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.
|
|
33
|
+
*/ "ChainIds"] = 'chainIds';
|
|
31
34
|
})(SnapCaveatType || (SnapCaveatType = {}));
|
|
32
35
|
|
|
33
36
|
//# sourceMappingURL=caveats.js.map
|
package/dist/cjs/caveats.js.map
CHANGED
|
@@ -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"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","SnapIds"],"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;
|
|
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"}
|
package/dist/cjs/handlers.js
CHANGED
|
@@ -26,6 +26,7 @@ var HandlerType;
|
|
|
26
26
|
HandlerType["OnCronjob"] = 'onCronjob';
|
|
27
27
|
HandlerType["OnInstall"] = 'onInstall';
|
|
28
28
|
HandlerType["OnUpdate"] = 'onUpdate';
|
|
29
|
+
HandlerType["OnNameLookup"] = 'onNameLookup';
|
|
29
30
|
})(HandlerType || (HandlerType = {}));
|
|
30
31
|
const SNAP_EXPORTS = {
|
|
31
32
|
[HandlerType.OnRpcRequest]: {
|
|
@@ -49,6 +50,13 @@ const SNAP_EXPORTS = {
|
|
|
49
50
|
return typeof snapExport === 'function';
|
|
50
51
|
}
|
|
51
52
|
},
|
|
53
|
+
[HandlerType.OnNameLookup]: {
|
|
54
|
+
type: HandlerType.OnNameLookup,
|
|
55
|
+
required: true,
|
|
56
|
+
validator: (snapExport)=>{
|
|
57
|
+
return typeof snapExport === 'function';
|
|
58
|
+
}
|
|
59
|
+
},
|
|
52
60
|
[HandlerType.OnInstall]: {
|
|
53
61
|
type: HandlerType.OnInstall,
|
|
54
62
|
required: false,
|
package/dist/cjs/handlers.js.map
CHANGED
|
@@ -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';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\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.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 * 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","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":";;;;;;;;;;;;;;;;;
|
|
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"}
|
|
@@ -30,6 +30,9 @@ _export(exports, {
|
|
|
30
30
|
SnapIdsStruct: function() {
|
|
31
31
|
return SnapIdsStruct;
|
|
32
32
|
},
|
|
33
|
+
ChainIdsStruct: function() {
|
|
34
|
+
return ChainIdsStruct;
|
|
35
|
+
},
|
|
33
36
|
PermissionsStruct: function() {
|
|
34
37
|
return PermissionsStruct;
|
|
35
38
|
},
|
|
@@ -53,6 +56,7 @@ const _array = require("../array");
|
|
|
53
56
|
const _cronjob = require("../cronjob");
|
|
54
57
|
const _entropy = require("../entropy");
|
|
55
58
|
const _jsonrpc = require("../json-rpc");
|
|
59
|
+
const _namespace = require("../namespace");
|
|
56
60
|
const _snaps = require("../snaps");
|
|
57
61
|
const _types = require("../types");
|
|
58
62
|
// BIP-43 purposes that cannot be used for entropy derivation. These are in the
|
|
@@ -118,6 +122,7 @@ const SnapIdsStruct = (0, _superstruct.refine)((0, _superstruct.record)(_snaps.S
|
|
|
118
122
|
}
|
|
119
123
|
return true;
|
|
120
124
|
});
|
|
125
|
+
const ChainIdsStruct = (0, _superstruct.array)(_namespace.ChainIdStruct);
|
|
121
126
|
const PermissionsStruct = (0, _superstruct.type)({
|
|
122
127
|
'endowment:long-running': (0, _superstruct.optional)((0, _superstruct.object)({})),
|
|
123
128
|
'endowment:network-access': (0, _superstruct.optional)((0, _superstruct.object)({})),
|
|
@@ -129,6 +134,7 @@ const PermissionsStruct = (0, _superstruct.type)({
|
|
|
129
134
|
jobs: _cronjob.CronjobSpecificationArrayStruct
|
|
130
135
|
})),
|
|
131
136
|
'endowment:rpc': (0, _superstruct.optional)(_jsonrpc.RpcOriginsStruct),
|
|
137
|
+
'endowment:name-lookup': (0, _superstruct.optional)(ChainIdsStruct),
|
|
132
138
|
snap_dialog: (0, _superstruct.optional)((0, _superstruct.object)({})),
|
|
133
139
|
// TODO: Remove
|
|
134
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 { 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\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 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","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","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 { 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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"}
|
package/dist/cjs/namespace.js
CHANGED
|
@@ -15,6 +15,9 @@ _export(exports, {
|
|
|
15
15
|
ACCOUNT_ID_REGEX: function() {
|
|
16
16
|
return ACCOUNT_ID_REGEX;
|
|
17
17
|
},
|
|
18
|
+
ACCOUNT_ADDRESS_REGEX: function() {
|
|
19
|
+
return ACCOUNT_ADDRESS_REGEX;
|
|
20
|
+
},
|
|
18
21
|
parseChainId: function() {
|
|
19
22
|
return parseChainId;
|
|
20
23
|
},
|
|
@@ -33,6 +36,9 @@ _export(exports, {
|
|
|
33
36
|
AccountIdArrayStruct: function() {
|
|
34
37
|
return AccountIdArrayStruct;
|
|
35
38
|
},
|
|
39
|
+
AccountAddressStruct: function() {
|
|
40
|
+
return AccountAddressStruct;
|
|
41
|
+
},
|
|
36
42
|
ChainStruct: function() {
|
|
37
43
|
return ChainStruct;
|
|
38
44
|
},
|
|
@@ -61,6 +67,7 @@ _export(exports, {
|
|
|
61
67
|
const _superstruct = require("superstruct");
|
|
62
68
|
const CHAIN_ID_REGEX = RegExp("^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$", "u");
|
|
63
69
|
const ACCOUNT_ID_REGEX = RegExp("^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$", "u");
|
|
70
|
+
const ACCOUNT_ADDRESS_REGEX = RegExp("^(?<accountAddress>[a-zA-Z0-9]{1,64})$", "u");
|
|
64
71
|
function parseChainId(chainId) {
|
|
65
72
|
const match = CHAIN_ID_REGEX.exec(chainId);
|
|
66
73
|
if (!match?.groups) {
|
|
@@ -89,6 +96,7 @@ const LimitedString = (0, _superstruct.size)((0, _superstruct.string)(), 1, 40);
|
|
|
89
96
|
const ChainIdStruct = (0, _superstruct.pattern)((0, _superstruct.string)(), CHAIN_ID_REGEX);
|
|
90
97
|
const AccountIdStruct = (0, _superstruct.pattern)((0, _superstruct.string)(), ACCOUNT_ID_REGEX);
|
|
91
98
|
const AccountIdArrayStruct = (0, _superstruct.array)(AccountIdStruct);
|
|
99
|
+
const AccountAddressStruct = (0, _superstruct.pattern)((0, _superstruct.string)(), ACCOUNT_ADDRESS_REGEX);
|
|
92
100
|
const ChainStruct = (0, _superstruct.object)({
|
|
93
101
|
id: ChainIdStruct,
|
|
94
102
|
name: LimitedString
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/namespace.ts"],"sourcesContent":["import type { Infer } from 'superstruct';\nimport {\n array,\n is,\n object,\n optional,\n pattern,\n size,\n string,\n} from 'superstruct';\n\nexport const CHAIN_ID_REGEX =\n /^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$/u;\n\nexport const ACCOUNT_ID_REGEX =\n /^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\n/**\n * Parse a chain ID string to an object containing the namespace and reference.\n * This validates the chain ID before parsing it.\n *\n * @param chainId - The chain ID to validate and parse.\n * @returns The parsed chain ID.\n */\nexport function parseChainId(chainId: ChainId): {\n namespace: NamespaceId;\n reference: string;\n} {\n const match = CHAIN_ID_REGEX.exec(chainId);\n if (!match?.groups) {\n throw new Error('Invalid chain ID.');\n }\n\n return {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n };\n}\n\n/**\n * Parse an account ID to an object containing the chain, chain ID and address.\n * This validates the account ID before parsing it.\n *\n * @param accountId - The account ID to validate and parse.\n * @returns The parsed account ID.\n */\nexport function parseAccountId(accountId: AccountId): {\n chain: { namespace: NamespaceId; reference: string };\n chainId: ChainId;\n address: string;\n} {\n const match = ACCOUNT_ID_REGEX.exec(accountId);\n if (!match?.groups) {\n throw new Error('Invalid account ID.');\n }\n\n return {\n address: match.groups.accountAddress,\n chainId: match.groups.chainId as ChainId,\n chain: {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n },\n };\n}\n\n/**\n * A helper struct for a string with a minimum length of 1 and a maximum length\n * of 40.\n */\nexport const LimitedString = size(string(), 1, 40);\n\n/**\n * A CAIP-2 chain ID, i.e., a human-readable namespace and reference.\n */\nexport const ChainIdStruct = pattern(string(), CHAIN_ID_REGEX);\nexport type ChainId = `${string}:${string}`;\n\nexport const AccountIdStruct = pattern(string(), ACCOUNT_ID_REGEX);\nexport type AccountId = `${ChainId}:${string}`;\n\nexport const AccountIdArrayStruct = array(AccountIdStruct);\n\n/**\n * A chain descriptor.\n */\nexport const ChainStruct = object({\n id: ChainIdStruct,\n name: LimitedString,\n});\nexport type Chain = Infer<typeof ChainStruct>;\n\nexport const NamespaceStruct = object({\n /**\n * A list of supported chains in the namespace.\n */\n chains: array(ChainStruct),\n\n /**\n * A list of supported RPC methods on the namespace, that a DApp can call.\n */\n methods: optional(array(LimitedString)),\n\n /**\n * A list of supported RPC events on the namespace, that a DApp can listen to.\n */\n events: optional(array(LimitedString)),\n});\nexport type Namespace = Infer<typeof NamespaceStruct>;\n\n/**\n * A CAIP-2 namespace, i.e., the first part of a chain ID.\n */\nexport const NamespaceIdStruct = pattern(string(), /^[-a-z0-9]{3,8}$/u);\nexport type NamespaceId = Infer<typeof NamespaceIdStruct>;\n\n/**\n * Check if the given value is a CAIP-2 namespace ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 namespace ID.\n */\nexport function isNamespaceId(value: unknown): value is NamespaceId {\n return is(value, NamespaceIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-2 chain ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 chain ID.\n */\nexport function isChainId(value: unknown): value is ChainId {\n return is(value, ChainIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-10 account ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-10 account ID.\n */\nexport function isAccountId(value: unknown): value is AccountId {\n return is(value, AccountIdStruct);\n}\n\n/**\n * Check if the given value is an array of CAIP-10 account IDs.\n *\n * @param value - The value to check.\n * @returns Whether the value is an array of CAIP-10 account IDs.\n */\nexport function isAccountIdArray(value: unknown): value is AccountId[] {\n return is(value, AccountIdArrayStruct);\n}\n\n/**\n * Check if a value is a {@link Namespace}.\n *\n * @param value - The value to validate.\n * @returns True if the value is a valid {@link Namespace}.\n */\nexport function isNamespace(value: unknown): value is Namespace {\n return is(value, NamespaceStruct);\n}\n"],"names":["CHAIN_ID_REGEX","ACCOUNT_ID_REGEX","parseChainId","parseAccountId","LimitedString","ChainIdStruct","AccountIdStruct","AccountIdArrayStruct","ChainStruct","NamespaceStruct","NamespaceIdStruct","isNamespaceId","isChainId","isAccountId","isAccountIdArray","isNamespace","chainId","match","exec","groups","Error","namespace","reference","accountId","address","accountAddress","chain","size","string","pattern","array","object","id","name","chains","methods","optional","events","value","is"],"mappings":";;;;;;;;;;;IAWaA,cAAc;eAAdA;;IAGAC,gBAAgB;eAAhBA;;
|
|
1
|
+
{"version":3,"sources":["../../src/namespace.ts"],"sourcesContent":["import type { Infer } from 'superstruct';\nimport {\n array,\n is,\n object,\n optional,\n pattern,\n size,\n string,\n} from 'superstruct';\n\nexport const CHAIN_ID_REGEX =\n /^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$/u;\n\nexport const ACCOUNT_ID_REGEX =\n /^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\nexport const ACCOUNT_ADDRESS_REGEX = /^(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\n/**\n * Parse a chain ID string to an object containing the namespace and reference.\n * This validates the chain ID before parsing it.\n *\n * @param chainId - The chain ID to validate and parse.\n * @returns The parsed chain ID.\n */\nexport function parseChainId(chainId: ChainId): {\n namespace: NamespaceId;\n reference: string;\n} {\n const match = CHAIN_ID_REGEX.exec(chainId);\n if (!match?.groups) {\n throw new Error('Invalid chain ID.');\n }\n\n return {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n };\n}\n\n/**\n * Parse an account ID to an object containing the chain, chain ID and address.\n * This validates the account ID before parsing it.\n *\n * @param accountId - The account ID to validate and parse.\n * @returns The parsed account ID.\n */\nexport function parseAccountId(accountId: AccountId): {\n chain: { namespace: NamespaceId; reference: string };\n chainId: ChainId;\n address: string;\n} {\n const match = ACCOUNT_ID_REGEX.exec(accountId);\n if (!match?.groups) {\n throw new Error('Invalid account ID.');\n }\n\n return {\n address: match.groups.accountAddress,\n chainId: match.groups.chainId as ChainId,\n chain: {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n },\n };\n}\n\n/**\n * A helper struct for a string with a minimum length of 1 and a maximum length\n * of 40.\n */\nexport const LimitedString = size(string(), 1, 40);\n\n/**\n * A CAIP-2 chain ID, i.e., a human-readable namespace and reference.\n */\nexport const ChainIdStruct = pattern(string(), CHAIN_ID_REGEX);\nexport type ChainId = `${string}:${string}`;\nexport type Caip2ChainId = Infer<typeof ChainIdStruct>;\n\nexport const AccountIdStruct = pattern(string(), ACCOUNT_ID_REGEX);\nexport type AccountId = `${ChainId}:${string}`;\n\nexport const AccountIdArrayStruct = array(AccountIdStruct);\nexport const AccountAddressStruct = pattern(string(), ACCOUNT_ADDRESS_REGEX);\nexport type AccountAddress = Infer<typeof AccountAddressStruct>;\n\n/**\n * A chain descriptor.\n */\nexport const ChainStruct = object({\n id: ChainIdStruct,\n name: LimitedString,\n});\nexport type Chain = Infer<typeof ChainStruct>;\n\nexport const NamespaceStruct = object({\n /**\n * A list of supported chains in the namespace.\n */\n chains: array(ChainStruct),\n\n /**\n * A list of supported RPC methods on the namespace, that a DApp can call.\n */\n methods: optional(array(LimitedString)),\n\n /**\n * A list of supported RPC events on the namespace, that a DApp can listen to.\n */\n events: optional(array(LimitedString)),\n});\nexport type Namespace = Infer<typeof NamespaceStruct>;\n\n/**\n * A CAIP-2 namespace, i.e., the first part of a chain ID.\n */\nexport const NamespaceIdStruct = pattern(string(), /^[-a-z0-9]{3,8}$/u);\nexport type NamespaceId = Infer<typeof NamespaceIdStruct>;\n\n/**\n * Check if the given value is a CAIP-2 namespace ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 namespace ID.\n */\nexport function isNamespaceId(value: unknown): value is NamespaceId {\n return is(value, NamespaceIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-2 chain ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 chain ID.\n */\nexport function isChainId(value: unknown): value is ChainId {\n return is(value, ChainIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-10 account ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-10 account ID.\n */\nexport function isAccountId(value: unknown): value is AccountId {\n return is(value, AccountIdStruct);\n}\n\n/**\n * Check if the given value is an array of CAIP-10 account IDs.\n *\n * @param value - The value to check.\n * @returns Whether the value is an array of CAIP-10 account IDs.\n */\nexport function isAccountIdArray(value: unknown): value is AccountId[] {\n return is(value, AccountIdArrayStruct);\n}\n\n/**\n * Check if a value is a {@link Namespace}.\n *\n * @param value - The value to validate.\n * @returns True if the value is a valid {@link Namespace}.\n */\nexport function isNamespace(value: unknown): value is Namespace {\n return is(value, NamespaceStruct);\n}\n"],"names":["CHAIN_ID_REGEX","ACCOUNT_ID_REGEX","ACCOUNT_ADDRESS_REGEX","parseChainId","parseAccountId","LimitedString","ChainIdStruct","AccountIdStruct","AccountIdArrayStruct","AccountAddressStruct","ChainStruct","NamespaceStruct","NamespaceIdStruct","isNamespaceId","isChainId","isAccountId","isAccountIdArray","isNamespace","chainId","match","exec","groups","Error","namespace","reference","accountId","address","accountAddress","chain","size","string","pattern","array","object","id","name","chains","methods","optional","events","value","is"],"mappings":";;;;;;;;;;;IAWaA,cAAc;eAAdA;;IAGAC,gBAAgB;eAAhBA;;IAGAC,qBAAqB;eAArBA;;IASGC,YAAY;eAAZA;;IAsBAC,cAAc;eAAdA;;IAwBHC,aAAa;eAAbA;;IAKAC,aAAa;eAAbA;;IAIAC,eAAe;eAAfA;;IAGAC,oBAAoB;eAApBA;;IACAC,oBAAoB;eAApBA;;IAMAC,WAAW;eAAXA;;IAMAC,eAAe;eAAfA;;IAqBAC,iBAAiB;eAAjBA;;IASGC,aAAa;eAAbA;;IAUAC,SAAS;eAATA;;IAUAC,WAAW;eAAXA;;IAUAC,gBAAgB;eAAhBA;;IAUAC,WAAW;eAAXA;;;6BA9JT;AAEA,MAAMjB,iBACX;AAEK,MAAMC,mBACX;AAEK,MAAMC,wBAAwB;AAS9B,SAASC,aAAae,OAAgB;IAI3C,MAAMC,QAAQnB,eAAeoB,IAAI,CAACF;IAClC,IAAI,CAACC,OAAOE,QAAQ;QAClB,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;QACLC,WAAWJ,MAAME,MAAM,CAACE,SAAS;QACjCC,WAAWL,MAAME,MAAM,CAACG,SAAS;IACnC;AACF;AASO,SAASpB,eAAeqB,SAAoB;IAKjD,MAAMN,QAAQlB,iBAAiBmB,IAAI,CAACK;IACpC,IAAI,CAACN,OAAOE,QAAQ;QAClB,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;QACLI,SAASP,MAAME,MAAM,CAACM,cAAc;QACpCT,SAASC,MAAME,MAAM,CAACH,OAAO;QAC7BU,OAAO;YACLL,WAAWJ,MAAME,MAAM,CAACE,SAAS;YACjCC,WAAWL,MAAME,MAAM,CAACG,SAAS;QACnC;IACF;AACF;AAMO,MAAMnB,gBAAgBwB,IAAAA,iBAAI,EAACC,IAAAA,mBAAM,KAAI,GAAG;AAKxC,MAAMxB,gBAAgByB,IAAAA,oBAAO,EAACD,IAAAA,mBAAM,KAAI9B;AAIxC,MAAMO,kBAAkBwB,IAAAA,oBAAO,EAACD,IAAAA,mBAAM,KAAI7B;AAG1C,MAAMO,uBAAuBwB,IAAAA,kBAAK,EAACzB;AACnC,MAAME,uBAAuBsB,IAAAA,oBAAO,EAACD,IAAAA,mBAAM,KAAI5B;AAM/C,MAAMQ,cAAcuB,IAAAA,mBAAM,EAAC;IAChCC,IAAI5B;IACJ6B,MAAM9B;AACR;AAGO,MAAMM,kBAAkBsB,IAAAA,mBAAM,EAAC;IACpC;;GAEC,GACDG,QAAQJ,IAAAA,kBAAK,EAACtB;IAEd;;GAEC,GACD2B,SAASC,IAAAA,qBAAQ,EAACN,IAAAA,kBAAK,EAAC3B;IAExB;;GAEC,GACDkC,QAAQD,IAAAA,qBAAQ,EAACN,IAAAA,kBAAK,EAAC3B;AACzB;AAMO,MAAMO,oBAAoBmB,IAAAA,oBAAO,EAACD,IAAAA,mBAAM,KAAI;AAS5C,SAASjB,cAAc2B,KAAc;IAC1C,OAAOC,IAAAA,eAAE,EAACD,OAAO5B;AACnB;AAQO,SAASE,UAAU0B,KAAc;IACtC,OAAOC,IAAAA,eAAE,EAACD,OAAOlC;AACnB;AAQO,SAASS,YAAYyB,KAAc;IACxC,OAAOC,IAAAA,eAAE,EAACD,OAAOjC;AACnB;AAQO,SAASS,iBAAiBwB,KAAc;IAC7C,OAAOC,IAAAA,eAAE,EAACD,OAAOhC;AACnB;AAQO,SAASS,YAAYuB,KAAc;IACxC,OAAOC,IAAAA,eAAE,EAACD,OAAO7B;AACnB"}
|
package/dist/esm/caveats.js
CHANGED
|
@@ -18,6 +18,9 @@ export var SnapCaveatType;
|
|
|
18
18
|
SnapCaveatType[/**
|
|
19
19
|
* Caveat specifying the snap IDs that can be interacted with.
|
|
20
20
|
*/ "SnapIds"] = 'snapIds';
|
|
21
|
+
SnapCaveatType[/**
|
|
22
|
+
* Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.
|
|
23
|
+
*/ "ChainIds"] = 'chainIds';
|
|
21
24
|
})(SnapCaveatType || (SnapCaveatType = {}));
|
|
22
25
|
|
|
23
26
|
//# sourceMappingURL=caveats.js.map
|
package/dist/esm/caveats.js.map
CHANGED
|
@@ -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"],"names":["SnapCaveatType","PermittedDerivationPaths","PermittedCoinTypes","SnapCronjob","TransactionOrigin","RpcOrigin","SnapIds"],"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;
|
|
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"}
|
package/dist/esm/handlers.js
CHANGED
|
@@ -5,6 +5,7 @@ export var HandlerType;
|
|
|
5
5
|
HandlerType["OnCronjob"] = 'onCronjob';
|
|
6
6
|
HandlerType["OnInstall"] = 'onInstall';
|
|
7
7
|
HandlerType["OnUpdate"] = 'onUpdate';
|
|
8
|
+
HandlerType["OnNameLookup"] = 'onNameLookup';
|
|
8
9
|
})(HandlerType || (HandlerType = {}));
|
|
9
10
|
export const SNAP_EXPORTS = {
|
|
10
11
|
[HandlerType.OnRpcRequest]: {
|
|
@@ -28,6 +29,13 @@ export const SNAP_EXPORTS = {
|
|
|
28
29
|
return typeof snapExport === 'function';
|
|
29
30
|
}
|
|
30
31
|
},
|
|
32
|
+
[HandlerType.OnNameLookup]: {
|
|
33
|
+
type: HandlerType.OnNameLookup,
|
|
34
|
+
required: true,
|
|
35
|
+
validator: (snapExport)=>{
|
|
36
|
+
return typeof snapExport === 'function';
|
|
37
|
+
}
|
|
38
|
+
},
|
|
31
39
|
[HandlerType.OnInstall]: {
|
|
32
40
|
type: HandlerType.OnInstall,
|
|
33
41
|
required: false,
|
package/dist/esm/handlers.js.map
CHANGED
|
@@ -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';\n\nexport enum HandlerType {\n OnRpcRequest = 'onRpcRequest',\n OnTransaction = 'onTransaction',\n OnCronjob = 'onCronjob',\n OnInstall = 'onInstall',\n OnUpdate = 'onUpdate',\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.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 * 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","SNAP_EXPORTS","type","required","validator","snapExport","SeverityLevel","Critical"],"mappings":"
|
|
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"}
|
|
@@ -5,6 +5,7 @@ import { isEqual } from '../array';
|
|
|
5
5
|
import { CronjobSpecificationArrayStruct } from '../cronjob';
|
|
6
6
|
import { SIP_6_MAGIC_VALUE, STATE_ENCRYPTION_MAGIC_VALUE } from '../entropy';
|
|
7
7
|
import { RpcOriginsStruct } from '../json-rpc';
|
|
8
|
+
import { ChainIdStruct } from '../namespace';
|
|
8
9
|
import { SnapIdStruct } from '../snaps';
|
|
9
10
|
import { NameStruct, NpmSnapFileNames } from '../types';
|
|
10
11
|
// BIP-43 purposes that cannot be used for entropy derivation. These are in the
|
|
@@ -71,6 +72,7 @@ export const SnapIdsStruct = refine(record(SnapIdStruct, object({
|
|
|
71
72
|
}
|
|
72
73
|
return true;
|
|
73
74
|
});
|
|
75
|
+
export const ChainIdsStruct = array(ChainIdStruct);
|
|
74
76
|
/* eslint-disable @typescript-eslint/naming-convention */ export const PermissionsStruct = type({
|
|
75
77
|
'endowment:long-running': optional(object({})),
|
|
76
78
|
'endowment:network-access': optional(object({})),
|
|
@@ -82,6 +84,7 @@ export const SnapIdsStruct = refine(record(SnapIdStruct, object({
|
|
|
82
84
|
jobs: CronjobSpecificationArrayStruct
|
|
83
85
|
})),
|
|
84
86
|
'endowment:rpc': optional(RpcOriginsStruct),
|
|
87
|
+
'endowment:name-lookup': optional(ChainIdsStruct),
|
|
85
88
|
snap_dialog: optional(object({})),
|
|
86
89
|
// TODO: Remove
|
|
87
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 { 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\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 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","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","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 { 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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"}
|
package/dist/esm/namespace.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { array, is, object, optional, pattern, size, string } from 'superstruct';
|
|
2
2
|
export const CHAIN_ID_REGEX = RegExp("^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$", "u");
|
|
3
3
|
export const ACCOUNT_ID_REGEX = RegExp("^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$", "u");
|
|
4
|
+
export const ACCOUNT_ADDRESS_REGEX = RegExp("^(?<accountAddress>[a-zA-Z0-9]{1,64})$", "u");
|
|
4
5
|
/**
|
|
5
6
|
* Parse a chain ID string to an object containing the namespace and reference.
|
|
6
7
|
* This validates the chain ID before parsing it.
|
|
@@ -46,6 +47,7 @@ export const ACCOUNT_ID_REGEX = RegExp("^(?<chainId>(?<namespace>[-a-z0-9]{3,8})
|
|
|
46
47
|
*/ export const ChainIdStruct = pattern(string(), CHAIN_ID_REGEX);
|
|
47
48
|
export const AccountIdStruct = pattern(string(), ACCOUNT_ID_REGEX);
|
|
48
49
|
export const AccountIdArrayStruct = array(AccountIdStruct);
|
|
50
|
+
export const AccountAddressStruct = pattern(string(), ACCOUNT_ADDRESS_REGEX);
|
|
49
51
|
/**
|
|
50
52
|
* A chain descriptor.
|
|
51
53
|
*/ export const ChainStruct = object({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/namespace.ts"],"sourcesContent":["import type { Infer } from 'superstruct';\nimport {\n array,\n is,\n object,\n optional,\n pattern,\n size,\n string,\n} from 'superstruct';\n\nexport const CHAIN_ID_REGEX =\n /^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$/u;\n\nexport const ACCOUNT_ID_REGEX =\n /^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\n/**\n * Parse a chain ID string to an object containing the namespace and reference.\n * This validates the chain ID before parsing it.\n *\n * @param chainId - The chain ID to validate and parse.\n * @returns The parsed chain ID.\n */\nexport function parseChainId(chainId: ChainId): {\n namespace: NamespaceId;\n reference: string;\n} {\n const match = CHAIN_ID_REGEX.exec(chainId);\n if (!match?.groups) {\n throw new Error('Invalid chain ID.');\n }\n\n return {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n };\n}\n\n/**\n * Parse an account ID to an object containing the chain, chain ID and address.\n * This validates the account ID before parsing it.\n *\n * @param accountId - The account ID to validate and parse.\n * @returns The parsed account ID.\n */\nexport function parseAccountId(accountId: AccountId): {\n chain: { namespace: NamespaceId; reference: string };\n chainId: ChainId;\n address: string;\n} {\n const match = ACCOUNT_ID_REGEX.exec(accountId);\n if (!match?.groups) {\n throw new Error('Invalid account ID.');\n }\n\n return {\n address: match.groups.accountAddress,\n chainId: match.groups.chainId as ChainId,\n chain: {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n },\n };\n}\n\n/**\n * A helper struct for a string with a minimum length of 1 and a maximum length\n * of 40.\n */\nexport const LimitedString = size(string(), 1, 40);\n\n/**\n * A CAIP-2 chain ID, i.e., a human-readable namespace and reference.\n */\nexport const ChainIdStruct = pattern(string(), CHAIN_ID_REGEX);\nexport type ChainId = `${string}:${string}`;\n\nexport const AccountIdStruct = pattern(string(), ACCOUNT_ID_REGEX);\nexport type AccountId = `${ChainId}:${string}`;\n\nexport const AccountIdArrayStruct = array(AccountIdStruct);\n\n/**\n * A chain descriptor.\n */\nexport const ChainStruct = object({\n id: ChainIdStruct,\n name: LimitedString,\n});\nexport type Chain = Infer<typeof ChainStruct>;\n\nexport const NamespaceStruct = object({\n /**\n * A list of supported chains in the namespace.\n */\n chains: array(ChainStruct),\n\n /**\n * A list of supported RPC methods on the namespace, that a DApp can call.\n */\n methods: optional(array(LimitedString)),\n\n /**\n * A list of supported RPC events on the namespace, that a DApp can listen to.\n */\n events: optional(array(LimitedString)),\n});\nexport type Namespace = Infer<typeof NamespaceStruct>;\n\n/**\n * A CAIP-2 namespace, i.e., the first part of a chain ID.\n */\nexport const NamespaceIdStruct = pattern(string(), /^[-a-z0-9]{3,8}$/u);\nexport type NamespaceId = Infer<typeof NamespaceIdStruct>;\n\n/**\n * Check if the given value is a CAIP-2 namespace ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 namespace ID.\n */\nexport function isNamespaceId(value: unknown): value is NamespaceId {\n return is(value, NamespaceIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-2 chain ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 chain ID.\n */\nexport function isChainId(value: unknown): value is ChainId {\n return is(value, ChainIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-10 account ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-10 account ID.\n */\nexport function isAccountId(value: unknown): value is AccountId {\n return is(value, AccountIdStruct);\n}\n\n/**\n * Check if the given value is an array of CAIP-10 account IDs.\n *\n * @param value - The value to check.\n * @returns Whether the value is an array of CAIP-10 account IDs.\n */\nexport function isAccountIdArray(value: unknown): value is AccountId[] {\n return is(value, AccountIdArrayStruct);\n}\n\n/**\n * Check if a value is a {@link Namespace}.\n *\n * @param value - The value to validate.\n * @returns True if the value is a valid {@link Namespace}.\n */\nexport function isNamespace(value: unknown): value is Namespace {\n return is(value, NamespaceStruct);\n}\n"],"names":["array","is","object","optional","pattern","size","string","CHAIN_ID_REGEX","ACCOUNT_ID_REGEX","parseChainId","chainId","match","exec","groups","Error","namespace","reference","parseAccountId","accountId","address","accountAddress","chain","LimitedString","ChainIdStruct","AccountIdStruct","AccountIdArrayStruct","ChainStruct","id","name","NamespaceStruct","chains","methods","events","NamespaceIdStruct","isNamespaceId","value","isChainId","isAccountId","isAccountIdArray","isNamespace"],"mappings":"AACA,SACEA,KAAK,EACLC,EAAE,EACFC,MAAM,EACNC,QAAQ,EACRC,OAAO,EACPC,IAAI,EACJC,MAAM,QACD,cAAc;AAErB,OAAO,MAAMC,iBACX,+EAAmE;AAErE,OAAO,MAAMC,mBACX,gIAAoH;AAEtH;;;;;;CAMC,GACD,OAAO,SAASC,aAAaC,OAAgB;IAI3C,MAAMC,
|
|
1
|
+
{"version":3,"sources":["../../src/namespace.ts"],"sourcesContent":["import type { Infer } from 'superstruct';\nimport {\n array,\n is,\n object,\n optional,\n pattern,\n size,\n string,\n} from 'superstruct';\n\nexport const CHAIN_ID_REGEX =\n /^(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})$/u;\n\nexport const ACCOUNT_ID_REGEX =\n /^(?<chainId>(?<namespace>[-a-z0-9]{3,8}):(?<reference>[-a-zA-Z0-9]{1,32})):(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\nexport const ACCOUNT_ADDRESS_REGEX = /^(?<accountAddress>[a-zA-Z0-9]{1,64})$/u;\n\n/**\n * Parse a chain ID string to an object containing the namespace and reference.\n * This validates the chain ID before parsing it.\n *\n * @param chainId - The chain ID to validate and parse.\n * @returns The parsed chain ID.\n */\nexport function parseChainId(chainId: ChainId): {\n namespace: NamespaceId;\n reference: string;\n} {\n const match = CHAIN_ID_REGEX.exec(chainId);\n if (!match?.groups) {\n throw new Error('Invalid chain ID.');\n }\n\n return {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n };\n}\n\n/**\n * Parse an account ID to an object containing the chain, chain ID and address.\n * This validates the account ID before parsing it.\n *\n * @param accountId - The account ID to validate and parse.\n * @returns The parsed account ID.\n */\nexport function parseAccountId(accountId: AccountId): {\n chain: { namespace: NamespaceId; reference: string };\n chainId: ChainId;\n address: string;\n} {\n const match = ACCOUNT_ID_REGEX.exec(accountId);\n if (!match?.groups) {\n throw new Error('Invalid account ID.');\n }\n\n return {\n address: match.groups.accountAddress,\n chainId: match.groups.chainId as ChainId,\n chain: {\n namespace: match.groups.namespace,\n reference: match.groups.reference,\n },\n };\n}\n\n/**\n * A helper struct for a string with a minimum length of 1 and a maximum length\n * of 40.\n */\nexport const LimitedString = size(string(), 1, 40);\n\n/**\n * A CAIP-2 chain ID, i.e., a human-readable namespace and reference.\n */\nexport const ChainIdStruct = pattern(string(), CHAIN_ID_REGEX);\nexport type ChainId = `${string}:${string}`;\nexport type Caip2ChainId = Infer<typeof ChainIdStruct>;\n\nexport const AccountIdStruct = pattern(string(), ACCOUNT_ID_REGEX);\nexport type AccountId = `${ChainId}:${string}`;\n\nexport const AccountIdArrayStruct = array(AccountIdStruct);\nexport const AccountAddressStruct = pattern(string(), ACCOUNT_ADDRESS_REGEX);\nexport type AccountAddress = Infer<typeof AccountAddressStruct>;\n\n/**\n * A chain descriptor.\n */\nexport const ChainStruct = object({\n id: ChainIdStruct,\n name: LimitedString,\n});\nexport type Chain = Infer<typeof ChainStruct>;\n\nexport const NamespaceStruct = object({\n /**\n * A list of supported chains in the namespace.\n */\n chains: array(ChainStruct),\n\n /**\n * A list of supported RPC methods on the namespace, that a DApp can call.\n */\n methods: optional(array(LimitedString)),\n\n /**\n * A list of supported RPC events on the namespace, that a DApp can listen to.\n */\n events: optional(array(LimitedString)),\n});\nexport type Namespace = Infer<typeof NamespaceStruct>;\n\n/**\n * A CAIP-2 namespace, i.e., the first part of a chain ID.\n */\nexport const NamespaceIdStruct = pattern(string(), /^[-a-z0-9]{3,8}$/u);\nexport type NamespaceId = Infer<typeof NamespaceIdStruct>;\n\n/**\n * Check if the given value is a CAIP-2 namespace ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 namespace ID.\n */\nexport function isNamespaceId(value: unknown): value is NamespaceId {\n return is(value, NamespaceIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-2 chain ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-2 chain ID.\n */\nexport function isChainId(value: unknown): value is ChainId {\n return is(value, ChainIdStruct);\n}\n\n/**\n * Check if the given value is a CAIP-10 account ID.\n *\n * @param value - The value to check.\n * @returns Whether the value is a CAIP-10 account ID.\n */\nexport function isAccountId(value: unknown): value is AccountId {\n return is(value, AccountIdStruct);\n}\n\n/**\n * Check if the given value is an array of CAIP-10 account IDs.\n *\n * @param value - The value to check.\n * @returns Whether the value is an array of CAIP-10 account IDs.\n */\nexport function isAccountIdArray(value: unknown): value is AccountId[] {\n return is(value, AccountIdArrayStruct);\n}\n\n/**\n * Check if a value is a {@link Namespace}.\n *\n * @param value - The value to validate.\n * @returns True if the value is a valid {@link Namespace}.\n */\nexport function isNamespace(value: unknown): value is Namespace {\n return is(value, NamespaceStruct);\n}\n"],"names":["array","is","object","optional","pattern","size","string","CHAIN_ID_REGEX","ACCOUNT_ID_REGEX","ACCOUNT_ADDRESS_REGEX","parseChainId","chainId","match","exec","groups","Error","namespace","reference","parseAccountId","accountId","address","accountAddress","chain","LimitedString","ChainIdStruct","AccountIdStruct","AccountIdArrayStruct","AccountAddressStruct","ChainStruct","id","name","NamespaceStruct","chains","methods","events","NamespaceIdStruct","isNamespaceId","value","isChainId","isAccountId","isAccountIdArray","isNamespace"],"mappings":"AACA,SACEA,KAAK,EACLC,EAAE,EACFC,MAAM,EACNC,QAAQ,EACRC,OAAO,EACPC,IAAI,EACJC,MAAM,QACD,cAAc;AAErB,OAAO,MAAMC,iBACX,+EAAmE;AAErE,OAAO,MAAMC,mBACX,gIAAoH;AAEtH,OAAO,MAAMC,wBAAwB,sDAA0C;AAE/E;;;;;;CAMC,GACD,OAAO,SAASC,aAAaC,OAAgB;IAI3C,MAAMC,QAAQL,eAAeM,IAAI,CAACF;IAClC,IAAI,CAACC,OAAOE,QAAQ;QAClB,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;QACLC,WAAWJ,MAAME,MAAM,CAACE,SAAS;QACjCC,WAAWL,MAAME,MAAM,CAACG,SAAS;IACnC;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,eAAeC,SAAoB;IAKjD,MAAMP,QAAQJ,iBAAiBK,IAAI,CAACM;IACpC,IAAI,CAACP,OAAOE,QAAQ;QAClB,MAAM,IAAIC,MAAM;IAClB;IAEA,OAAO;QACLK,SAASR,MAAME,MAAM,CAACO,cAAc;QACpCV,SAASC,MAAME,MAAM,CAACH,OAAO;QAC7BW,OAAO;YACLN,WAAWJ,MAAME,MAAM,CAACE,SAAS;YACjCC,WAAWL,MAAME,MAAM,CAACG,SAAS;QACnC;IACF;AACF;AAEA;;;CAGC,GACD,OAAO,MAAMM,gBAAgBlB,KAAKC,UAAU,GAAG,IAAI;AAEnD;;CAEC,GACD,OAAO,MAAMkB,gBAAgBpB,QAAQE,UAAUC,gBAAgB;AAI/D,OAAO,MAAMkB,kBAAkBrB,QAAQE,UAAUE,kBAAkB;AAGnE,OAAO,MAAMkB,uBAAuB1B,MAAMyB,iBAAiB;AAC3D,OAAO,MAAME,uBAAuBvB,QAAQE,UAAUG,uBAAuB;AAG7E;;CAEC,GACD,OAAO,MAAMmB,cAAc1B,OAAO;IAChC2B,IAAIL;IACJM,MAAMP;AACR,GAAG;AAGH,OAAO,MAAMQ,kBAAkB7B,OAAO;IACpC;;GAEC,GACD8B,QAAQhC,MAAM4B;IAEd;;GAEC,GACDK,SAAS9B,SAASH,MAAMuB;IAExB;;GAEC,GACDW,QAAQ/B,SAASH,MAAMuB;AACzB,GAAG;AAGH;;CAEC,GACD,OAAO,MAAMY,oBAAoB/B,QAAQE,UAAU,qBAAqB;AAGxE;;;;;CAKC,GACD,OAAO,SAAS8B,cAAcC,KAAc;IAC1C,OAAOpC,GAAGoC,OAAOF;AACnB;AAEA;;;;;CAKC,GACD,OAAO,SAASG,UAAUD,KAAc;IACtC,OAAOpC,GAAGoC,OAAOb;AACnB;AAEA;;;;;CAKC,GACD,OAAO,SAASe,YAAYF,KAAc;IACxC,OAAOpC,GAAGoC,OAAOZ;AACnB;AAEA;;;;;CAKC,GACD,OAAO,SAASe,iBAAiBH,KAAc;IAC7C,OAAOpC,GAAGoC,OAAOX;AACnB;AAEA;;;;;CAKC,GACD,OAAO,SAASe,YAAYJ,KAAc;IACxC,OAAOpC,GAAGoC,OAAON;AACnB"}
|
package/dist/types/caveats.d.ts
CHANGED
|
@@ -22,5 +22,9 @@ export declare enum SnapCaveatType {
|
|
|
22
22
|
/**
|
|
23
23
|
* Caveat specifying the snap IDs that can be interacted with.
|
|
24
24
|
*/
|
|
25
|
-
SnapIds = "snapIds"
|
|
25
|
+
SnapIds = "snapIds",
|
|
26
|
+
/**
|
|
27
|
+
* Caveat specifying the CAIP-2 chain IDs that a snap can service, currently limited to `endowment:name-lookup`.
|
|
28
|
+
*/
|
|
29
|
+
ChainIds = "chainIds"
|
|
26
30
|
}
|
package/dist/types/handlers.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { Component } from '@metamask/snaps-ui';
|
|
2
2
|
import type { Json, JsonRpcParams, JsonRpcRequest } from '@metamask/utils';
|
|
3
3
|
import type { EnumToUnion } from './enum';
|
|
4
|
+
import type { AccountAddress, Caip2ChainId } from './namespace';
|
|
4
5
|
export declare enum HandlerType {
|
|
5
6
|
OnRpcRequest = "onRpcRequest",
|
|
6
7
|
OnTransaction = "onTransaction",
|
|
7
8
|
OnCronjob = "onCronjob",
|
|
8
9
|
OnInstall = "onInstall",
|
|
9
|
-
OnUpdate = "onUpdate"
|
|
10
|
+
OnUpdate = "onUpdate",
|
|
11
|
+
OnNameLookup = "onNameLookup"
|
|
10
12
|
}
|
|
11
13
|
declare type SnapHandler = {
|
|
12
14
|
/**
|
|
@@ -33,7 +35,7 @@ export declare const SNAP_EXPORTS: {
|
|
|
33
35
|
readonly onRpcRequest: {
|
|
34
36
|
readonly type: HandlerType.OnRpcRequest;
|
|
35
37
|
readonly required: true;
|
|
36
|
-
readonly validator: (snapExport: unknown) => snapExport is OnRpcRequestHandler<
|
|
38
|
+
readonly validator: (snapExport: unknown) => snapExport is OnRpcRequestHandler<JsonRpcParams>;
|
|
37
39
|
};
|
|
38
40
|
readonly onTransaction: {
|
|
39
41
|
readonly type: HandlerType.OnTransaction;
|
|
@@ -43,7 +45,12 @@ export declare const SNAP_EXPORTS: {
|
|
|
43
45
|
readonly onCronjob: {
|
|
44
46
|
readonly type: HandlerType.OnCronjob;
|
|
45
47
|
readonly required: true;
|
|
46
|
-
readonly validator: (snapExport: unknown) => snapExport is OnCronjobHandler<
|
|
48
|
+
readonly validator: (snapExport: unknown) => snapExport is OnCronjobHandler<JsonRpcParams>;
|
|
49
|
+
};
|
|
50
|
+
readonly onNameLookup: {
|
|
51
|
+
readonly type: HandlerType.OnNameLookup;
|
|
52
|
+
readonly required: true;
|
|
53
|
+
readonly validator: (snapExport: unknown) => snapExport is OnNameLookupHandler;
|
|
47
54
|
};
|
|
48
55
|
readonly onInstall: {
|
|
49
56
|
readonly type: HandlerType.OnInstall;
|
|
@@ -139,6 +146,43 @@ export declare type OnUpdateHandler = LifecycleEventHandler;
|
|
|
139
146
|
* Utility type for getting the handler function type from a handler type.
|
|
140
147
|
*/
|
|
141
148
|
export declare type HandlerFunction<Type extends SnapHandler> = Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler ? Handler : never;
|
|
149
|
+
/**
|
|
150
|
+
* The response from a snap's `onNameLookup` handler.
|
|
151
|
+
*
|
|
152
|
+
* @property resolvedAddress - The resolved address for a given domain.
|
|
153
|
+
* @property resolvedDomain - The resolved domain for a given address.
|
|
154
|
+
*
|
|
155
|
+
*
|
|
156
|
+
* If the snap has no resolved address/domain from its lookup, this should be `null`.
|
|
157
|
+
*/
|
|
158
|
+
export declare type OnNameLookupResponse = {
|
|
159
|
+
resolvedAddress: AccountAddress;
|
|
160
|
+
resolvedDomain?: never;
|
|
161
|
+
} | {
|
|
162
|
+
resolvedDomain: string;
|
|
163
|
+
resolvedAddress?: never;
|
|
164
|
+
} | null;
|
|
165
|
+
export declare type OnNameLookupArgs = {
|
|
166
|
+
chainId: Caip2ChainId;
|
|
167
|
+
} & ({
|
|
168
|
+
domain: string;
|
|
169
|
+
address?: never;
|
|
170
|
+
} | {
|
|
171
|
+
address: string;
|
|
172
|
+
domain?: never;
|
|
173
|
+
});
|
|
174
|
+
/**
|
|
175
|
+
* The `onNameLookup` handler. This is called whenever content is entered
|
|
176
|
+
* into the send to field for sending assets to an EOA address.
|
|
177
|
+
*
|
|
178
|
+
* @param args - The request arguments.
|
|
179
|
+
* @param args.domain - The human-readable address that is to be resolved.
|
|
180
|
+
* @param args.chainId - The CAIP-2 chain ID of the network the transaction is
|
|
181
|
+
* being submitted to.
|
|
182
|
+
* @param args.address - The address that is to be resolved.
|
|
183
|
+
* @returns Resolved address/domain from the lookup. See {@link OnNameLookupResponse}.
|
|
184
|
+
*/
|
|
185
|
+
export declare type OnNameLookupHandler = (args: OnNameLookupArgs) => Promise<OnNameLookupResponse>;
|
|
142
186
|
/**
|
|
143
187
|
* All the function-based handlers that a snap can implement.
|
|
144
188
|
*/
|
|
@@ -34,6 +34,7 @@ export declare const SnapIdsStruct: Struct<Record<string, {
|
|
|
34
34
|
version?: string | undefined;
|
|
35
35
|
}>, null>;
|
|
36
36
|
export declare type SnapIds = Infer<typeof SnapIdsStruct>;
|
|
37
|
+
export declare const ChainIdsStruct: Struct<string[], Struct<string, null>>;
|
|
37
38
|
export declare const PermissionsStruct: Struct<{
|
|
38
39
|
'endowment:long-running'?: {} | undefined;
|
|
39
40
|
'endowment:network-access'?: {} | undefined;
|
|
@@ -56,6 +57,7 @@ export declare const PermissionsStruct: Struct<{
|
|
|
56
57
|
dapps?: boolean | undefined;
|
|
57
58
|
snaps?: boolean | undefined;
|
|
58
59
|
} | undefined;
|
|
60
|
+
'endowment:name-lookup'?: string[] | undefined;
|
|
59
61
|
snap_dialog?: {} | undefined;
|
|
60
62
|
snap_confirm?: {} | undefined;
|
|
61
63
|
snap_manageState?: {} | undefined;
|
|
@@ -134,6 +136,7 @@ export declare const PermissionsStruct: Struct<{
|
|
|
134
136
|
dapps: Struct<boolean | undefined, null>;
|
|
135
137
|
snaps: Struct<boolean | undefined, null>;
|
|
136
138
|
}>;
|
|
139
|
+
'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
|
|
137
140
|
snap_dialog: Struct<{} | undefined, {}>;
|
|
138
141
|
snap_confirm: Struct<{} | undefined, {}>;
|
|
139
142
|
snap_manageState: Struct<{} | undefined, {}>;
|
|
@@ -215,6 +218,7 @@ export declare const SnapManifestStruct: Struct<{
|
|
|
215
218
|
dapps?: boolean | undefined;
|
|
216
219
|
snaps?: boolean | undefined;
|
|
217
220
|
} | undefined;
|
|
221
|
+
'endowment:name-lookup'?: string[] | undefined;
|
|
218
222
|
snap_dialog?: {} | undefined;
|
|
219
223
|
snap_confirm?: {} | undefined;
|
|
220
224
|
snap_manageState?: {} | undefined;
|
|
@@ -308,6 +312,7 @@ export declare const SnapManifestStruct: Struct<{
|
|
|
308
312
|
dapps?: boolean | undefined;
|
|
309
313
|
snaps?: boolean | undefined;
|
|
310
314
|
} | undefined;
|
|
315
|
+
'endowment:name-lookup'?: string[] | undefined;
|
|
311
316
|
snap_dialog?: {} | undefined;
|
|
312
317
|
snap_confirm?: {} | undefined;
|
|
313
318
|
snap_manageState?: {} | undefined;
|
|
@@ -386,6 +391,7 @@ export declare const SnapManifestStruct: Struct<{
|
|
|
386
391
|
dapps: Struct<boolean | undefined, null>;
|
|
387
392
|
snaps: Struct<boolean | undefined, null>;
|
|
388
393
|
}>;
|
|
394
|
+
'endowment:name-lookup': Struct<string[] | undefined, Struct<string, null>>;
|
|
389
395
|
snap_dialog: Struct<{} | undefined, {}>;
|
|
390
396
|
snap_confirm: Struct<{} | undefined, {}>;
|
|
391
397
|
snap_manageState: Struct<{} | undefined, {}>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Infer } from 'superstruct';
|
|
2
2
|
export declare const CHAIN_ID_REGEX: RegExp;
|
|
3
3
|
export declare const ACCOUNT_ID_REGEX: RegExp;
|
|
4
|
+
export declare const ACCOUNT_ADDRESS_REGEX: RegExp;
|
|
4
5
|
/**
|
|
5
6
|
* Parse a chain ID string to an object containing the namespace and reference.
|
|
6
7
|
* This validates the chain ID before parsing it.
|
|
@@ -37,9 +38,12 @@ export declare const LimitedString: import("superstruct").Struct<string, null>;
|
|
|
37
38
|
*/
|
|
38
39
|
export declare const ChainIdStruct: import("superstruct").Struct<string, null>;
|
|
39
40
|
export declare type ChainId = `${string}:${string}`;
|
|
41
|
+
export declare type Caip2ChainId = Infer<typeof ChainIdStruct>;
|
|
40
42
|
export declare const AccountIdStruct: import("superstruct").Struct<string, null>;
|
|
41
43
|
export declare type AccountId = `${ChainId}:${string}`;
|
|
42
44
|
export declare const AccountIdArrayStruct: import("superstruct").Struct<string[], import("superstruct").Struct<string, null>>;
|
|
45
|
+
export declare const AccountAddressStruct: import("superstruct").Struct<string, null>;
|
|
46
|
+
export declare type AccountAddress = Infer<typeof AccountAddressStruct>;
|
|
43
47
|
/**
|
|
44
48
|
* A chain descriptor.
|
|
45
49
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/snaps-utils",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.4-flask.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/MetaMask/snaps.git"
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
"@metamask/base-controller": "^3.2.0",
|
|
72
72
|
"@metamask/key-tree": "^9.0.0",
|
|
73
73
|
"@metamask/permission-controller": "^4.1.0",
|
|
74
|
-
"@metamask/snaps-registry": "^
|
|
75
|
-
"@metamask/snaps-ui": "^0.37.
|
|
76
|
-
"@metamask/utils": "^
|
|
74
|
+
"@metamask/snaps-registry": "^2.0.0",
|
|
75
|
+
"@metamask/snaps-ui": "^0.37.5-flask.1",
|
|
76
|
+
"@metamask/utils": "^8.1.0",
|
|
77
77
|
"@noble/hashes": "^1.3.1",
|
|
78
78
|
"@scure/base": "^1.1.1",
|
|
79
79
|
"chalk": "^4.1.2",
|