@metamask-previews/account-tree-controller 7.6.1-preview-6b4bcdab3 → 7.6.1-preview-12019cffe

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,10 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ### Changed
11
-
12
- - Bump `@metamask/accounts-controller` from `^39.0.7` to `^39.1.0` ([#9807](https://github.com/MetaMask/core/pull/9807))
13
-
14
10
  ## [7.6.1]
15
11
 
16
12
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/account-tree-controller",
3
- "version": "7.6.1-preview-6b4bcdab3",
3
+ "version": "7.6.1-preview-12019cffe",
4
4
  "description": "Controller to group account together based on some pre-defined rules",
5
5
  "keywords": [
6
6
  "Ethereum",
@@ -55,7 +55,7 @@
55
55
  "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
56
56
  },
57
57
  "dependencies": {
58
- "@metamask/accounts-controller": "^39.1.0",
58
+ "@metamask/accounts-controller": "^39.0.7",
59
59
  "@metamask/base-controller": "^9.1.0",
60
60
  "@metamask/keyring-api": "^24.0.0",
61
61
  "@metamask/keyring-controller": "^27.1.1",
@@ -1,65 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
5
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
6
- };
7
- var _IdMap_localToPayload, _IdMap_payloadToLocal;
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.IdMap = void 0;
10
- const utils_1 = require("@metamask/utils");
11
- /**
12
- * Bidirectional map between local controller IDs and portable payload IDs.
13
- *
14
- * Populated during {@link exportState} so that callers can bridge between
15
- * device-local wallet/group IDs and the stable cross-device IDs that appear
16
- * in a serialized {@link AccountTreePayload}.
17
- */
18
- class IdMap {
19
- /**
20
- * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.
21
- */
22
- constructor(entries = []) {
23
- _IdMap_localToPayload.set(this, new Map());
24
- _IdMap_payloadToLocal.set(this, new Map());
25
- for (const [localId, payloadId] of entries) {
26
- this.add(localId, payloadId);
27
- }
28
- }
29
- /**
30
- * Registers a local↔payload ID pair.
31
- *
32
- * @param localId - Local controller wallet or group ID.
33
- * @param payloadId - Corresponding portable payload ID.
34
- */
35
- add(localId, payloadId) {
36
- // Each local ID maps to exactly one payload ID and vice versa: wallet and
37
- // group IDs are unique by construction, so a duplicate signals a bug in the
38
- // caller (e.g. exportState visiting the same node twice).
39
- (0, utils_1.assert)(!__classPrivateFieldGet(this, _IdMap_localToPayload, "f").has(localId), `Local ID already registered: ${localId}`);
40
- (0, utils_1.assert)(!__classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").has(payloadId), `Payload ID already registered: ${payloadId}`);
41
- __classPrivateFieldGet(this, _IdMap_localToPayload, "f").set(localId, payloadId);
42
- __classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").set(payloadId, localId);
43
- }
44
- /**
45
- * Returns the portable payload ID for a given local ID.
46
- *
47
- * @param localId - Local controller wallet or group ID.
48
- * @returns The payload ID, or `undefined` if not registered.
49
- */
50
- getPayloadId(localId) {
51
- return __classPrivateFieldGet(this, _IdMap_localToPayload, "f").get(localId);
52
- }
53
- /**
54
- * Returns the local controller ID for a given payload ID.
55
- *
56
- * @param payloadId - Portable payload ID.
57
- * @returns The local wallet or group ID, or `undefined` if not registered.
58
- */
59
- getLocalId(payloadId) {
60
- return __classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").get(payloadId);
61
- }
62
- }
63
- exports.IdMap = IdMap;
64
- _IdMap_localToPayload = new WeakMap(), _IdMap_payloadToLocal = new WeakMap();
65
- //# sourceMappingURL=id-map.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"id-map.cjs","sourceRoot":"","sources":["../../src/state/id-map.ts"],"names":[],"mappings":";;;;;;;;;AACA,2CAAyC;AAUzC;;;;;;GAMG;AACH,MAAa,KAAK;IAKhB;;OAEG;IACH,YAAY,UAAsD,EAAE;QAP3D,gCAA2C,IAAI,GAAG,EAAE,EAAC;QAErD,gCAA2C,IAAI,GAAG,EAAE,EAAC;QAM5D,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,OAAgB,EAAE,SAAoB;QACxC,0EAA0E;QAC1E,4EAA4E;QAC5E,0DAA0D;QAC1D,IAAA,cAAM,EACJ,CAAC,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAClC,gCAAgC,OAAO,EAAE,CAC1C,CAAC;QACF,IAAA,cAAM,EACJ,CAAC,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,EACpC,kCAAkC,SAAS,EAAE,CAC9C,CAAC;QACF,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC7C,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAgB;QAC3B,OAAO,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,SAAoB;QAC7B,OAAO,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;CACF;AAvDD,sBAuDC","sourcesContent":["import type { AccountGroupId, AccountWalletId } from '@metamask/account-api';\nimport { assert } from '@metamask/utils';\n\nimport type {\n AccountGroupPayloadId,\n AccountWalletPayloadId,\n} from './payload.js';\n\ntype LocalId = AccountWalletId | AccountGroupId;\ntype PayloadId = AccountWalletPayloadId | AccountGroupPayloadId;\n\n/**\n * Bidirectional map between local controller IDs and portable payload IDs.\n *\n * Populated during {@link exportState} so that callers can bridge between\n * device-local wallet/group IDs and the stable cross-device IDs that appear\n * in a serialized {@link AccountTreePayload}.\n */\nexport class IdMap {\n readonly #localToPayload: Map<LocalId, PayloadId> = new Map();\n\n readonly #payloadToLocal: Map<PayloadId, LocalId> = new Map();\n\n /**\n * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.\n */\n constructor(entries: [localId: LocalId, payloadId: PayloadId][] = []) {\n for (const [localId, payloadId] of entries) {\n this.add(localId, payloadId);\n }\n }\n\n /**\n * Registers a local↔payload ID pair.\n *\n * @param localId - Local controller wallet or group ID.\n * @param payloadId - Corresponding portable payload ID.\n */\n add(localId: LocalId, payloadId: PayloadId): void {\n // Each local ID maps to exactly one payload ID and vice versa: wallet and\n // group IDs are unique by construction, so a duplicate signals a bug in the\n // caller (e.g. exportState visiting the same node twice).\n assert(\n !this.#localToPayload.has(localId),\n `Local ID already registered: ${localId}`,\n );\n assert(\n !this.#payloadToLocal.has(payloadId),\n `Payload ID already registered: ${payloadId}`,\n );\n this.#localToPayload.set(localId, payloadId);\n this.#payloadToLocal.set(payloadId, localId);\n }\n\n /**\n * Returns the portable payload ID for a given local ID.\n *\n * @param localId - Local controller wallet or group ID.\n * @returns The payload ID, or `undefined` if not registered.\n */\n getPayloadId(localId: LocalId): PayloadId | undefined {\n return this.#localToPayload.get(localId);\n }\n\n /**\n * Returns the local controller ID for a given payload ID.\n *\n * @param payloadId - Portable payload ID.\n * @returns The local wallet or group ID, or `undefined` if not registered.\n */\n getLocalId(payloadId: PayloadId): LocalId | undefined {\n return this.#payloadToLocal.get(payloadId);\n }\n}\n"]}
@@ -1,41 +0,0 @@
1
- import type { AccountGroupId, AccountWalletId } from "@metamask/account-api";
2
- import type { AccountGroupPayloadId, AccountWalletPayloadId } from "./payload.cjs";
3
- type LocalId = AccountWalletId | AccountGroupId;
4
- type PayloadId = AccountWalletPayloadId | AccountGroupPayloadId;
5
- /**
6
- * Bidirectional map between local controller IDs and portable payload IDs.
7
- *
8
- * Populated during {@link exportState} so that callers can bridge between
9
- * device-local wallet/group IDs and the stable cross-device IDs that appear
10
- * in a serialized {@link AccountTreePayload}.
11
- */
12
- export declare class IdMap {
13
- #private;
14
- /**
15
- * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.
16
- */
17
- constructor(entries?: [localId: LocalId, payloadId: PayloadId][]);
18
- /**
19
- * Registers a local↔payload ID pair.
20
- *
21
- * @param localId - Local controller wallet or group ID.
22
- * @param payloadId - Corresponding portable payload ID.
23
- */
24
- add(localId: LocalId, payloadId: PayloadId): void;
25
- /**
26
- * Returns the portable payload ID for a given local ID.
27
- *
28
- * @param localId - Local controller wallet or group ID.
29
- * @returns The payload ID, or `undefined` if not registered.
30
- */
31
- getPayloadId(localId: LocalId): PayloadId | undefined;
32
- /**
33
- * Returns the local controller ID for a given payload ID.
34
- *
35
- * @param payloadId - Portable payload ID.
36
- * @returns The local wallet or group ID, or `undefined` if not registered.
37
- */
38
- getLocalId(payloadId: PayloadId): LocalId | undefined;
39
- }
40
- export {};
41
- //# sourceMappingURL=id-map.d.cts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"id-map.d.cts","sourceRoot":"","sources":["../../src/state/id-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACvB,sBAAqB;AAEtB,KAAK,OAAO,GAAG,eAAe,GAAG,cAAc,CAAC;AAChD,KAAK,SAAS,GAAG,sBAAsB,GAAG,qBAAqB,CAAC;AAEhE;;;;;;GAMG;AACH,qBAAa,KAAK;;IAKhB;;OAEG;gBACS,OAAO,GAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,EAAO;IAMpE;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAgBjD;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS;IAIrD;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS;CAGtD"}
@@ -1,41 +0,0 @@
1
- import type { AccountGroupId, AccountWalletId } from "@metamask/account-api";
2
- import type { AccountGroupPayloadId, AccountWalletPayloadId } from "./payload.mjs";
3
- type LocalId = AccountWalletId | AccountGroupId;
4
- type PayloadId = AccountWalletPayloadId | AccountGroupPayloadId;
5
- /**
6
- * Bidirectional map between local controller IDs and portable payload IDs.
7
- *
8
- * Populated during {@link exportState} so that callers can bridge between
9
- * device-local wallet/group IDs and the stable cross-device IDs that appear
10
- * in a serialized {@link AccountTreePayload}.
11
- */
12
- export declare class IdMap {
13
- #private;
14
- /**
15
- * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.
16
- */
17
- constructor(entries?: [localId: LocalId, payloadId: PayloadId][]);
18
- /**
19
- * Registers a local↔payload ID pair.
20
- *
21
- * @param localId - Local controller wallet or group ID.
22
- * @param payloadId - Corresponding portable payload ID.
23
- */
24
- add(localId: LocalId, payloadId: PayloadId): void;
25
- /**
26
- * Returns the portable payload ID for a given local ID.
27
- *
28
- * @param localId - Local controller wallet or group ID.
29
- * @returns The payload ID, or `undefined` if not registered.
30
- */
31
- getPayloadId(localId: LocalId): PayloadId | undefined;
32
- /**
33
- * Returns the local controller ID for a given payload ID.
34
- *
35
- * @param payloadId - Portable payload ID.
36
- * @returns The local wallet or group ID, or `undefined` if not registered.
37
- */
38
- getLocalId(payloadId: PayloadId): LocalId | undefined;
39
- }
40
- export {};
41
- //# sourceMappingURL=id-map.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"id-map.d.mts","sourceRoot":"","sources":["../../src/state/id-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,8BAA8B;AAG7E,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACvB,sBAAqB;AAEtB,KAAK,OAAO,GAAG,eAAe,GAAG,cAAc,CAAC;AAChD,KAAK,SAAS,GAAG,sBAAsB,GAAG,qBAAqB,CAAC;AAEhE;;;;;;GAMG;AACH,qBAAa,KAAK;;IAKhB;;OAEG;gBACS,OAAO,GAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC,EAAO;IAMpE;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAgBjD;;;;;OAKG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS;IAIrD;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS;CAGtD"}
@@ -1,61 +0,0 @@
1
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
- };
6
- var _IdMap_localToPayload, _IdMap_payloadToLocal;
7
- import { assert } from "@metamask/utils";
8
- /**
9
- * Bidirectional map between local controller IDs and portable payload IDs.
10
- *
11
- * Populated during {@link exportState} so that callers can bridge between
12
- * device-local wallet/group IDs and the stable cross-device IDs that appear
13
- * in a serialized {@link AccountTreePayload}.
14
- */
15
- export class IdMap {
16
- /**
17
- * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.
18
- */
19
- constructor(entries = []) {
20
- _IdMap_localToPayload.set(this, new Map());
21
- _IdMap_payloadToLocal.set(this, new Map());
22
- for (const [localId, payloadId] of entries) {
23
- this.add(localId, payloadId);
24
- }
25
- }
26
- /**
27
- * Registers a local↔payload ID pair.
28
- *
29
- * @param localId - Local controller wallet or group ID.
30
- * @param payloadId - Corresponding portable payload ID.
31
- */
32
- add(localId, payloadId) {
33
- // Each local ID maps to exactly one payload ID and vice versa: wallet and
34
- // group IDs are unique by construction, so a duplicate signals a bug in the
35
- // caller (e.g. exportState visiting the same node twice).
36
- assert(!__classPrivateFieldGet(this, _IdMap_localToPayload, "f").has(localId), `Local ID already registered: ${localId}`);
37
- assert(!__classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").has(payloadId), `Payload ID already registered: ${payloadId}`);
38
- __classPrivateFieldGet(this, _IdMap_localToPayload, "f").set(localId, payloadId);
39
- __classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").set(payloadId, localId);
40
- }
41
- /**
42
- * Returns the portable payload ID for a given local ID.
43
- *
44
- * @param localId - Local controller wallet or group ID.
45
- * @returns The payload ID, or `undefined` if not registered.
46
- */
47
- getPayloadId(localId) {
48
- return __classPrivateFieldGet(this, _IdMap_localToPayload, "f").get(localId);
49
- }
50
- /**
51
- * Returns the local controller ID for a given payload ID.
52
- *
53
- * @param payloadId - Portable payload ID.
54
- * @returns The local wallet or group ID, or `undefined` if not registered.
55
- */
56
- getLocalId(payloadId) {
57
- return __classPrivateFieldGet(this, _IdMap_payloadToLocal, "f").get(payloadId);
58
- }
59
- }
60
- _IdMap_localToPayload = new WeakMap(), _IdMap_payloadToLocal = new WeakMap();
61
- //# sourceMappingURL=id-map.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"id-map.mjs","sourceRoot":"","sources":["../../src/state/id-map.ts"],"names":[],"mappings":";;;;;;AACA,OAAO,EAAE,MAAM,EAAE,wBAAwB;AAUzC;;;;;;GAMG;AACH,MAAM,OAAO,KAAK;IAKhB;;OAEG;IACH,YAAY,UAAsD,EAAE;QAP3D,gCAA2C,IAAI,GAAG,EAAE,EAAC;QAErD,gCAA2C,IAAI,GAAG,EAAE,EAAC;QAM5D,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC;YAC3C,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,OAAgB,EAAE,SAAoB;QACxC,0EAA0E;QAC1E,4EAA4E;QAC5E,0DAA0D;QAC1D,MAAM,CACJ,CAAC,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAClC,gCAAgC,OAAO,EAAE,CAC1C,CAAC;QACF,MAAM,CACJ,CAAC,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,EACpC,kCAAkC,SAAS,EAAE,CAC9C,CAAC;QACF,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAC7C,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,OAAgB;QAC3B,OAAO,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,SAAoB;QAC7B,OAAO,uBAAA,IAAI,6BAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;CACF","sourcesContent":["import type { AccountGroupId, AccountWalletId } from '@metamask/account-api';\nimport { assert } from '@metamask/utils';\n\nimport type {\n AccountGroupPayloadId,\n AccountWalletPayloadId,\n} from './payload.js';\n\ntype LocalId = AccountWalletId | AccountGroupId;\ntype PayloadId = AccountWalletPayloadId | AccountGroupPayloadId;\n\n/**\n * Bidirectional map between local controller IDs and portable payload IDs.\n *\n * Populated during {@link exportState} so that callers can bridge between\n * device-local wallet/group IDs and the stable cross-device IDs that appear\n * in a serialized {@link AccountTreePayload}.\n */\nexport class IdMap {\n readonly #localToPayload: Map<LocalId, PayloadId> = new Map();\n\n readonly #payloadToLocal: Map<PayloadId, LocalId> = new Map();\n\n /**\n * @param entries - Optional seed pairs `[localId, payloadId]` to pre-populate the map.\n */\n constructor(entries: [localId: LocalId, payloadId: PayloadId][] = []) {\n for (const [localId, payloadId] of entries) {\n this.add(localId, payloadId);\n }\n }\n\n /**\n * Registers a local↔payload ID pair.\n *\n * @param localId - Local controller wallet or group ID.\n * @param payloadId - Corresponding portable payload ID.\n */\n add(localId: LocalId, payloadId: PayloadId): void {\n // Each local ID maps to exactly one payload ID and vice versa: wallet and\n // group IDs are unique by construction, so a duplicate signals a bug in the\n // caller (e.g. exportState visiting the same node twice).\n assert(\n !this.#localToPayload.has(localId),\n `Local ID already registered: ${localId}`,\n );\n assert(\n !this.#payloadToLocal.has(payloadId),\n `Payload ID already registered: ${payloadId}`,\n );\n this.#localToPayload.set(localId, payloadId);\n this.#payloadToLocal.set(payloadId, localId);\n }\n\n /**\n * Returns the portable payload ID for a given local ID.\n *\n * @param localId - Local controller wallet or group ID.\n * @returns The payload ID, or `undefined` if not registered.\n */\n getPayloadId(localId: LocalId): PayloadId | undefined {\n return this.#localToPayload.get(localId);\n }\n\n /**\n * Returns the local controller ID for a given payload ID.\n *\n * @param payloadId - Portable payload ID.\n * @returns The local wallet or group ID, or `undefined` if not registered.\n */\n getLocalId(payloadId: PayloadId): LocalId | undefined {\n return this.#payloadToLocal.get(payloadId);\n }\n}\n"]}
@@ -1,169 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.assertAccountTreePayload = exports.AccountTreePayloadStruct = exports.ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION = exports.toGroupPayloadId = exports.toWalletPayloadId = exports.AccountWalletPrivateKeyEncoding = exports.AccountWalletPayloadType = exports.parsePayloadGroupId = void 0;
4
- const keyring_api_1 = require("@metamask/keyring-api");
5
- const superstruct_1 = require("@metamask/superstruct");
6
- const utils_js_1 = require("./utils.cjs");
7
- const PAYLOAD_GROUP_ID_REGEX = /^(?<walletId>wallet:[^/]+)\/(?<subId>.+)$/u;
8
- /**
9
- * Parses a payload group ID into its wallet ID and group sub-ID components.
10
- *
11
- * @param groupId - The payload group ID to parse.
12
- * @returns The parsed wallet ID and group sub-ID.
13
- * @throws If the group ID format is invalid.
14
- */
15
- function parsePayloadGroupId(groupId) {
16
- const match = PAYLOAD_GROUP_ID_REGEX.exec(groupId);
17
- if (!match?.groups) {
18
- throw new Error(`Invalid payload group ID: "${groupId}"`);
19
- }
20
- return {
21
- walletId: match.groups.walletId,
22
- subId: match.groups.subId,
23
- };
24
- }
25
- exports.parsePayloadGroupId = parsePayloadGroupId;
26
- /**
27
- * Wallet type discriminants used in serialized {@link AccountTreePayload} entries.
28
- *
29
- * Use these constants instead of raw string literals so callers get autocomplete
30
- * and a single source of truth for the discriminant values.
31
- */
32
- exports.AccountWalletPayloadType = {
33
- Mnemonic: 'mnemonic',
34
- PrivateKey: 'private-key',
35
- };
36
- /**
37
- * Encoding formats for exported private key material.
38
- */
39
- exports.AccountWalletPrivateKeyEncoding = {
40
- Hexadecimal: 'hexadecimal',
41
- Base58: 'base58',
42
- Base32: 'base32',
43
- };
44
- /**
45
- * Constructs an {@link AccountWalletPayloadId} from an entropy source ID.
46
- *
47
- * @param entropySourceId - Stable entropy source ID returned by `HdKeyring.toEntropySourceId()`.
48
- * @returns The portable wallet payload ID.
49
- */
50
- function toWalletPayloadId(entropySourceId) {
51
- return `wallet:${entropySourceId}`;
52
- }
53
- exports.toWalletPayloadId = toWalletPayloadId;
54
- /**
55
- * Constructs an {@link AccountGroupPayloadId} from a wallet payload ID and a sub-ID.
56
- *
57
- * @param walletId - The wallet payload ID this group belongs to.
58
- * @param subId - The group-specific sub-ID (e.g. group index for mnemonic wallets, address for private-key wallets).
59
- * @returns The portable group payload ID.
60
- */
61
- function toGroupPayloadId(walletId, subId) {
62
- return `${walletId}/${subId}`;
63
- }
64
- exports.toGroupPayloadId = toGroupPayloadId;
65
- const AccountWalletPayloadIdStruct = (0, superstruct_1.define)('AccountWalletPayloadId', (value) => typeof value === 'string' && value.startsWith('wallet:')
66
- ? true
67
- : 'Expected a wallet payload ID starting with "wallet:"');
68
- const AccountGroupPayloadIdStruct = (0, superstruct_1.define)('AccountGroupPayloadId', (value) => typeof value === 'string' && PAYLOAD_GROUP_ID_REGEX.test(value)
69
- ? true
70
- : 'Expected a group payload ID in the form "wallet:<id>/<subId>"');
71
- const AccountWalletPayloadMetadataStruct = (0, superstruct_1.object)({
72
- name: (0, superstruct_1.string)(),
73
- });
74
- const AccountWalletGroupPayloadMetadataStruct = (0, superstruct_1.object)({
75
- name: (0, superstruct_1.string)(),
76
- pinned: (0, superstruct_1.boolean)(),
77
- hidden: (0, superstruct_1.boolean)(),
78
- });
79
- const AccountWalletPrivateKeyValueStruct = (0, superstruct_1.object)({
80
- privateKey: (0, superstruct_1.sensitive)(utils_js_1.BytesStruct),
81
- encoding: (0, superstruct_1.enums)(Object.values(exports.AccountWalletPrivateKeyEncoding)),
82
- type: (0, superstruct_1.exactOptional)(keyring_api_1.KeyringAccountTypeStruct),
83
- });
84
- const AccountWalletMnemonicGroupEntryStruct = (0, superstruct_1.object)({
85
- id: AccountGroupPayloadIdStruct,
86
- groupIndex: (0, superstruct_1.integer)(),
87
- metadata: AccountWalletGroupPayloadMetadataStruct,
88
- });
89
- const AccountWalletPrivateKeyGroupEntryStruct = (0, superstruct_1.object)({
90
- id: AccountGroupPayloadIdStruct,
91
- value: (0, superstruct_1.exactOptional)(AccountWalletPrivateKeyValueStruct),
92
- metadata: AccountWalletGroupPayloadMetadataStruct,
93
- });
94
- // The `groups` array in a mnemonic wallet payload must have contiguous group indices starting at 0.
95
- const AccountWalletMnemonicGroupsStruct = (0, superstruct_1.refine)((0, superstruct_1.array)(AccountWalletMnemonicGroupEntryStruct), 'contiguous-group-indices', (groups) => {
96
- let prev;
97
- for (const curr of groups) {
98
- if (prev === undefined && curr.groupIndex !== 0) {
99
- return `group indices must start at 0; got ${curr.groupIndex}`;
100
- }
101
- if (prev !== undefined && curr.groupIndex !== prev.groupIndex + 1) {
102
- return `group indices must be contiguous and sorted; found gap between index ${prev.groupIndex} and ${curr.groupIndex}`;
103
- }
104
- prev = curr;
105
- }
106
- return true;
107
- });
108
- const AccountWalletMnemonicPayloadStruct = (0, superstruct_1.object)({
109
- id: AccountWalletPayloadIdStruct,
110
- type: (0, superstruct_1.literal)(exports.AccountWalletPayloadType.Mnemonic),
111
- value: (0, superstruct_1.exactOptional)((0, superstruct_1.sensitive)(utils_js_1.BytesStruct)),
112
- metadata: AccountWalletPayloadMetadataStruct,
113
- groups: AccountWalletMnemonicGroupsStruct,
114
- });
115
- const AccountWalletPrivateKeyPayloadStruct = (0, superstruct_1.object)({
116
- id: AccountWalletPayloadIdStruct,
117
- type: (0, superstruct_1.literal)(exports.AccountWalletPayloadType.PrivateKey),
118
- metadata: AccountWalletPayloadMetadataStruct,
119
- groups: (0, superstruct_1.array)(AccountWalletPrivateKeyGroupEntryStruct),
120
- });
121
- const AccountTreeWalletEntryStruct = (0, superstruct_1.union)([
122
- AccountWalletMnemonicPayloadStruct,
123
- AccountWalletPrivateKeyPayloadStruct,
124
- ]);
125
- /** Current version of the {@link AccountTreePayload} format. */
126
- exports.ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION = 1;
127
- /**
128
- * Superstruct schema for a fully versioned {@link AccountTreePayload}.
129
- *
130
- * Pins `version` to exactly {@link ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION} so
131
- * payloads from newer clients (v2+) are rejected rather than silently
132
- * mis-handled as v1. Once a migration framework is wired up in
133
- * {@link AccountTreeSnapshot.deserialize}, older versions will be up-migrated
134
- * before this struct is checked, and newer versions will require a new struct.
135
- *
136
- * Secret fields (`value`, `privateKey`) use the Superstruct `sensitive()`
137
- * wrapper so validation failures redact secrets from error output.
138
- */
139
- exports.AccountTreePayloadStruct = (0, superstruct_1.object)({
140
- version: (0, superstruct_1.literal)(exports.ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION),
141
- wallets: (0, superstruct_1.array)(AccountTreeWalletEntryStruct),
142
- });
143
- /**
144
- * Asserts that `value` conforms to the v1 {@link AccountTreePayload} schema.
145
- *
146
- * Prefer {@link AccountTreeSnapshot.deserialize} at transport boundaries so
147
- * validation stays paired with snapshot construction. Use this helper when you
148
- * already hold a parsed object and need to assert its shape before further
149
- * processing.
150
- *
151
- * @param value - Value to validate.
152
- * @throws If `value` is not a valid v1 payload, including unsupported wallet types.
153
- */
154
- function assertAccountTreePayload(value) {
155
- try {
156
- // AccountTreePayloadStruct pins version to ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION,
157
- // so unknown future versions are rejected here rather than silently mis-handled.
158
- (0, superstruct_1.assert)(value, exports.AccountTreePayloadStruct);
159
- }
160
- catch (error) {
161
- if (error instanceof superstruct_1.StructError) {
162
- throw new Error(`Invalid AccountTreePayload: ${(0, utils_js_1.formatValidationErrorMessages)(error)}`);
163
- }
164
- /* istanbul ignore next */
165
- throw error;
166
- }
167
- }
168
- exports.assertAccountTreePayload = assertAccountTreePayload;
169
- //# sourceMappingURL=payload.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"payload.cjs","sourceRoot":"","sources":["../../src/state/payload.ts"],"names":[],"mappings":"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","sourcesContent":["import { KeyringAccountTypeStruct } from '@metamask/keyring-api';\nimport type { KeyringAccount } from '@metamask/keyring-api';\nimport {\n array,\n assert,\n boolean,\n define,\n enums,\n integer,\n literal,\n object,\n exactOptional,\n refine,\n sensitive,\n string,\n StructError,\n union,\n} from '@metamask/superstruct';\nimport type { Infer } from '@metamask/superstruct';\n\nimport type { DeepReadonly, EncodedBytes } from './utils.js';\nimport { BytesStruct, formatValidationErrorMessages } from './utils.js';\n\n/** Stable cross-device wallet identifier. Format: `wallet:<entropySourceId>`. */\nexport type AccountWalletPayloadId = `wallet:${string}`;\n\n/** Stable cross-device group identifier. Format: `wallet:<entropySourceId>/<groupSubId>`. */\nexport type AccountGroupPayloadId = `${AccountWalletPayloadId}/${string}`;\n\n/**\n * Parsed representation of an {@link AccountGroupPayloadId}.\n */\nexport type ParsedPayloadGroupId = {\n /** The wallet portion of the group ID. */\n walletId: AccountWalletPayloadId;\n /** The group-specific sub-ID (e.g. group index for mnemonic wallets, address for private-key wallets). */\n subId: string;\n};\n\nconst PAYLOAD_GROUP_ID_REGEX = /^(?<walletId>wallet:[^/]+)\\/(?<subId>.+)$/u;\n\n/**\n * Parses a payload group ID into its wallet ID and group sub-ID components.\n *\n * @param groupId - The payload group ID to parse.\n * @returns The parsed wallet ID and group sub-ID.\n * @throws If the group ID format is invalid.\n */\nexport function parsePayloadGroupId(\n groupId: AccountGroupPayloadId,\n): ParsedPayloadGroupId {\n const match = PAYLOAD_GROUP_ID_REGEX.exec(groupId);\n if (!match?.groups) {\n throw new Error(`Invalid payload group ID: \"${groupId}\"`);\n }\n return {\n walletId: match.groups.walletId as AccountWalletPayloadId,\n subId: match.groups.subId,\n };\n}\n\n/**\n * Wallet type discriminants used in serialized {@link AccountTreePayload} entries.\n *\n * Use these constants instead of raw string literals so callers get autocomplete\n * and a single source of truth for the discriminant values.\n */\nexport const AccountWalletPayloadType = {\n Mnemonic: 'mnemonic',\n PrivateKey: 'private-key',\n} as const;\n\nexport type AccountWalletPayloadType =\n (typeof AccountWalletPayloadType)[keyof typeof AccountWalletPayloadType];\n\n/** Wallet-level metadata carried in every payload wallet entry. */\nexport type AccountWalletPayloadMetadata = { name: string };\n\n/** Group-level metadata carried in every payload group entry. */\nexport type AccountWalletGroupPayloadMetadata = {\n name: string;\n pinned: boolean;\n hidden: boolean;\n};\n\n/** A single group entry inside an {@link AccountWalletMnemonicPayload}. */\nexport type AccountWalletMnemonicGroupEntry = {\n /** Stable group payload ID. Format: `<walletPayloadId>/<groupIndex>`. */\n id: AccountGroupPayloadId;\n /** BIP-44 account index this group was derived at. */\n groupIndex: number;\n metadata: AccountWalletGroupPayloadMetadata;\n};\n\n/**\n * Encoding formats for exported private key material.\n */\nexport const AccountWalletPrivateKeyEncoding = {\n Hexadecimal: 'hexadecimal',\n Base58: 'base58',\n Base32: 'base32',\n} as const;\n\nexport type AccountWalletPrivateKeyEncoding =\n (typeof AccountWalletPrivateKeyEncoding)[keyof typeof AccountWalletPrivateKeyEncoding];\n\n/** A single group entry inside an {@link AccountWalletPrivateKeyPayload}. */\nexport type AccountWalletPrivateKeyGroupEntry = {\n /** Stable group payload ID. Format: `wallet:private-key/<address>`. */\n id: AccountGroupPayloadId;\n /**\n * Private key material. Shape matches `ExportedAccount` from `@metamask/keyring-api/v2`\n * so the importer knows how to decode the key without additional out-of-band information.\n * Absent in metadata-only exports.\n */\n value?: {\n privateKey: EncodedBytes;\n encoding: AccountWalletPrivateKeyEncoding;\n /**\n * Account type from `KeyringAccountType` (e.g. `'eip155:eoa'`, `'bip122:p2wpkh'`).\n * Absent for EVM accounts -- import via `SimpleKeyring`.\n * Present for non-EVM accounts -- routing to the BIP-44 Snap handling this type is not yet implemented.\n */\n type?: KeyringAccount['type'];\n };\n metadata: AccountWalletGroupPayloadMetadata;\n};\n\n/** Payload entry for an HD (entropy) wallet and its derived account groups. */\nexport type AccountWalletMnemonicPayload = {\n id: AccountWalletPayloadId;\n type: typeof AccountWalletPayloadType.Mnemonic;\n /** BIP-39 mnemonic phrase encoded as bytes. Absent in metadata-only exports. */\n value?: EncodedBytes;\n metadata: AccountWalletPayloadMetadata;\n groups: AccountWalletMnemonicGroupEntry[];\n};\n\n/**\n * Payload entry for all imported private-key accounts.\n *\n * All local simple-keyring wallets are merged into this single entry;\n * each account is represented as a separate group entry keyed by address.\n */\nexport type AccountWalletPrivateKeyPayload = {\n id: AccountWalletPayloadId;\n type: typeof AccountWalletPayloadType.PrivateKey;\n metadata: AccountWalletPayloadMetadata;\n groups: AccountWalletPrivateKeyGroupEntry[];\n};\n\n/** Union of all wallet entry types that can appear in an {@link AccountTreePayload}. */\nexport type AccountTreeWalletEntry =\n | AccountWalletMnemonicPayload\n | AccountWalletPrivateKeyPayload;\n\n/** Portable snapshot of the full account tree state (flat versioned format). */\nexport type AccountTreePayload = {\n version: number;\n wallets: AccountTreeWalletEntry[];\n};\n\n/**\n * Deeply read-only wallet view passed to {@link AccountTreeSnapshot.filterWallets}\n * and {@link AccountTreeSnapshot.filterAllGroups} predicates.\n *\n * Entries are deep-cloned and deep-frozen when a snapshot is constructed, so\n * callers cannot mutate wallet IDs, types, secrets, metadata, or groups.\n */\nexport type AccountTreeSnapshotWallet = DeepReadonly<\n AccountWalletMnemonicPayload | AccountWalletPrivateKeyPayload\n>;\n\n/**\n * Deeply read-only group view passed to {@link AccountTreeSnapshot.filterGroups}\n * and {@link AccountTreeSnapshot.filterAllGroups} predicates.\n *\n * Entries are deep-cloned and deep-frozen when a snapshot is constructed, so\n * callers cannot mutate group IDs, secrets, metadata, or parent wallet references.\n */\nexport type AccountTreeSnapshotGroup = DeepReadonly<\n AccountWalletMnemonicGroupEntry | AccountWalletPrivateKeyGroupEntry\n>;\n\n/**\n * Constructs an {@link AccountWalletPayloadId} from an entropy source ID.\n *\n * @param entropySourceId - Stable entropy source ID returned by `HdKeyring.toEntropySourceId()`.\n * @returns The portable wallet payload ID.\n */\nexport function toWalletPayloadId(\n entropySourceId: string,\n): AccountWalletPayloadId {\n return `wallet:${entropySourceId}`;\n}\n\n/**\n * Constructs an {@link AccountGroupPayloadId} from a wallet payload ID and a sub-ID.\n *\n * @param walletId - The wallet payload ID this group belongs to.\n * @param subId - The group-specific sub-ID (e.g. group index for mnemonic wallets, address for private-key wallets).\n * @returns The portable group payload ID.\n */\nexport function toGroupPayloadId(\n walletId: AccountWalletPayloadId,\n subId: string | number,\n): AccountGroupPayloadId {\n return `${walletId}/${subId}`;\n}\n\n/** Options accepted by {@link AccountTreeController.exportState}. */\nexport type ExportStateOptions = {\n /** When `true`, secrets (mnemonic / private keys) are included. Requires the vault to be unlocked. */\n includeSecrets?: boolean;\n};\n\nconst AccountWalletPayloadIdStruct = define<AccountWalletPayloadId>(\n 'AccountWalletPayloadId',\n (value) =>\n typeof value === 'string' && value.startsWith('wallet:')\n ? true\n : 'Expected a wallet payload ID starting with \"wallet:\"',\n);\n\nconst AccountGroupPayloadIdStruct = define<AccountGroupPayloadId>(\n 'AccountGroupPayloadId',\n (value) =>\n typeof value === 'string' && PAYLOAD_GROUP_ID_REGEX.test(value)\n ? true\n : 'Expected a group payload ID in the form \"wallet:<id>/<subId>\"',\n);\n\nconst AccountWalletPayloadMetadataStruct = object({\n name: string(),\n});\n\nconst AccountWalletGroupPayloadMetadataStruct = object({\n name: string(),\n pinned: boolean(),\n hidden: boolean(),\n});\n\nconst AccountWalletPrivateKeyValueStruct = object({\n privateKey: sensitive(BytesStruct),\n encoding: enums(Object.values(AccountWalletPrivateKeyEncoding)),\n type: exactOptional(KeyringAccountTypeStruct),\n});\n\nconst AccountWalletMnemonicGroupEntryStruct = object({\n id: AccountGroupPayloadIdStruct,\n groupIndex: integer(),\n metadata: AccountWalletGroupPayloadMetadataStruct,\n});\n\nconst AccountWalletPrivateKeyGroupEntryStruct = object({\n id: AccountGroupPayloadIdStruct,\n value: exactOptional(AccountWalletPrivateKeyValueStruct),\n metadata: AccountWalletGroupPayloadMetadataStruct,\n});\n\n// The `groups` array in a mnemonic wallet payload must have contiguous group indices starting at 0.\nconst AccountWalletMnemonicGroupsStruct = refine(\n array(AccountWalletMnemonicGroupEntryStruct),\n 'contiguous-group-indices',\n (groups) => {\n let prev: AccountWalletMnemonicGroupEntry | undefined;\n for (const curr of groups) {\n if (prev === undefined && curr.groupIndex !== 0) {\n return `group indices must start at 0; got ${curr.groupIndex}`;\n }\n if (prev !== undefined && curr.groupIndex !== prev.groupIndex + 1) {\n return `group indices must be contiguous and sorted; found gap between index ${prev.groupIndex} and ${curr.groupIndex}`;\n }\n prev = curr;\n }\n return true;\n },\n);\n\nconst AccountWalletMnemonicPayloadStruct = object({\n id: AccountWalletPayloadIdStruct,\n type: literal(AccountWalletPayloadType.Mnemonic),\n value: exactOptional(sensitive(BytesStruct)),\n metadata: AccountWalletPayloadMetadataStruct,\n groups: AccountWalletMnemonicGroupsStruct,\n});\n\nconst AccountWalletPrivateKeyPayloadStruct = object({\n id: AccountWalletPayloadIdStruct,\n type: literal(AccountWalletPayloadType.PrivateKey),\n metadata: AccountWalletPayloadMetadataStruct,\n groups: array(AccountWalletPrivateKeyGroupEntryStruct),\n});\n\nconst AccountTreeWalletEntryStruct = union([\n AccountWalletMnemonicPayloadStruct,\n AccountWalletPrivateKeyPayloadStruct,\n]);\n\n/** Current version of the {@link AccountTreePayload} format. */\nexport const ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION = 1;\n\n/**\n * Superstruct schema for a fully versioned {@link AccountTreePayload}.\n *\n * Pins `version` to exactly {@link ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION} so\n * payloads from newer clients (v2+) are rejected rather than silently\n * mis-handled as v1. Once a migration framework is wired up in\n * {@link AccountTreeSnapshot.deserialize}, older versions will be up-migrated\n * before this struct is checked, and newer versions will require a new struct.\n *\n * Secret fields (`value`, `privateKey`) use the Superstruct `sensitive()`\n * wrapper so validation failures redact secrets from error output.\n */\nexport const AccountTreePayloadStruct = object({\n version: literal(ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION),\n wallets: array(AccountTreeWalletEntryStruct),\n});\n\n/** Inferred TypeScript type for a value matching {@link AccountTreePayloadStruct}. */\nexport type AccountTreePayloadStructType = Infer<\n typeof AccountTreePayloadStruct\n>;\n\n/**\n * Asserts that `value` conforms to the v1 {@link AccountTreePayload} schema.\n *\n * Prefer {@link AccountTreeSnapshot.deserialize} at transport boundaries so\n * validation stays paired with snapshot construction. Use this helper when you\n * already hold a parsed object and need to assert its shape before further\n * processing.\n *\n * @param value - Value to validate.\n * @throws If `value` is not a valid v1 payload, including unsupported wallet types.\n */\nexport function assertAccountTreePayload(\n value: unknown,\n): asserts value is AccountTreePayload {\n try {\n // AccountTreePayloadStruct pins version to ACCOUNT_TREE_PAYLOAD_CURRENT_VERSION,\n // so unknown future versions are rejected here rather than silently mis-handled.\n assert(value, AccountTreePayloadStruct);\n } catch (error) {\n if (error instanceof StructError) {\n throw new Error(\n `Invalid AccountTreePayload: ${formatValidationErrorMessages(error)}`,\n );\n }\n /* istanbul ignore next */\n throw error;\n }\n}\n"]}