@metamask/snaps-utils 9.2.2 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/dist/account.cjs +53 -0
  3. package/dist/account.cjs.map +1 -1
  4. package/dist/account.d.cts +26 -1
  5. package/dist/account.d.cts.map +1 -1
  6. package/dist/account.d.mts +26 -1
  7. package/dist/account.d.mts.map +1 -1
  8. package/dist/account.mjs +49 -1
  9. package/dist/account.mjs.map +1 -1
  10. package/dist/eval-worker.cjs +38 -11
  11. package/dist/eval-worker.cjs.map +1 -1
  12. package/dist/eval-worker.d.cts.map +1 -1
  13. package/dist/eval-worker.d.mts.map +1 -1
  14. package/dist/eval-worker.mjs +38 -11
  15. package/dist/eval-worker.mjs.map +1 -1
  16. package/dist/eval.cjs +6 -0
  17. package/dist/eval.cjs.map +1 -1
  18. package/dist/eval.d.cts +7 -0
  19. package/dist/eval.d.cts.map +1 -1
  20. package/dist/eval.d.mts +7 -0
  21. package/dist/eval.d.mts.map +1 -1
  22. package/dist/eval.mjs +6 -0
  23. package/dist/eval.mjs.map +1 -1
  24. package/dist/fs.cjs +51 -6
  25. package/dist/fs.cjs.map +1 -1
  26. package/dist/fs.d.cts +16 -4
  27. package/dist/fs.d.cts.map +1 -1
  28. package/dist/fs.d.mts +16 -4
  29. package/dist/fs.d.mts.map +1 -1
  30. package/dist/fs.mjs +49 -5
  31. package/dist/fs.mjs.map +1 -1
  32. package/dist/handlers/exports.cjs +7 -0
  33. package/dist/handlers/exports.cjs.map +1 -1
  34. package/dist/handlers/exports.d.cts +6 -1
  35. package/dist/handlers/exports.d.cts.map +1 -1
  36. package/dist/handlers/exports.d.mts +6 -1
  37. package/dist/handlers/exports.d.mts.map +1 -1
  38. package/dist/handlers/exports.mjs +7 -0
  39. package/dist/handlers/exports.mjs.map +1 -1
  40. package/dist/handlers/home-page.d.cts +3 -3
  41. package/dist/handlers/home-page.d.mts +3 -3
  42. package/dist/handlers/settings-page.d.cts +1 -1
  43. package/dist/handlers/settings-page.d.mts +1 -1
  44. package/dist/handlers/signature.d.cts +1 -1
  45. package/dist/handlers/signature.d.mts +1 -1
  46. package/dist/handlers/transaction.d.cts +3 -3
  47. package/dist/handlers/transaction.d.mts +3 -3
  48. package/dist/handlers/types.cjs +1 -0
  49. package/dist/handlers/types.cjs.map +1 -1
  50. package/dist/handlers/types.d.cts +2 -1
  51. package/dist/handlers/types.d.cts.map +1 -1
  52. package/dist/handlers/types.d.mts +2 -1
  53. package/dist/handlers/types.d.mts.map +1 -1
  54. package/dist/handlers/types.mjs +1 -0
  55. package/dist/handlers/types.mjs.map +1 -1
  56. package/dist/index.cjs +1 -0
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.cts +1 -1
  59. package/dist/index.d.cts.map +1 -1
  60. package/dist/index.d.mts +1 -1
  61. package/dist/index.d.mts.map +1 -1
  62. package/dist/index.mjs +1 -0
  63. package/dist/index.mjs.map +1 -1
  64. package/dist/manifest/manifest.cjs +36 -4
  65. package/dist/manifest/manifest.cjs.map +1 -1
  66. package/dist/manifest/manifest.d.cts +40 -7
  67. package/dist/manifest/manifest.d.cts.map +1 -1
  68. package/dist/manifest/manifest.d.mts +40 -7
  69. package/dist/manifest/manifest.d.mts.map +1 -1
  70. package/dist/manifest/manifest.mjs +13 -4
  71. package/dist/manifest/manifest.mjs.map +1 -1
  72. package/dist/manifest/validator-types.cjs.map +1 -1
  73. package/dist/manifest/validator-types.d.cts +18 -1
  74. package/dist/manifest/validator-types.d.cts.map +1 -1
  75. package/dist/manifest/validator-types.d.mts +18 -1
  76. package/dist/manifest/validator-types.d.mts.map +1 -1
  77. package/dist/manifest/validator-types.mjs.map +1 -1
  78. package/dist/manifest/validator.cjs +23 -10
  79. package/dist/manifest/validator.cjs.map +1 -1
  80. package/dist/manifest/validator.d.cts +4 -2
  81. package/dist/manifest/validator.d.cts.map +1 -1
  82. package/dist/manifest/validator.d.mts +4 -2
  83. package/dist/manifest/validator.d.mts.map +1 -1
  84. package/dist/manifest/validator.mjs +23 -10
  85. package/dist/manifest/validator.mjs.map +1 -1
  86. package/dist/manifest/validators/index.cjs +2 -0
  87. package/dist/manifest/validators/index.cjs.map +1 -1
  88. package/dist/manifest/validators/index.d.cts +2 -0
  89. package/dist/manifest/validators/index.d.cts.map +1 -1
  90. package/dist/manifest/validators/index.d.mts +2 -0
  91. package/dist/manifest/validators/index.d.mts.map +1 -1
  92. package/dist/manifest/validators/index.mjs +2 -0
  93. package/dist/manifest/validators/index.mjs.map +1 -1
  94. package/dist/manifest/validators/production-platform-version.cjs +47 -0
  95. package/dist/manifest/validators/production-platform-version.cjs.map +1 -0
  96. package/dist/manifest/validators/production-platform-version.d.cts +7 -0
  97. package/dist/manifest/validators/production-platform-version.d.cts.map +1 -0
  98. package/dist/manifest/validators/production-platform-version.d.mts +7 -0
  99. package/dist/manifest/validators/production-platform-version.d.mts.map +1 -0
  100. package/dist/manifest/validators/production-platform-version.mjs +44 -0
  101. package/dist/manifest/validators/production-platform-version.mjs.map +1 -0
  102. package/dist/manifest/validators/unused-exports.cjs +53 -0
  103. package/dist/manifest/validators/unused-exports.cjs.map +1 -0
  104. package/dist/manifest/validators/unused-exports.d.cts +7 -0
  105. package/dist/manifest/validators/unused-exports.d.cts.map +1 -0
  106. package/dist/manifest/validators/unused-exports.d.mts +7 -0
  107. package/dist/manifest/validators/unused-exports.d.mts.map +1 -0
  108. package/dist/manifest/validators/unused-exports.mjs +50 -0
  109. package/dist/manifest/validators/unused-exports.mjs.map +1 -0
  110. package/dist/time.cjs +15 -1
  111. package/dist/time.cjs.map +1 -1
  112. package/dist/time.d.cts +7 -0
  113. package/dist/time.d.cts.map +1 -1
  114. package/dist/time.d.mts +7 -0
  115. package/dist/time.d.mts.map +1 -1
  116. package/dist/time.mjs +13 -0
  117. package/dist/time.mjs.map +1 -1
  118. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [9.4.0]
11
+
12
+ ### Added
13
+
14
+ - Validate platform version against production ([#3417](https://github.com/MetaMask/snaps/pull/3417))
15
+ - Detect unused permissions in Snaps CLI ([#3335](https://github.com/MetaMask/snaps/pull/3335))
16
+ - Add support for `AccountSelector` component ([#3088](https://github.com/MetaMask/snaps/pull/3088))
17
+ - Add `toCensoredISO8601String` util function ([#3414](https://github.com/MetaMask/snaps/pull/3414))
18
+
19
+ ### Changed
20
+
21
+ - Bump `@metamask/slip44` from `4.1.0` to `4.2.0` ([#3419](https://github.com/MetaMask/snaps/pull/3419))
22
+
23
+ ## [9.3.0]
24
+
25
+ ### Added
26
+
27
+ - Add support for SIP-31 `onClientRequest` handler ([#3394](https://github.com/MetaMask/snaps/pull/3394))
28
+
10
29
  ## [9.2.2]
11
30
 
12
31
  ### Changed
@@ -604,7 +623,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
604
623
  - The version of the package no longer needs to match the version of all other
605
624
  MetaMask Snaps packages.
606
625
 
607
- [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.2.2...HEAD
626
+ [Unreleased]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.4.0...HEAD
627
+ [9.4.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.3.0...@metamask/snaps-utils@9.4.0
628
+ [9.3.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.2.2...@metamask/snaps-utils@9.3.0
608
629
  [9.2.2]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.2.1...@metamask/snaps-utils@9.2.2
609
630
  [9.2.1]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.2.0...@metamask/snaps-utils@9.2.1
610
631
  [9.2.0]: https://github.com/MetaMask/snaps/compare/@metamask/snaps-utils@9.1.0...@metamask/snaps-utils@9.2.0
package/dist/account.cjs CHANGED
@@ -1,3 +1,56 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.snapOwnsAccount = exports.createChainIdList = exports.createAccountList = void 0;
4
+ const utils_1 = require("@metamask/utils");
5
+ /**
6
+ * Create a list of CAIP account IDs from an address and a list of scopes.
7
+ *
8
+ * @param address - The address to create the account IDs from.
9
+ * @param scopes - The scopes to create the account IDs from.
10
+ * @returns The list of CAIP account IDs.
11
+ */
12
+ function createAccountList(address, scopes) {
13
+ return scopes.map((scope) => `${scope}:${address}`);
14
+ }
15
+ exports.createAccountList = createAccountList;
16
+ /**
17
+ * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.
18
+ *
19
+ * @param accountScopes - The account scopes to create the chain ID list from.
20
+ * @param requestedChainIds - The requested chain IDs to filter the account scopes by.
21
+ * @returns The list of CAIP chain IDs.
22
+ */
23
+ function createChainIdList(accountScopes, requestedChainIds) {
24
+ // If there are no requested chain IDs, return all account scopes.
25
+ if (!requestedChainIds || requestedChainIds.length === 0) {
26
+ return accountScopes;
27
+ }
28
+ return accountScopes.reduce((acc, scope) => {
29
+ // If the scope represents all EVM compatible chains, return all requested chain IDs.
30
+ if (scope === 'eip155:0') {
31
+ const evmChainIds = requestedChainIds.filter((chainId) => {
32
+ const { namespace } = (0, utils_1.parseCaipChainId)(chainId);
33
+ return namespace === utils_1.KnownCaipNamespace.Eip155;
34
+ });
35
+ acc.push(...evmChainIds);
36
+ }
37
+ // If the scope is not in the requested chain IDs, skip it.
38
+ else if (requestedChainIds.includes(scope)) {
39
+ acc.push(scope);
40
+ }
41
+ return acc;
42
+ }, []);
43
+ }
44
+ exports.createChainIdList = createChainIdList;
45
+ /**
46
+ * Whether if the snap owns the account.
47
+ *
48
+ * @param snapId - The snap id.
49
+ * @param account - The account.
50
+ * @returns True if the snap owns the account, otherwise false.
51
+ */
52
+ function snapOwnsAccount(snapId, account) {
53
+ return account.metadata.snap?.id === snapId;
54
+ }
55
+ exports.snapOwnsAccount = snapOwnsAccount;
3
56
  //# sourceMappingURL=account.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"account.cjs","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"","sourcesContent":["import type { SnapId } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\n\n/**\n * Copy of the original type from\n * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts\n */\nexport type InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n"]}
1
+ {"version":3,"file":"account.cjs","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":";;;AAEA,2CAAuE;AAmBvE;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAC/B,OAAe,EACf,MAAqB;IAErB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,EAAE,CAAoB,CAAC;AACzE,CAAC;AALD,8CAKC;AAED;;;;;;GAMG;AACH,SAAgB,iBAAiB,CAC/B,aAA4B,EAC5B,iBAAiC;IAEjC,kEAAkE;IAClE,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QACxD,qFAAqF;QACrF,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;gBACvD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,wBAAgB,EAAC,OAAO,CAAC,CAAC;gBAEhD,OAAO,SAAS,KAAK,0BAAkB,CAAC,MAAM,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAC3B,CAAC;QAED,2DAA2D;aACtD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AA5BD,8CA4BC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,MAAc,EAAE,OAAwB;IACtE,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,MAAM,CAAC;AAC9C,CAAC;AAFD,0CAEC","sourcesContent":["import type { SnapId } from '@metamask/snaps-sdk';\nimport type { Json, CaipAccountId, CaipChainId } from '@metamask/utils';\nimport { KnownCaipNamespace, parseCaipChainId } from '@metamask/utils';\n\n/**\n * Copy of the original type from\n * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts\n */\nexport type InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n scopes: CaipChainId[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\n/**\n * Create a list of CAIP account IDs from an address and a list of scopes.\n *\n * @param address - The address to create the account IDs from.\n * @param scopes - The scopes to create the account IDs from.\n * @returns The list of CAIP account IDs.\n */\nexport function createAccountList(\n address: string,\n scopes: CaipChainId[],\n): CaipAccountId[] {\n return scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[];\n}\n\n/**\n * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.\n *\n * @param accountScopes - The account scopes to create the chain ID list from.\n * @param requestedChainIds - The requested chain IDs to filter the account scopes by.\n * @returns The list of CAIP chain IDs.\n */\nexport function createChainIdList(\n accountScopes: CaipChainId[],\n requestedChainIds?: CaipChainId[],\n) {\n // If there are no requested chain IDs, return all account scopes.\n if (!requestedChainIds || requestedChainIds.length === 0) {\n return accountScopes;\n }\n\n return accountScopes.reduce<CaipChainId[]>((acc, scope) => {\n // If the scope represents all EVM compatible chains, return all requested chain IDs.\n if (scope === 'eip155:0') {\n const evmChainIds = requestedChainIds.filter((chainId) => {\n const { namespace } = parseCaipChainId(chainId);\n\n return namespace === KnownCaipNamespace.Eip155;\n });\n\n acc.push(...evmChainIds);\n }\n\n // If the scope is not in the requested chain IDs, skip it.\n else if (requestedChainIds.includes(scope)) {\n acc.push(scope);\n }\n\n return acc;\n }, []);\n}\n\n/**\n * Whether if the snap owns the account.\n *\n * @param snapId - The snap id.\n * @param account - The account.\n * @returns True if the snap owns the account, otherwise false.\n */\nexport function snapOwnsAccount(snapId: SnapId, account: InternalAccount) {\n return account.metadata.snap?.id === snapId;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { SnapId } from "@metamask/snaps-sdk";
2
- import type { Json } from "@metamask/utils";
2
+ import type { Json, CaipAccountId, CaipChainId } from "@metamask/utils";
3
3
  /**
4
4
  * Copy of the original type from
5
5
  * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts
@@ -10,6 +10,7 @@ export type InternalAccount = {
10
10
  address: string;
11
11
  options: Record<string, Json>;
12
12
  methods: string[];
13
+ scopes: CaipChainId[];
13
14
  metadata: {
14
15
  name: string;
15
16
  snap?: {
@@ -19,4 +20,28 @@ export type InternalAccount = {
19
20
  };
20
21
  };
21
22
  };
23
+ /**
24
+ * Create a list of CAIP account IDs from an address and a list of scopes.
25
+ *
26
+ * @param address - The address to create the account IDs from.
27
+ * @param scopes - The scopes to create the account IDs from.
28
+ * @returns The list of CAIP account IDs.
29
+ */
30
+ export declare function createAccountList(address: string, scopes: CaipChainId[]): CaipAccountId[];
31
+ /**
32
+ * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.
33
+ *
34
+ * @param accountScopes - The account scopes to create the chain ID list from.
35
+ * @param requestedChainIds - The requested chain IDs to filter the account scopes by.
36
+ * @returns The list of CAIP chain IDs.
37
+ */
38
+ export declare function createChainIdList(accountScopes: CaipChainId[], requestedChainIds?: CaipChainId[]): `${string}:${string}`[];
39
+ /**
40
+ * Whether if the snap owns the account.
41
+ *
42
+ * @param snapId - The snap id.
43
+ * @param account - The account.
44
+ * @returns True if the snap owns the account, otherwise false.
45
+ */
46
+ export declare function snapOwnsAccount(snapId: SnapId, account: InternalAccount): boolean;
22
47
  //# sourceMappingURL=account.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.cts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"account.d.cts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,wBAAwB;AAGxE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,EAAE,GACpB,aAAa,EAAE,CAEjB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,WAAW,EAAE,EAC5B,iBAAiB,CAAC,EAAE,WAAW,EAAE,2BA0BlC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,WAEvE"}
@@ -1,5 +1,5 @@
1
1
  import type { SnapId } from "@metamask/snaps-sdk";
2
- import type { Json } from "@metamask/utils";
2
+ import type { Json, CaipAccountId, CaipChainId } from "@metamask/utils";
3
3
  /**
4
4
  * Copy of the original type from
5
5
  * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts
@@ -10,6 +10,7 @@ export type InternalAccount = {
10
10
  address: string;
11
11
  options: Record<string, Json>;
12
12
  methods: string[];
13
+ scopes: CaipChainId[];
13
14
  metadata: {
14
15
  name: string;
15
16
  snap?: {
@@ -19,4 +20,28 @@ export type InternalAccount = {
19
20
  };
20
21
  };
21
22
  };
23
+ /**
24
+ * Create a list of CAIP account IDs from an address and a list of scopes.
25
+ *
26
+ * @param address - The address to create the account IDs from.
27
+ * @param scopes - The scopes to create the account IDs from.
28
+ * @returns The list of CAIP account IDs.
29
+ */
30
+ export declare function createAccountList(address: string, scopes: CaipChainId[]): CaipAccountId[];
31
+ /**
32
+ * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.
33
+ *
34
+ * @param accountScopes - The account scopes to create the chain ID list from.
35
+ * @param requestedChainIds - The requested chain IDs to filter the account scopes by.
36
+ * @returns The list of CAIP chain IDs.
37
+ */
38
+ export declare function createChainIdList(accountScopes: CaipChainId[], requestedChainIds?: CaipChainId[]): `${string}:${string}`[];
39
+ /**
40
+ * Whether if the snap owns the account.
41
+ *
42
+ * @param snapId - The snap id.
43
+ * @param account - The account.
44
+ * @returns True if the snap owns the account, otherwise false.
45
+ */
46
+ export declare function snapOwnsAccount(snapId: SnapId, account: InternalAccount): boolean;
22
47
  //# sourceMappingURL=account.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account.d.mts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"account.d.mts","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,4BAA4B;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,wBAAwB;AAGxE;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,EAAE,GACpB,aAAa,EAAE,CAEjB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,WAAW,EAAE,EAC5B,iBAAiB,CAAC,EAAE,WAAW,EAAE,2BA0BlC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,WAEvE"}
package/dist/account.mjs CHANGED
@@ -1,2 +1,50 @@
1
- export {};
1
+ import { KnownCaipNamespace, parseCaipChainId } from "@metamask/utils";
2
+ /**
3
+ * Create a list of CAIP account IDs from an address and a list of scopes.
4
+ *
5
+ * @param address - The address to create the account IDs from.
6
+ * @param scopes - The scopes to create the account IDs from.
7
+ * @returns The list of CAIP account IDs.
8
+ */
9
+ export function createAccountList(address, scopes) {
10
+ return scopes.map((scope) => `${scope}:${address}`);
11
+ }
12
+ /**
13
+ * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.
14
+ *
15
+ * @param accountScopes - The account scopes to create the chain ID list from.
16
+ * @param requestedChainIds - The requested chain IDs to filter the account scopes by.
17
+ * @returns The list of CAIP chain IDs.
18
+ */
19
+ export function createChainIdList(accountScopes, requestedChainIds) {
20
+ // If there are no requested chain IDs, return all account scopes.
21
+ if (!requestedChainIds || requestedChainIds.length === 0) {
22
+ return accountScopes;
23
+ }
24
+ return accountScopes.reduce((acc, scope) => {
25
+ // If the scope represents all EVM compatible chains, return all requested chain IDs.
26
+ if (scope === 'eip155:0') {
27
+ const evmChainIds = requestedChainIds.filter((chainId) => {
28
+ const { namespace } = parseCaipChainId(chainId);
29
+ return namespace === KnownCaipNamespace.Eip155;
30
+ });
31
+ acc.push(...evmChainIds);
32
+ }
33
+ // If the scope is not in the requested chain IDs, skip it.
34
+ else if (requestedChainIds.includes(scope)) {
35
+ acc.push(scope);
36
+ }
37
+ return acc;
38
+ }, []);
39
+ }
40
+ /**
41
+ * Whether if the snap owns the account.
42
+ *
43
+ * @param snapId - The snap id.
44
+ * @param account - The account.
45
+ * @returns True if the snap owns the account, otherwise false.
46
+ */
47
+ export function snapOwnsAccount(snapId, account) {
48
+ return account.metadata.snap?.id === snapId;
49
+ }
2
50
  //# sourceMappingURL=account.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"account.mjs","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"","sourcesContent":["import type { SnapId } from '@metamask/snaps-sdk';\nimport type { Json } from '@metamask/utils';\n\n/**\n * Copy of the original type from\n * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts\n */\nexport type InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n"]}
1
+ {"version":3,"file":"account.mjs","sourceRoot":"","sources":["../src/account.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,wBAAwB;AAmBvE;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,MAAqB;IAErB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,EAAE,CAAoB,CAAC;AACzE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAA4B,EAC5B,iBAAiC;IAEjC,kEAAkE;IAClE,IAAI,CAAC,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,OAAO,aAAa,CAAC,MAAM,CAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QACxD,qFAAqF;QACrF,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;gBACvD,MAAM,EAAE,SAAS,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;gBAEhD,OAAO,SAAS,KAAK,kBAAkB,CAAC,MAAM,CAAC;YACjD,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAC3B,CAAC;QAED,2DAA2D;aACtD,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,EAAE,OAAwB;IACtE,OAAO,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,MAAM,CAAC;AAC9C,CAAC","sourcesContent":["import type { SnapId } from '@metamask/snaps-sdk';\nimport type { Json, CaipAccountId, CaipChainId } from '@metamask/utils';\nimport { KnownCaipNamespace, parseCaipChainId } from '@metamask/utils';\n\n/**\n * Copy of the original type from\n * https://github.com/MetaMask/accounts/blob/main/packages/keyring-internal-api/src/types.ts\n */\nexport type InternalAccount = {\n id: string;\n type: string;\n address: string;\n options: Record<string, Json>;\n methods: string[];\n scopes: CaipChainId[];\n metadata: {\n name: string;\n snap?: { id: SnapId; enabled: boolean; name: string };\n };\n};\n\n/**\n * Create a list of CAIP account IDs from an address and a list of scopes.\n *\n * @param address - The address to create the account IDs from.\n * @param scopes - The scopes to create the account IDs from.\n * @returns The list of CAIP account IDs.\n */\nexport function createAccountList(\n address: string,\n scopes: CaipChainId[],\n): CaipAccountId[] {\n return scopes.map((scope) => `${scope}:${address}`) as CaipAccountId[];\n}\n\n/**\n * Create a list of CAIP chain IDs from a list of account scopes and a list of requested chain IDs.\n *\n * @param accountScopes - The account scopes to create the chain ID list from.\n * @param requestedChainIds - The requested chain IDs to filter the account scopes by.\n * @returns The list of CAIP chain IDs.\n */\nexport function createChainIdList(\n accountScopes: CaipChainId[],\n requestedChainIds?: CaipChainId[],\n) {\n // If there are no requested chain IDs, return all account scopes.\n if (!requestedChainIds || requestedChainIds.length === 0) {\n return accountScopes;\n }\n\n return accountScopes.reduce<CaipChainId[]>((acc, scope) => {\n // If the scope represents all EVM compatible chains, return all requested chain IDs.\n if (scope === 'eip155:0') {\n const evmChainIds = requestedChainIds.filter((chainId) => {\n const { namespace } = parseCaipChainId(chainId);\n\n return namespace === KnownCaipNamespace.Eip155;\n });\n\n acc.push(...evmChainIds);\n }\n\n // If the scope is not in the requested chain IDs, skip it.\n else if (requestedChainIds.includes(scope)) {\n acc.push(scope);\n }\n\n return acc;\n }, []);\n}\n\n/**\n * Whether if the snap owns the account.\n *\n * @param snapId - The snap id.\n * @param account - The account.\n * @returns True if the snap owns the account, otherwise false.\n */\nexport function snapOwnsAccount(snapId: SnapId, account: InternalAccount) {\n return account.metadata.snap?.id === snapId;\n}\n"]}
@@ -1,10 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
4
- // @ts-ignore - TypeScript complains about this being ESM in a CJS file, but
5
- // `ses/lockdown` has a CommonJS entry point.
6
3
  // eslint-disable-next-line import-x/no-unassigned-import
7
4
  require("ses/lockdown");
5
+ const utils_1 = require("@metamask/utils");
8
6
  const fs_1 = require("fs");
9
7
  const handlers_1 = require("./handlers/index.cjs");
10
8
  const mock_1 = require("./mock.cjs");
@@ -25,17 +23,46 @@ const compartment = new Compartment({
25
23
  module: snapModule,
26
24
  exports: snapModule.exports,
27
25
  });
28
- // Mirror BaseSnapExecutor
26
+ // Add self referential properties for compatibility with 3rd party libraries.
27
+ // This mirrors the implementation in the Snaps execution environment.
29
28
  compartment.globalThis.self = compartment.globalThis;
30
29
  compartment.globalThis.global = compartment.globalThis;
31
30
  compartment.globalThis.window = compartment.globalThis;
32
31
  compartment.evaluate((0, fs_1.readFileSync)(snapFilePath, 'utf8'));
33
- const invalidExports = Object.keys(snapModule.exports).filter((snapExport) => !handlers_1.SNAP_EXPORT_NAMES.includes(snapExport));
34
- if (invalidExports.length > 0) {
35
- // eslint-disable-next-line no-console
36
- console.warn(`Invalid snap exports detected:\n${invalidExports.join('\n')}`);
32
+ /**
33
+ * Check the exports of the Snap module to ensure they are valid, and exit the
34
+ * worker process.
35
+ *
36
+ * @param exports - The exports of the Snap module.
37
+ */
38
+ function checkExports(exports) {
39
+ // eslint-disable-next-line @typescript-eslint/unbound-method
40
+ (0, utils_1.assert)(process.send, 'This script must be run as a child process.');
41
+ process.send({
42
+ type: 'snap-exports',
43
+ data: {
44
+ exports: Object.keys(exports),
45
+ },
46
+ });
47
+ const invalidExports = Object.keys(snapModule.exports).filter((snapExport) => !handlers_1.SNAP_EXPORT_NAMES.includes(snapExport));
48
+ if (invalidExports.length > 0) {
49
+ // eslint-disable-next-line no-console
50
+ console.warn(`Invalid snap exports detected:\n${invalidExports.join('\n')}`);
51
+ }
52
+ // To ensure the worker exits we explicitly call exit here. If we didn't, the
53
+ // worker would wait for timers set during `Compartment` eval.
54
+ process.exit(0);
55
+ }
56
+ if (snapModule.exports instanceof Promise) {
57
+ // The Snap may use async logic (e.g., when loading WASM), so we need to
58
+ // handle that case.
59
+ snapModule.exports.then(checkExports).catch((error) => {
60
+ // eslint-disable-next-line no-console
61
+ console.error('Error loading Snap module:', error);
62
+ process.exit(1);
63
+ });
64
+ }
65
+ else {
66
+ checkExports(snapModule.exports);
37
67
  }
38
- // To ensure the worker exits we explicitly call exit here
39
- // If we didn't the eval would wait for timers set during Compartment eval
40
- process.exit(0);
41
68
  //# sourceMappingURL=eval-worker.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval-worker.cjs","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":";;AAAA,6DAA6D;AAC7D,4EAA4E;AAC5E,6CAA6C;AAC7C,yDAAyD;AACzD,wBAAsB;AAEtB,2BAAkC;AAGlC,mDAA+C;AAC/C,qCAAgD;AAIhD,QAAQ,CAAC;IACP,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,SAAS;IACzB,cAAc,EAAE,QAAQ;IACxB,YAAY,EAAE,QAAQ;IAEtB,2EAA2E;IAC3E,yEAAyE;IACzE,kCAAkC;IAClC,YAAY,EAAE,QAAQ;CACvB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,GAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IAClC,GAAG,IAAA,6BAAsB,GAAE;IAC3B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU,CAAC,OAAO;CAC5B,CAAC,CAAC;AAEH,0BAA0B;AAC1B,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;AACrD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AACvD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AAEvD,WAAW,CAAC,QAAQ,CAAC,IAAA,iBAAY,EAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAC3D,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,4BAAiB,CAAC,QAAQ,CAAC,UAAyB,CAAC,CACvE,CAAC;AAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC9B,sCAAsC;IACtC,OAAO,CAAC,IAAI,CAAC,mCAAmC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,0DAA0D;AAC1D,0EAA0E;AAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - TypeScript complains about this being ESM in a CJS file, but\n// `ses/lockdown` has a CommonJS entry point.\n// eslint-disable-next-line import-x/no-unassigned-import\nimport 'ses/lockdown';\n\nimport { readFileSync } from 'fs';\n\nimport type { HandlerType } from './handlers';\nimport { SNAP_EXPORT_NAMES } from './handlers';\nimport { generateMockEndowments } from './mock';\n\ndeclare let lockdown: any, Compartment: any;\n\nlockdown({\n errorTaming: 'unsafe',\n stackFiltering: 'verbose',\n overrideTaming: 'severe',\n localeTaming: 'unsafe',\n\n // We disable domain taming, because it does not work in certain cases when\n // running tests. This is unlikely to be a problem in production, because\n // Node.js domains are deprecated.\n domainTaming: 'unsafe',\n});\n\nconst snapFilePath = process.argv[2];\n\nconst snapModule: { exports?: any } = { exports: {} };\n\nconst compartment = new Compartment({\n ...generateMockEndowments(),\n module: snapModule,\n exports: snapModule.exports,\n});\n\n// Mirror BaseSnapExecutor\ncompartment.globalThis.self = compartment.globalThis;\ncompartment.globalThis.global = compartment.globalThis;\ncompartment.globalThis.window = compartment.globalThis;\n\ncompartment.evaluate(readFileSync(snapFilePath, 'utf8'));\n\nconst invalidExports = Object.keys(snapModule.exports).filter(\n (snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport as HandlerType),\n);\n\nif (invalidExports.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid snap exports detected:\\n${invalidExports.join('\\n')}`);\n}\n\n// To ensure the worker exits we explicitly call exit here\n// If we didn't the eval would wait for timers set during Compartment eval\nprocess.exit(0);\n"]}
1
+ {"version":3,"file":"eval-worker.cjs","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":";;AAAA,yDAAyD;AACzD,wBAAsB;AAEtB,2CAAyC;AACzC,2BAAkC;AAGlC,mDAA+C;AAC/C,qCAAgD;AAEhD,QAAQ,CAAC;IACP,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,SAAS;IACzB,cAAc,EAAE,QAAQ;IACxB,YAAY,EAAE,QAAQ;IAEtB,2EAA2E;IAC3E,yEAAyE;IACzE,kCAAkC;IAClC,YAAY,EAAE,QAAQ;CACvB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,GAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IAClC,GAAG,IAAA,6BAAsB,GAAE;IAC3B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU,CAAC,OAAO;CAC5B,CAAC,CAAC;AAEH,8EAA8E;AAC9E,sEAAsE;AACtE,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;AACrD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AACvD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AAEvD,WAAW,CAAC,QAAQ,CAAC,IAAA,iBAAY,EAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,SAAS,YAAY,CAAC,OAAY;IAChC,6DAA6D;IAC7D,IAAA,cAAM,EAAC,OAAO,CAAC,IAAI,EAAE,6CAA6C,CAAC,CAAC;IAEpE,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SAC9B;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAC3D,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,4BAAiB,CAAC,QAAQ,CAAC,UAAyB,CAAC,CACvE,CAAC;IAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACV,mCAAmC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,8DAA8D;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,UAAU,CAAC,OAAO,YAAY,OAAO,EAAE,CAAC;IAC1C,wEAAwE;IACxE,oBAAoB;IACpB,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;QAC3D,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC","sourcesContent":["// eslint-disable-next-line import-x/no-unassigned-import\nimport 'ses/lockdown';\n\nimport { assert } from '@metamask/utils';\nimport { readFileSync } from 'fs';\n\nimport type { HandlerType } from './handlers';\nimport { SNAP_EXPORT_NAMES } from './handlers';\nimport { generateMockEndowments } from './mock';\n\nlockdown({\n errorTaming: 'unsafe',\n stackFiltering: 'verbose',\n overrideTaming: 'severe',\n localeTaming: 'unsafe',\n\n // We disable domain taming, because it does not work in certain cases when\n // running tests. This is unlikely to be a problem in production, because\n // Node.js domains are deprecated.\n domainTaming: 'unsafe',\n});\n\nconst snapFilePath = process.argv[2];\n\nconst snapModule: { exports?: any } = { exports: {} };\n\nconst compartment = new Compartment({\n ...generateMockEndowments(),\n module: snapModule,\n exports: snapModule.exports,\n});\n\n// Add self referential properties for compatibility with 3rd party libraries.\n// This mirrors the implementation in the Snaps execution environment.\ncompartment.globalThis.self = compartment.globalThis;\ncompartment.globalThis.global = compartment.globalThis;\ncompartment.globalThis.window = compartment.globalThis;\n\ncompartment.evaluate(readFileSync(snapFilePath, 'utf8'));\n\n/**\n * Check the exports of the Snap module to ensure they are valid, and exit the\n * worker process.\n *\n * @param exports - The exports of the Snap module.\n */\nfunction checkExports(exports: any) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n assert(process.send, 'This script must be run as a child process.');\n\n process.send({\n type: 'snap-exports',\n data: {\n exports: Object.keys(exports),\n },\n });\n\n const invalidExports = Object.keys(snapModule.exports).filter(\n (snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport as HandlerType),\n );\n\n if (invalidExports.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `Invalid snap exports detected:\\n${invalidExports.join('\\n')}`,\n );\n }\n\n // To ensure the worker exits we explicitly call exit here. If we didn't, the\n // worker would wait for timers set during `Compartment` eval.\n process.exit(0);\n}\n\nif (snapModule.exports instanceof Promise) {\n // The Snap may use async logic (e.g., when loading WASM), so we need to\n // handle that case.\n snapModule.exports.then(checkExports).catch((error: Error) => {\n // eslint-disable-next-line no-console\n console.error('Error loading Snap module:', error);\n process.exit(1);\n });\n} else {\n checkExports(snapModule.exports);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"eval-worker.d.cts","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AAIA,sBAAsB"}
1
+ {"version":3,"file":"eval-worker.d.cts","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AACA,sBAAsB"}
@@ -1 +1 @@
1
- {"version":3,"file":"eval-worker.d.mts","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AAIA,sBAAsB"}
1
+ {"version":3,"file":"eval-worker.d.mts","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AACA,sBAAsB"}
@@ -1,8 +1,6 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
- // @ts-ignore - TypeScript complains about this being ESM in a CJS file, but
3
- // `ses/lockdown` has a CommonJS entry point.
4
1
  // eslint-disable-next-line import-x/no-unassigned-import
5
2
  import "ses/lockdown";
3
+ import { assert } from "@metamask/utils";
6
4
  import { readFileSync } from "fs";
7
5
  import { SNAP_EXPORT_NAMES } from "./handlers/index.mjs";
8
6
  import { generateMockEndowments } from "./mock.mjs";
@@ -23,17 +21,46 @@ const compartment = new Compartment({
23
21
  module: snapModule,
24
22
  exports: snapModule.exports,
25
23
  });
26
- // Mirror BaseSnapExecutor
24
+ // Add self referential properties for compatibility with 3rd party libraries.
25
+ // This mirrors the implementation in the Snaps execution environment.
27
26
  compartment.globalThis.self = compartment.globalThis;
28
27
  compartment.globalThis.global = compartment.globalThis;
29
28
  compartment.globalThis.window = compartment.globalThis;
30
29
  compartment.evaluate(readFileSync(snapFilePath, 'utf8'));
31
- const invalidExports = Object.keys(snapModule.exports).filter((snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport));
32
- if (invalidExports.length > 0) {
33
- // eslint-disable-next-line no-console
34
- console.warn(`Invalid snap exports detected:\n${invalidExports.join('\n')}`);
30
+ /**
31
+ * Check the exports of the Snap module to ensure they are valid, and exit the
32
+ * worker process.
33
+ *
34
+ * @param exports - The exports of the Snap module.
35
+ */
36
+ function checkExports(exports) {
37
+ // eslint-disable-next-line @typescript-eslint/unbound-method
38
+ assert(process.send, 'This script must be run as a child process.');
39
+ process.send({
40
+ type: 'snap-exports',
41
+ data: {
42
+ exports: Object.keys(exports),
43
+ },
44
+ });
45
+ const invalidExports = Object.keys(snapModule.exports).filter((snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport));
46
+ if (invalidExports.length > 0) {
47
+ // eslint-disable-next-line no-console
48
+ console.warn(`Invalid snap exports detected:\n${invalidExports.join('\n')}`);
49
+ }
50
+ // To ensure the worker exits we explicitly call exit here. If we didn't, the
51
+ // worker would wait for timers set during `Compartment` eval.
52
+ process.exit(0);
53
+ }
54
+ if (snapModule.exports instanceof Promise) {
55
+ // The Snap may use async logic (e.g., when loading WASM), so we need to
56
+ // handle that case.
57
+ snapModule.exports.then(checkExports).catch((error) => {
58
+ // eslint-disable-next-line no-console
59
+ console.error('Error loading Snap module:', error);
60
+ process.exit(1);
61
+ });
62
+ }
63
+ else {
64
+ checkExports(snapModule.exports);
35
65
  }
36
- // To ensure the worker exits we explicitly call exit here
37
- // If we didn't the eval would wait for timers set during Compartment eval
38
- process.exit(0);
39
66
  //# sourceMappingURL=eval-worker.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"eval-worker.mjs","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,4EAA4E;AAC5E,6CAA6C;AAC7C,yDAAyD;AACzD,sBAAsB;AAEtB,OAAO,EAAE,YAAY,EAAE,WAAW;AAGlC,OAAO,EAAE,iBAAiB,EAAE,6BAAmB;AAC/C,OAAO,EAAE,sBAAsB,EAAE,mBAAe;AAIhD,QAAQ,CAAC;IACP,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,SAAS;IACzB,cAAc,EAAE,QAAQ;IACxB,YAAY,EAAE,QAAQ;IAEtB,2EAA2E;IAC3E,yEAAyE;IACzE,kCAAkC;IAClC,YAAY,EAAE,QAAQ;CACvB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,GAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IAClC,GAAG,sBAAsB,EAAE;IAC3B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU,CAAC,OAAO;CAC5B,CAAC,CAAC;AAEH,0BAA0B;AAC1B,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;AACrD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AACvD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AAEvD,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAC3D,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,UAAyB,CAAC,CACvE,CAAC;AAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;IAC9B,sCAAsC;IACtC,OAAO,CAAC,IAAI,CAAC,mCAAmC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,0DAA0D;AAC1D,0EAA0E;AAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC","sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - TypeScript complains about this being ESM in a CJS file, but\n// `ses/lockdown` has a CommonJS entry point.\n// eslint-disable-next-line import-x/no-unassigned-import\nimport 'ses/lockdown';\n\nimport { readFileSync } from 'fs';\n\nimport type { HandlerType } from './handlers';\nimport { SNAP_EXPORT_NAMES } from './handlers';\nimport { generateMockEndowments } from './mock';\n\ndeclare let lockdown: any, Compartment: any;\n\nlockdown({\n errorTaming: 'unsafe',\n stackFiltering: 'verbose',\n overrideTaming: 'severe',\n localeTaming: 'unsafe',\n\n // We disable domain taming, because it does not work in certain cases when\n // running tests. This is unlikely to be a problem in production, because\n // Node.js domains are deprecated.\n domainTaming: 'unsafe',\n});\n\nconst snapFilePath = process.argv[2];\n\nconst snapModule: { exports?: any } = { exports: {} };\n\nconst compartment = new Compartment({\n ...generateMockEndowments(),\n module: snapModule,\n exports: snapModule.exports,\n});\n\n// Mirror BaseSnapExecutor\ncompartment.globalThis.self = compartment.globalThis;\ncompartment.globalThis.global = compartment.globalThis;\ncompartment.globalThis.window = compartment.globalThis;\n\ncompartment.evaluate(readFileSync(snapFilePath, 'utf8'));\n\nconst invalidExports = Object.keys(snapModule.exports).filter(\n (snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport as HandlerType),\n);\n\nif (invalidExports.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(`Invalid snap exports detected:\\n${invalidExports.join('\\n')}`);\n}\n\n// To ensure the worker exits we explicitly call exit here\n// If we didn't the eval would wait for timers set during Compartment eval\nprocess.exit(0);\n"]}
1
+ {"version":3,"file":"eval-worker.mjs","sourceRoot":"","sources":["../src/eval-worker.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,sBAAsB;AAEtB,OAAO,EAAE,MAAM,EAAE,wBAAwB;AACzC,OAAO,EAAE,YAAY,EAAE,WAAW;AAGlC,OAAO,EAAE,iBAAiB,EAAE,6BAAmB;AAC/C,OAAO,EAAE,sBAAsB,EAAE,mBAAe;AAEhD,QAAQ,CAAC;IACP,WAAW,EAAE,QAAQ;IACrB,cAAc,EAAE,SAAS;IACzB,cAAc,EAAE,QAAQ;IACxB,YAAY,EAAE,QAAQ;IAEtB,2EAA2E;IAC3E,yEAAyE;IACzE,kCAAkC;IAClC,YAAY,EAAE,QAAQ;CACvB,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,GAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;IAClC,GAAG,sBAAsB,EAAE;IAC3B,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,UAAU,CAAC,OAAO;CAC5B,CAAC,CAAC;AAEH,8EAA8E;AAC9E,sEAAsE;AACtE,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,CAAC;AACrD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AACvD,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC;AAEvD,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,SAAS,YAAY,CAAC,OAAY;IAChC,6DAA6D;IAC7D,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,6CAA6C,CAAC,CAAC;IAEpE,OAAO,CAAC,IAAI,CAAC;QACX,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE;YACJ,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SAC9B;KACF,CAAC,CAAC;IAEH,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAC3D,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,UAAyB,CAAC,CACvE,CAAC;IAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,sCAAsC;QACtC,OAAO,CAAC,IAAI,CACV,mCAAmC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/D,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,8DAA8D;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,UAAU,CAAC,OAAO,YAAY,OAAO,EAAE,CAAC;IAC1C,wEAAwE;IACxE,oBAAoB;IACpB,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;QAC3D,sCAAsC;QACtC,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;KAAM,CAAC;IACN,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC","sourcesContent":["// eslint-disable-next-line import-x/no-unassigned-import\nimport 'ses/lockdown';\n\nimport { assert } from '@metamask/utils';\nimport { readFileSync } from 'fs';\n\nimport type { HandlerType } from './handlers';\nimport { SNAP_EXPORT_NAMES } from './handlers';\nimport { generateMockEndowments } from './mock';\n\nlockdown({\n errorTaming: 'unsafe',\n stackFiltering: 'verbose',\n overrideTaming: 'severe',\n localeTaming: 'unsafe',\n\n // We disable domain taming, because it does not work in certain cases when\n // running tests. This is unlikely to be a problem in production, because\n // Node.js domains are deprecated.\n domainTaming: 'unsafe',\n});\n\nconst snapFilePath = process.argv[2];\n\nconst snapModule: { exports?: any } = { exports: {} };\n\nconst compartment = new Compartment({\n ...generateMockEndowments(),\n module: snapModule,\n exports: snapModule.exports,\n});\n\n// Add self referential properties for compatibility with 3rd party libraries.\n// This mirrors the implementation in the Snaps execution environment.\ncompartment.globalThis.self = compartment.globalThis;\ncompartment.globalThis.global = compartment.globalThis;\ncompartment.globalThis.window = compartment.globalThis;\n\ncompartment.evaluate(readFileSync(snapFilePath, 'utf8'));\n\n/**\n * Check the exports of the Snap module to ensure they are valid, and exit the\n * worker process.\n *\n * @param exports - The exports of the Snap module.\n */\nfunction checkExports(exports: any) {\n // eslint-disable-next-line @typescript-eslint/unbound-method\n assert(process.send, 'This script must be run as a child process.');\n\n process.send({\n type: 'snap-exports',\n data: {\n exports: Object.keys(exports),\n },\n });\n\n const invalidExports = Object.keys(snapModule.exports).filter(\n (snapExport) => !SNAP_EXPORT_NAMES.includes(snapExport as HandlerType),\n );\n\n if (invalidExports.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `Invalid snap exports detected:\\n${invalidExports.join('\\n')}`,\n );\n }\n\n // To ensure the worker exits we explicitly call exit here. If we didn't, the\n // worker would wait for timers set during `Compartment` eval.\n process.exit(0);\n}\n\nif (snapModule.exports instanceof Promise) {\n // The Snap may use async logic (e.g., when loading WASM), so we need to\n // handle that case.\n snapModule.exports.then(checkExports).catch((error: Error) => {\n // eslint-disable-next-line no-console\n console.error('Error loading Snap module:', error);\n process.exit(1);\n });\n} else {\n checkExports(snapModule.exports);\n}\n"]}
package/dist/eval.cjs CHANGED
@@ -30,8 +30,13 @@ async function evalBundle(bundlePath) {
30
30
  });
31
31
  let stdout = '';
32
32
  let stderr = '';
33
+ let exports = [];
33
34
  (0, utils_1.assert)(worker.stdout, '`stdout` should be defined.');
34
35
  (0, utils_1.assert)(worker.stderr, '`stderr` should be defined.');
36
+ worker.on('message', (message) => {
37
+ (0, utils_1.assert)(message.type === 'snap-exports', `Received unexpected message with type "${message.type}".`);
38
+ exports = message.data.exports;
39
+ });
35
40
  worker.stdout.on('data', (data) => {
36
41
  stdout += data.toString();
37
42
  });
@@ -42,6 +47,7 @@ async function evalBundle(bundlePath) {
42
47
  const output = {
43
48
  stdout,
44
49
  stderr,
50
+ exports,
45
51
  };
46
52
  if (exitCode === 0) {
47
53
  return resolve(output);
package/dist/eval.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"eval.cjs","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AACzC,iDAAqC;AACrC,+BAA4B;AAE5B,iCAAwC;AAOxC,MAAa,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,MAAkB;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AATD,sCASC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,IAAA,qBAAgB,EAAC,UAAU,CAAC,CAAC;IAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAA,oBAAI,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;YACpE,oEAAoE;YACpE,qDAAqD;YACrD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAA,cAAM,EAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QACrD,IAAA,cAAM,EAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG;gBACb,MAAM;gBACN,MAAM;aACP,CAAC;YAEF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,OAAO,MAAM,CACX,IAAI,aAAa,CACf,2CAA2C,QAAQ,GAAG,EACtD,MAAM,CACP,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AA1CD,gCA0CC","sourcesContent":["import { assert } from '@metamask/utils';\nimport { fork } from 'child_process';\nimport { join } from 'path';\n\nimport { validateFilePath } from './fs';\n\nexport type EvalOutput = {\n stdout: string;\n stderr: string;\n};\n\nexport class SnapEvalError extends Error {\n readonly output: EvalOutput;\n\n constructor(message: string, output: EvalOutput) {\n super(message);\n\n this.name = 'SnapEvalError';\n this.output = output;\n }\n}\n\n/**\n * Spawn a new process to run the provided bundle in.\n *\n * @param bundlePath - The path to the bundle to run.\n * @returns `null` if the worker ran successfully.\n * @throws If the worker failed to run successfully.\n */\nexport async function evalBundle(bundlePath: string): Promise<EvalOutput> {\n await validateFilePath(bundlePath);\n\n return new Promise((resolve, reject) => {\n const worker = fork(join(__dirname, 'eval-worker.cjs'), [bundlePath], {\n // To avoid printing the output of the worker to the console, we set\n // `stdio` to `pipe` and handle the output ourselves.\n stdio: 'pipe',\n });\n\n let stdout = '';\n let stderr = '';\n\n assert(worker.stdout, '`stdout` should be defined.');\n assert(worker.stderr, '`stderr` should be defined.');\n\n worker.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n worker.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n worker.on('exit', (exitCode: number) => {\n const output = {\n stdout,\n stderr,\n };\n\n if (exitCode === 0) {\n return resolve(output);\n }\n\n return reject(\n new SnapEvalError(\n `Process exited with non-zero exit code: ${exitCode}.`,\n output,\n ),\n );\n });\n });\n}\n"]}
1
+ {"version":3,"file":"eval.cjs","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":";;;AAAA,2CAAyC;AACzC,iDAAqC;AACrC,+BAA4B;AAE5B,iCAAwC;AAexC,MAAa,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,MAAkB;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AATD,sCASC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,IAAA,qBAAgB,EAAC,UAAU,CAAC,CAAC;IAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAA,oBAAI,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,iBAAiB,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;YACpE,oEAAoE;YACpE,qDAAqD;YACrD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,GAAa,EAAE,CAAC;QAE3B,IAAA,cAAM,EAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QACrD,IAAA,cAAM,EAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QAErD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAA0B,EAAE,EAAE;YAClD,IAAA,cAAM,EACJ,OAAO,CAAC,IAAI,KAAK,cAAc,EAC/B,0CAA0C,OAAO,CAAC,IAAI,IAAI,CAC3D,CAAC;YAEF,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG;gBACb,MAAM;gBACN,MAAM;gBACN,OAAO;aACR,CAAC;YAEF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,OAAO,MAAM,CACX,IAAI,aAAa,CACf,2CAA2C,QAAQ,GAAG,EACtD,MAAM,CACP,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AArDD,gCAqDC","sourcesContent":["import { assert } from '@metamask/utils';\nimport { fork } from 'child_process';\nimport { join } from 'path';\n\nimport { validateFilePath } from './fs';\n\nexport type EvalWorkerMessage = {\n type: 'snap-exports';\n data: {\n exports: string[];\n };\n};\n\nexport type EvalOutput = {\n stdout: string;\n stderr: string;\n exports: string[];\n};\n\nexport class SnapEvalError extends Error {\n readonly output: EvalOutput;\n\n constructor(message: string, output: EvalOutput) {\n super(message);\n\n this.name = 'SnapEvalError';\n this.output = output;\n }\n}\n\n/**\n * Spawn a new process to run the provided bundle in.\n *\n * @param bundlePath - The path to the bundle to run.\n * @returns `null` if the worker ran successfully.\n * @throws If the worker failed to run successfully.\n */\nexport async function evalBundle(bundlePath: string): Promise<EvalOutput> {\n await validateFilePath(bundlePath);\n\n return new Promise((resolve, reject) => {\n const worker = fork(join(__dirname, 'eval-worker.cjs'), [bundlePath], {\n // To avoid printing the output of the worker to the console, we set\n // `stdio` to `pipe` and handle the output ourselves.\n stdio: 'pipe',\n });\n\n let stdout = '';\n let stderr = '';\n let exports: string[] = [];\n\n assert(worker.stdout, '`stdout` should be defined.');\n assert(worker.stderr, '`stderr` should be defined.');\n\n worker.on('message', (message: EvalWorkerMessage) => {\n assert(\n message.type === 'snap-exports',\n `Received unexpected message with type \"${message.type}\".`,\n );\n\n exports = message.data.exports;\n });\n\n worker.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n worker.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n worker.on('exit', (exitCode: number) => {\n const output = {\n stdout,\n stderr,\n exports,\n };\n\n if (exitCode === 0) {\n return resolve(output);\n }\n\n return reject(\n new SnapEvalError(\n `Process exited with non-zero exit code: ${exitCode}.`,\n output,\n ),\n );\n });\n });\n}\n"]}
package/dist/eval.d.cts CHANGED
@@ -1,6 +1,13 @@
1
+ export type EvalWorkerMessage = {
2
+ type: 'snap-exports';
3
+ data: {
4
+ exports: string[];
5
+ };
6
+ };
1
7
  export type EvalOutput = {
2
8
  stdout: string;
3
9
  stderr: string;
10
+ exports: string[];
4
11
  };
5
12
  export declare class SnapEvalError extends Error {
6
13
  readonly output: EvalOutput;
@@ -1 +1 @@
1
- {"version":3,"file":"eval.d.cts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;CAMhD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0CxE"}
1
+ {"version":3,"file":"eval.d.cts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;CAMhD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqDxE"}
package/dist/eval.d.mts CHANGED
@@ -1,6 +1,13 @@
1
+ export type EvalWorkerMessage = {
2
+ type: 'snap-exports';
3
+ data: {
4
+ exports: string[];
5
+ };
6
+ };
1
7
  export type EvalOutput = {
2
8
  stdout: string;
3
9
  stderr: string;
10
+ exports: string[];
4
11
  };
5
12
  export declare class SnapEvalError extends Error {
6
13
  readonly output: EvalOutput;
@@ -1 +1 @@
1
- {"version":3,"file":"eval.d.mts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;CAMhD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0CxE"}
1
+ {"version":3,"file":"eval.d.mts","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE;QACJ,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;gBAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU;CAMhD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqDxE"}
package/dist/eval.mjs CHANGED
@@ -44,8 +44,13 @@ export async function evalBundle(bundlePath) {
44
44
  });
45
45
  let stdout = '';
46
46
  let stderr = '';
47
+ let exports = [];
47
48
  assert(worker.stdout, '`stdout` should be defined.');
48
49
  assert(worker.stderr, '`stderr` should be defined.');
50
+ worker.on('message', (message) => {
51
+ assert(message.type === 'snap-exports', `Received unexpected message with type "${message.type}".`);
52
+ exports = message.data.exports;
53
+ });
49
54
  worker.stdout.on('data', (data) => {
50
55
  stdout += data.toString();
51
56
  });
@@ -56,6 +61,7 @@ export async function evalBundle(bundlePath) {
56
61
  const output = {
57
62
  stdout,
58
63
  stderr,
64
+ exports,
59
65
  };
60
66
  if (exitCode === 0) {
61
67
  return resolve(output);
package/dist/eval.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"eval.mjs","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AACzC,OAAO,EAAE,IAAI,EAAE,sBAAsB;AACrC,OAAO,EAAE,IAAI,EAAE,aAAa;AAE5B,OAAO,EAAE,gBAAgB,EAAE,iBAAa;AAOxC,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,MAAkB;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,8BAAY,iBAAiB,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;YACpE,oEAAoE;YACpE,qDAAqD;YACrD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QAErD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG;gBACb,MAAM;gBACN,MAAM;aACP,CAAC;YAEF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,OAAO,MAAM,CACX,IAAI,aAAa,CACf,2CAA2C,QAAQ,GAAG,EACtD,MAAM,CACP,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\nimport { fork } from 'child_process';\nimport { join } from 'path';\n\nimport { validateFilePath } from './fs';\n\nexport type EvalOutput = {\n stdout: string;\n stderr: string;\n};\n\nexport class SnapEvalError extends Error {\n readonly output: EvalOutput;\n\n constructor(message: string, output: EvalOutput) {\n super(message);\n\n this.name = 'SnapEvalError';\n this.output = output;\n }\n}\n\n/**\n * Spawn a new process to run the provided bundle in.\n *\n * @param bundlePath - The path to the bundle to run.\n * @returns `null` if the worker ran successfully.\n * @throws If the worker failed to run successfully.\n */\nexport async function evalBundle(bundlePath: string): Promise<EvalOutput> {\n await validateFilePath(bundlePath);\n\n return new Promise((resolve, reject) => {\n const worker = fork(join(__dirname, 'eval-worker.cjs'), [bundlePath], {\n // To avoid printing the output of the worker to the console, we set\n // `stdio` to `pipe` and handle the output ourselves.\n stdio: 'pipe',\n });\n\n let stdout = '';\n let stderr = '';\n\n assert(worker.stdout, '`stdout` should be defined.');\n assert(worker.stderr, '`stderr` should be defined.');\n\n worker.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n worker.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n worker.on('exit', (exitCode: number) => {\n const output = {\n stdout,\n stderr,\n };\n\n if (exitCode === 0) {\n return resolve(output);\n }\n\n return reject(\n new SnapEvalError(\n `Process exited with non-zero exit code: ${exitCode}.`,\n output,\n ),\n );\n });\n });\n}\n"]}
1
+ {"version":3,"file":"eval.mjs","sourceRoot":"","sources":["../src/eval.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AACzC,OAAO,EAAE,IAAI,EAAE,sBAAsB;AACrC,OAAO,EAAE,IAAI,EAAE,aAAa;AAE5B,OAAO,EAAE,gBAAgB,EAAE,iBAAa;AAexC,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,OAAe,EAAE,MAAkB;QAC7C,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,8BAAY,iBAAiB,CAAC,EAAE,CAAC,UAAU,CAAC,EAAE;YACpE,oEAAoE;YACpE,qDAAqD;YACrD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,GAAa,EAAE,CAAC;QAE3B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;QAErD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAA0B,EAAE,EAAE;YAClD,MAAM,CACJ,OAAO,CAAC,IAAI,KAAK,cAAc,EAC/B,0CAA0C,OAAO,CAAC,IAAI,IAAI,CAC3D,CAAC;YAEF,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACxC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,QAAgB,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG;gBACb,MAAM;gBACN,MAAM;gBACN,OAAO;aACR,CAAC;YAEF,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,OAAO,MAAM,CACX,IAAI,aAAa,CACf,2CAA2C,QAAQ,GAAG,EACtD,MAAM,CACP,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { assert } from '@metamask/utils';\nimport { fork } from 'child_process';\nimport { join } from 'path';\n\nimport { validateFilePath } from './fs';\n\nexport type EvalWorkerMessage = {\n type: 'snap-exports';\n data: {\n exports: string[];\n };\n};\n\nexport type EvalOutput = {\n stdout: string;\n stderr: string;\n exports: string[];\n};\n\nexport class SnapEvalError extends Error {\n readonly output: EvalOutput;\n\n constructor(message: string, output: EvalOutput) {\n super(message);\n\n this.name = 'SnapEvalError';\n this.output = output;\n }\n}\n\n/**\n * Spawn a new process to run the provided bundle in.\n *\n * @param bundlePath - The path to the bundle to run.\n * @returns `null` if the worker ran successfully.\n * @throws If the worker failed to run successfully.\n */\nexport async function evalBundle(bundlePath: string): Promise<EvalOutput> {\n await validateFilePath(bundlePath);\n\n return new Promise((resolve, reject) => {\n const worker = fork(join(__dirname, 'eval-worker.cjs'), [bundlePath], {\n // To avoid printing the output of the worker to the console, we set\n // `stdio` to `pipe` and handle the output ourselves.\n stdio: 'pipe',\n });\n\n let stdout = '';\n let stderr = '';\n let exports: string[] = [];\n\n assert(worker.stdout, '`stdout` should be defined.');\n assert(worker.stderr, '`stderr` should be defined.');\n\n worker.on('message', (message: EvalWorkerMessage) => {\n assert(\n message.type === 'snap-exports',\n `Received unexpected message with type \"${message.type}\".`,\n );\n\n exports = message.data.exports;\n });\n\n worker.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n worker.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n worker.on('exit', (exitCode: number) => {\n const output = {\n stdout,\n stderr,\n exports,\n };\n\n if (exitCode === 0) {\n return resolve(output);\n }\n\n return reject(\n new SnapEvalError(\n `Process exited with non-zero exit code: ${exitCode}.`,\n output,\n ),\n );\n });\n });\n}\n"]}